- `docs/` 를 .gitignore 에서 빼 git 추적 대상으로 전환 (위키·완료 이력·검증 기록) - `docs/raw/PLAN.md` · `docs/raw/OWNERS.md` 를 저장소 최상위로 이동 후 .gitignore 에 등록 — 창끼리 공유하되 저장소에는 안 올리는 장부 - 살아 있는 경로 참조 7개 파일 정정 (아카이브 107건은 그때 사실이라 그대로 둠) - graphify 날짜별 산출물(`docs/wiki/graphify-out/20*/`) 제외 — `graphify update` 가 다시 만듦 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
6.6 KiB
6.6 KiB
계획노선 shapefile 입력 + PRJ 2개 분리
원본: docs/raw/PLAN.md의 「계획노선 shapefile 입력 + PRJ 2개 분리」. 검증 대기 상태로 이관했다.
남은 좌표계 기본값 일원화는 PLAN.md 「프로젝트 작업 좌표계 일원화」에 있다.
배경: 원청 정식 계획노선이 shapefile(UTM-K)로, 지형 자료가 별도 PRJ(동부원점 Bessel)로 들어왔다. 실측 — 노선 bbox를 지형 계로 옮기면 TFW 원점(208,288.84 / 368,092.28) 안쪽에 정확히 앉는다(노선 1,241m × 454m). 기존 입력 경로는 ① shapefile 확장자를 아예 막고 ② PRJ를 프로젝트당 1개로 전제했다.
설계 원칙 (2026-08-31 사용자 확정):
- EPSG 코드로 구분하지 않는다. 모르는 좌표계가 들어와도 돌아야 한다 — 판별은
라벨일 뿐이고 변환은
crs_input_from_prj()가 주는 값(EPSG 확정 시"EPSG:n", 아니면 원문 WKT)으로 한다. 실측: 이번 PRJ 2종 모두to_epsg()가 None인데 WKT↔WKT 변환은 정확했다. - PRJ 짝은 폴더로 가른다. shapefile은 규격상 형제 파일이 같은 basename·같은
폴더에 있어야 GDAL이 연다. 세트를
input/shp/에 두면 노선 PRJ가 그 안에, 지형 PRJ는input/prj/에 남아 파일명 정렬 운에 기대지 않고 갈린다. - 노선은 2D로 받는다. 업로드 shp는 PolyLine(type 3), Z 없음, 121정점. 지반고는
이미
build_surface_sampler()+sample_xy()가 확정 서피스에서 뽑는다 (B05_Profile_Engine_Sections_Core.py:135). CSV의 z는 참조값이라 z=0으로 채운다. - 파일 하나에 카드 한 장. 노선 파일이 5개면 카드도 5개다(2026-08-31 사용자 지시).
구현 (커밋 fe72ea04 · 36e4decf + 2열 개편, 브랜치 feat/b03-route-shapefile):
- A. 업로드 허용에
.shp .shx .dbf .cpg추가(py·ts). 한 번에 보낼 파일 수 5 → 10 (화면의 카드 수 한도도 10으로). - B.
B03_FileInput_Engine_Shapefile.py신설 — ESRI 규격 직접 파싱(GDAL 미사용). 형제 파일이 아직 안 와도.shp하나로 기하를 읽는다..cpg내용이949뿐인 실물을 CP949로 정규화.analyze_input_metadata()에.shp분기. - C.
read_planned_route()로 CSV·shapefile 일원화,find_planned_route_file()은 shapefile 우선.PlannedRoute.crs_input추가(변환 입력),epsg는 라벨로 유지. - D. shapefile 세트를
input/shp/에 모으고(resolve_upload_destination+reconcile_shapefile_members),find_project_prj()가 지형 PRJ를 프로젝트 좌표계로 고른다.project_epsg_from_prj()·B04_PreProcess_Engine.py의glob()[0]제거. - E. 필수 세트를 "노선 1종(csv|shp) + prj + tfw"로 완화, shp면
shx·dbf· 노선 PRJ 동반 필수. 재접속 현황에relative_path를 실어 노선 PRJ를route_prj로 따로 세게 했다 — 지형 PRJ 없이 통과하던 구멍을 막았다. - F. UI — 컨테이너 2개 · 파일마다 카드 한 장
- 왼쪽 「계획노선 자료」:
csv(.csv·.shp) ·shx·dbf·cpg·route_prj - 오른쪽 「지형 자료 (LAS)」:
las_laz·prj(지형 좌표계) ·tfw·tif- LAS 없는 설계 토글
.prj만 확장자로 안 갈린다 — 노선 도형과 basename이 같으면 노선 좌표계 카드, 아니면 지형 카드(planSlotAssignments). 재접속 현황은 저장 경로로 가린다.- 형제 카드는 노선 도형이 shapefile일 때만 필수 — "· 선택" 꼬리표가 실시간으로 붙고 떨어진다.
- 처음엔 슬롯 하나에 세트를 담았으나(
companions) 사용자 지시로 갈아엎었고, 슬롯=파일 하나인 기존 구조가 그대로 살아 업로드 루프도 원래대로 돌아왔다.
- 왼쪽 「계획노선 자료」:
자체검증 — tmp/tests/test_route_shapefile_input.py 9개 전부 통과
(./venv/Scripts/python.exe -m pytest tmp/tests/ -q, 2026-08-31):
- 실물 파서: PolyLine 1파트·121정점·전 정점 z=0 ✓
.cpg가949뿐인 실물 → CP949 정규화, 속성대상지=일월.용화.2.2·길이=2.200✓- 노선 PRJ는
to_epsg()가 None →crs_input이 원문 WKT, 라벨만 5179 ✓ - 노선(UTM-K) → 지형 PRJ 변환이 TFW 원점 안쪽, 연장 2,000~2,300m(속성 2.2km와 일치) ✓
- CSV·shapefile 공존 시 shapefile 우선, 노선명은 dbf 속성에서 ✓
- 노선 PRJ 파일명이 정렬상 앞서도(
a_route.prj<z_terrain.prj) 지형 PRJ 선택 ✓ - PRJ가 SHP보다 먼저 도착한 순서도 세트 폴더로 끌어오고 지형 PRJ는 그대로 ✓
- 필수 세트: shp면
shx·dbf·route_prj요구, 지형 PRJ 없으면 차단, CSV 기존 흐름은 그대로 통과(회귀) ✓ npx tsc --noEmit통과,ruff check·ruff format통과- 전체 스위트 잔여 실패 11건은 기존 실패 —
git archive HEAD사본에서 같은 11건이 동일하게 실패한다(B05 구조물·B06 포장·B07 토적도·PRJ 실물경로). 실패 테스트 중 이번에 고친 모듈을 import하는 것은 없다. - 화면 검증(공용 브라우저, 백엔드 재시작 + 캐시 비우기 + reload): 실물 7파일
(노선 5 + 지형 prj·tfw)을 한 번에 떨어뜨려 배정 실측 —
route.prj는 노선 좌표계 카드,terrain.prj는 지형 카드로 정확히 갈렸다. shx·dbf·route_prj의 "· 선택"이 사라지고 cpg만 남았다. 업로드 버튼은 LAS 미선택이라 비활성(정상). 조작한 화면은 새로고침으로 되돌렸다 — 업로드 버튼은 누르지 않았다. - 카드 제목이 한글 글자 단위로 3줄까지 접히던 것을
word-break: keep-all+ 헤더 flex-wrap으로 고쳤다 — 카드 9개 전부 1줄로 실측.
계획 대비 차이·남긴 것:
- 임시 보관함(
is_batch_required_complete)은 확장자만 알아 노선/지형 PRJ를 못 가린다 — 묶음 완료 판정은shx·dbf까지만 본다. 프로젝트 업로드 경로는 경로로 갈라 정확. B04_PreProcess_Engine_SheetSurface.py의planned.epsg or 5186은 그대로 뒀다 — 좌표계 기본값 산재는 아래 「프로젝트 작업 좌표계 일원화」 몫이다.- 미실행: 실제 프로젝트에 자료를 올려 끝까지 도는 종단 확인은 사용자 프로젝트 데이터를 건드려서 하지 않았다 — 지시가 있으면 시험 프로젝트로 수행한다.
- 미실행:
prettier는 돌리지 않았다. 대상 파일이 원래 prettier 형식이 아니라 파일 전체가 재포맷돼(로케일 200줄 이상) 변경분이 묻힌다. 새 코드는 주변 서식에 맞췄다.