90 lines
4.8 KiB
Python
90 lines
4.8 KiB
Python
"""G6 — 교각별 지반 알림 판정."""
|
||
from __future__ import annotations
|
||
|
||
from dataclasses import dataclass
|
||
|
||
from .config import GroundConfig
|
||
from .piers import Pier
|
||
from .strata import SoilColumn
|
||
|
||
|
||
@dataclass
|
||
class Alert:
|
||
code: str
|
||
level: str # 경고 / 정보
|
||
pier: str
|
||
message: str
|
||
|
||
|
||
def check_pier(pier: Pier, ground_center: float | None, corner_els: list[float | None],
|
||
column: SoilColumn | None, cfg: GroundConfig | None = None,
|
||
has_bore_data: bool = True, dtm_spacing: float | None = None) -> list[Alert]:
|
||
cfg = cfg or GroundConfig()
|
||
out: list[Alert] = []
|
||
A = lambda c, lv, m: out.append(Alert(c, lv, pier.id, m)) # noqa: E731
|
||
|
||
# W11 — DTM 범위 밖
|
||
if ground_center is None:
|
||
A("W11", "경고", "교각 중심이 지형 자료 범위 밖입니다."
|
||
+ (f" 엑셀 지반고 {pier.excel_ground_el:.3f}를 씁니다." if pier.excel_ground_el is not None else ""))
|
||
|
||
# I07 — 지형 점이 성김 (값의 신뢰도 낮음)
|
||
if ground_center is not None and dtm_spacing is not None and dtm_spacing > cfg.dtm_sparse:
|
||
A("I07", "정보", f"지반고를 만든 지형 점이 최대 {dtm_spacing:.1f} m 떨어져 있습니다 (기준 {cfg.dtm_sparse:.0f} m). 현장 측량값을 확인하세요.")
|
||
|
||
# W09 — 엑셀 지반고와 DTM 차이
|
||
if ground_center is not None and pier.excel_ground_el is not None:
|
||
d = ground_center - pier.excel_ground_el
|
||
if abs(d) > cfg.ground_tol:
|
||
A("W09", "경고", f"엑셀 지반고 {pier.excel_ground_el:.3f}와 지형 {ground_center:.3f}의 차이 {d:+.3f} m가 "
|
||
f"허용 {cfg.ground_tol} m를 넘습니다.")
|
||
|
||
# W05 — 확대기초 상면이 지반 위로 나옴 (네 모서리 기준)
|
||
if pier.footing_top_el is not None:
|
||
known = [z for z in corner_els if z is not None]
|
||
if not known: # 흙덮개 계산(pipeline.evaluate_pier)과 같은 순서로 대체
|
||
fallback = ground_center if ground_center is not None else pier.excel_ground_el
|
||
known = [] if fallback is None else [fallback]
|
||
if known and min(known) < pier.footing_top_el:
|
||
A("W05", "경고", f"확대기초 상면 {pier.footing_top_el:.3f}가 지반 최저 {min(known):.3f}보다 "
|
||
f"{pier.footing_top_el - min(known):.3f} m 높습니다 (흙덮개 부족).")
|
||
|
||
if column is None or column.method == "none":
|
||
if not has_bore_data:
|
||
A("I05", "정보", "시추 자료가 없어 지층을 판정하지 않았습니다.")
|
||
else:
|
||
A("I04", "정보", f"{cfg.bore_max:.0f} m 안에 쓸 수 있는 시추공이 없습니다.")
|
||
return out
|
||
|
||
# W13 — 지반고와 시추 공구EL이 어긋나 맨 위 지층 두께가 달라짐
|
||
if column.top_shift is not None and abs(column.top_shift) > cfg.ground_tol:
|
||
A("W13", "경고", f"지반고와 시추 공구EL의 차이 {column.top_shift:+.3f} m가 허용 {cfg.ground_tol} m를 넘습니다. "
|
||
"지층 경계는 시추 기준이므로 맨 위 층 두께가 그만큼 달라졌습니다.")
|
||
|
||
# I04 — 가까운 시추공이 멂
|
||
if column.nearest_dist is not None and column.nearest_dist > cfg.bore_far:
|
||
A("I04", "정보", f"가장 가까운 시추공까지 {column.nearest_dist:.1f} m입니다 (기준 {cfg.bore_far:.0f} m).")
|
||
|
||
# W12 — 두 공의 지층 순서 불일치
|
||
if column.order_mismatch:
|
||
ids = ", ".join(u["id"] for u in column.used)
|
||
A("W12", "경고", f"시추공 {ids}의 지층 순서가 달라 가까운 공 하나만 썼습니다.")
|
||
|
||
# W10 — 말뚝 선단의 지지층 근입
|
||
if pier.pile_tip_el is not None and pier.pile_d_mm is not None:
|
||
need = cfg.embed_d * pier.pile_d_mm / 1000
|
||
if column.support_top_el is None:
|
||
A("W10", "경고", f"시추 자료 안에 지지층({cfg.support_layer})이 없습니다. 말뚝 선단 {pier.pile_tip_el:.3f} 확인 필요.")
|
||
else:
|
||
limit = column.support_top_el - need
|
||
if pier.pile_tip_el > limit + 1e-9:
|
||
A("W10", "경고", f"말뚝 선단 {pier.pile_tip_el:.3f}가 {column.support_name} 상단 {column.support_top_el:.3f} − "
|
||
f"근입 {need:.3f} = {limit:.3f}보다 높습니다.")
|
||
elif column.bottom_el is not None and pier.pile_tip_el < column.bottom_el:
|
||
A("I06", "정보", f"말뚝 선단 {pier.pile_tip_el:.3f}가 시추 자료 하단 {column.bottom_el:.3f}보다 깊습니다.")
|
||
|
||
# I03 — 확대기초 하단이 지하수위 아래
|
||
if pier.footing_bottom_el is not None and column.gwl_el is not None and pier.footing_bottom_el < column.gwl_el:
|
||
A("I03", "정보", f"확대기초 하단 {pier.footing_bottom_el:.3f}가 지하수위 {column.gwl_el:.3f} 아래입니다 (시공 주의).")
|
||
return out
|