같은 폴백 사다리가 네 곳에 서로 다른 모양으로 흩어져 있었고, 그중 배수유역 라우터
`_route_center_lonlat` 은 노선 CSV 의 `crs_epsg` **라벨**을 그대로 변환에 썼다(라벨과
실좌표계가 다른 사례 실측 — 2026-09-01 용화 라벨 5179 / 실제 5176).
`common_util_crs.resolve_project_crs()` 신설 — 사다리는 ① 노선 crs_input ② 파일 라벨
(원본 좌표를 읽는 자리만) ③ 지형 PRJ(작업 좌표계 정본) ④ DB epsg ⑤ EPSG:5186.
작업 좌표계는 **지형 PRJ 우선으로 확정**(2026-09-03 사용자 결정 — 서피스 격자가 모델좌표의
주인이라 현행 유지). `project_epsg_from_prj()` 도 이 창구로 위임.
더해 지표면 트림이 노선을 통째로 지울 때 노선·지표면 bbox 를 함께 로그에 남긴다 —
"겹치지 않습니다" 만으로는 좌표계 문제인지 측량 범위 문제인지 갈리지 않았다.
검증 — `tmp/tests/test_project_crs_resolution.py` 5건 신설(사다리 4·진단 1),
전체 375 passed·17 skipped, ruff format 무변경.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
용화 자동 체인이 끝까지 돌았는데 종단 계획선이 PVI 3개 직선으로 나왔다. 관 22개
측점이 92.6~2044.9m 로 트림 전 원본(2,136m) 기준인데 확정 노선은 1,070.4m 라
21개가 노선 밖이었다. 좌표계도 갈려 있었다 — 관은 EPSG 5179(노선 파일), 노선은
5176(프로젝트)에 저장돼 누가거리만 우연히 맞물려 있었다.
원인은 계획노선을 읽는 곳이 흩어져 있는 것이다. 트림·조밀화를 체인 한 곳에만
넣었더니 배수유역·유입·도엽은 원본을 그대로 읽었다.
- load_design_route() 신규 — 읽기·좌표계 변환·트림·조밀화를 한 곳에서 끝낸다.
설계 계통(체인·배수유역)은 전부 이 함수를 지난다.
- Router_Watershed 도 이 함수를 쓴다. 좌표계가 프로젝트 기준으로 통일돼 관과
노선이 같은 공간에 놓인다.
- 도엽 서피스는 SHEET_SURFACE_AUTO_METHODS(기본 laplace 1종)만 자동 생성한다.
여섯 방식을 매번 만들면 WF1 891초 중 655초를 여기서 쓴다. 나머지는 관리자가
화면에서 고를 때 만든다.
Router_Inflow 는 노선을 EPSG 라벨용으로만 쓰고 기하를 안 써서 제외했다.
Engine_Extent(배경 지도 범위)도 제외 — 지도는 트림 전 전 구간을 덮어야 사용자가
측량 범위 밖을 볼 수 있다.
실측(용화 route 120):
배수유역 노선 2,136m -> 1,070m 격자 889x1435 -> 545x831
1차 영역 538,574㎡ -> 263,170㎡
관 좌표계 EPSG 5179 -> 5176
관 22개(10개가 노선 밖) -> 11개 전부 노선 안
종단 PVI 3개 -> 13개, 종곡선 1 -> 11, 불균형 97.0% -> 86.2%
PVI 측점이 관 측점과 일치한다(반올림 오차 제외).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
실측(2026-08-31): 업로드 후 화면에서 "계획 노선 CSV를 읽지 못했습니다: ...shp"
경고가 반복됐다. find_planned_route_file 은 shapefile을 우선 돌려주는데 받는 쪽이
아직 read_planned_route_csv 였다 - 확장자 분기가 없는 판독기라 .shp 를 CSV로 열다
실패하고 노선 없이 진행했다.
앞선 커밋에서 Service_Chain, SheetSurface, Router_GIS 는 바꿨으나 아래 세 곳을
놓쳤다(조사 당시 grep 출력이 잘려 목록에서 빠졌다):
- B04_PreProcess_Router_Watershed.py (2곳)
- B04_PreProcess_Router_Inflow.py
- common_util_drainage_context.py
셋 다 read_planned_route 로 바꿨다 - CSV/shapefile을 확장자로 갈라 읽는다.
검증: ruff check 통과, tmp/tests 302 passed (잔여 실패 11건은 기존 실패로
HEAD 사본에서 동일 재현).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
납품 도면 2장을 B07 도면 목록에 새로 붙였다. 계산은 하지 않는다 —
유토곡선은 B06 확정 시 저장한 산출물(longitudinal_sections.data.mass_haul)을,
유역도는 B04 세부유역 GeoJSON과 도엽 등고선·세류선을 읽어 좌표만 종이 mm로 옮긴다.
- 도면 종류 확장: kind에 mass_haul·watershed 추가(Schema·Api_Fetch·openwebcad
App.types), 12분류 라벨에 연결, 목록에 단장 도면 2건 상시 노출
- 엔진 신규: _Engine_Cad_MassHaul.py(축·곡선·평형선·띠 현·balloon·측점 테이블),
_Engine_Cad_Basin.py(등고선·세류선 배경·노선·유역·구역별 정보표·방위표)
- 척도 상수: 유토곡선 H 1/2,000 · 세로 1mm=50㎥, 유역도 1/6,000 (A1 고정)
- 유토곡선 저장 payload에 띠·잔여의 기하 필드 추가 — 파이썬에 곡선 보간·토량 배분
로직을 복제하지 않기 위해 값을 낳는 쪽(TS 엔진)에서 함께 남긴다
- 유역도 배경은 여러 도엽을 합쳐 받은 뒤 도곽 크기로 절취(clip_line_to_box)
- 배수규격은 소요 관경이 아니라 규격관(recommended_diameter_mm)으로 표기
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>