"""저장된 프로젝트마다 관 지점 읽기가 **어느 가지**로 가는지 잰다 (계획서 0-7). 투영 이월 가지를 지워도 되는지 판단하는 근거다 — 실제 자료에서 그 가지가 안 돌면 「지문 일치」·「허용오차 안」 둘 중 하나로 끝난다는 뜻이다. 값은 안 고친다(읽기만). """ import json import sys from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parents[2] if str(PROJECT_ROOT) not in sys.path: sys.path.insert(0, str(PROJECT_ROOT)) from common_util.common_util_drainage_pipes import ( # noqa: E402 ROUTE_MATCH_TOLERANCE_M, max_projection_shift, parse_pipe_points, ) from common_util.common_util_route_geometry import RouteVertex # noqa: E402 from config.config_system import STORAGE_BASE_DIR # noqa: E402 ROOT = Path(STORAGE_BASE_DIR) def route_vertices(project_dir: Path): """B05 가 읽는 노선 정점 — `route_main.geojson`.""" for name in ("route_main.geojson", "planned_route.geojson"): for path in project_dir.rglob(name): data = json.loads(path.read_text(encoding="utf-8")) # 파일 꼴이 둘이다 — Feature 하나짜리와 FeatureCollection. geoms = [data.get("geometry") or {}] geoms += [(f.get("geometry") or {}) for f in (data.get("features") or [])] for geom in geoms: if geom.get("type") == "LineString" and geom.get("coordinates"): # 투영은 x·y 만 본다 — z·누가거리는 0 으로 채운다(읽기 전용 계산). return ( [ RouteVertex(x=float(pair[0]), y=float(pair[1]), z=0.0, chainage_m=0.0) for pair in geom["coordinates"] ], path.name, ) return None, None for pipe_file in sorted(ROOT.rglob("pipe_points.json")): if "initial_snapshot" in str(pipe_file): continue project_dir = pipe_file.parents[3] document = json.loads(pipe_file.read_text(encoding="utf-8")) points = parse_pipe_points(document.get("points")) stored_sig = str(document.get("route_signature") or "") vertices, src = route_vertices(project_dir) shift = max_projection_shift(points, vertices) if vertices else None if shift is None: verdict = "노선 파일 없음 — 판정 불가" elif shift <= ROUTE_MATCH_TOLERANCE_M: verdict = f"허용오차 안 (같은 노선) — {shift:.4f}m ≤ {ROUTE_MATCH_TOLERANCE_M}m" else: verdict = f"⚠ 투영 이월 가지 — {shift:.4f}m > {ROUTE_MATCH_TOLERANCE_M}m" print(f"{project_dir.name[:8]} 관 {len(points):3d}건 · 지문 {stored_sig[:18]:18s} · {src} · {verdict}")