Files
Aislo/docs/raw/plans/2026-08-31_plan_prj_crs_detection.md
T
eomsangdonandClaude Opus 5 eb30b774f8 chore(docs): docs 폴더 git 추적 전환 · PLAN·OWNERS 최상위 이관
- `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>
2026-09-09 18:19:07 +09:00

4.3 KiB
Raw Blame History

PRJ 좌표계 판별 수리 — WKT 정본 + EPSG 라벨

원본: docs/raw/PLAN.md의 「PRJ 좌표계 판별 수리」. 커밋 0d90595a. 교차검증 기록은 PLAN.md 「다른 AI 작업(PRJ 좌표계 판별) 검증」에 남아 있다.

배경: get_epsg_from_prj()가 WKT에 항상 있는 false_easting 문자열 때문에 어떤 PRJ든 EPSG:5187을 반환한다(실측 — 표준 WKT 6종 전부 5187). 새로 받은 원청 자료 2종은 pyproj.to_epsg()도 None: LAS 동반 PRJ = Korean 1985 Modified East Belt(실제 5176, 5187로 읽으면 100,308m 오차), 노선 shapefile PRJ = UTM-K(실제 5179, AUTHORITY 태그 없음).

설계 원칙 (2026-08-31 브레인스토밍 확정):

  • 정본은 WKT — 변환기는 파일의 WKT로 만든다. 파일에 박힌 TOWGS84 7모수 등이 EPSG DB 정의와 다를 수 있으므로, EPSG 코드로 재조회해 변환하면 지역 보정이 사라진다.
  • EPSG는 라벨 — 메타데이터·로그·비교용. 판별 사다리: ① CRS.to_epsg()(EPSG 전체 DB 대조 — 후보 목록 무관, 해외 좌표계도 통과) → ② 원문 WKT 마지막 AUTHORITY["EPSG",…] → ③ 투영 파라미터 지문(중앙자오선·원점위도·축척·FE·FN·타원체 장반경)을 한국 후보와 대조.
  • 라벨 실패 ≠ 차단. WKT가 유효하면 WKT로 흐른다. 차단은 WKT 불량일 때만.
  • COMPD_CS(KNGeoid24 결합)는 수평 성분으로 판별한다.

이번 범위 (라이다·도엽·위성 다운로드가 좌표계를 읽는 지점만. DB 스키마·shapefile 입력 슬롯·업로드 교차검증은 아래 「계획노선 입력 좌표계 일원화」 백로그 유지):

  • common_util/common_util_crs.py 신설 — strip_bound(), horizontal_crs(), identify_epsg()(사다리 ①②③), crs_input_from_prj(), 한국 후보 상수.
    • 구현에서 확정된 사항 2건(계획 대비 추가): ① 파일에 TOWGS84가 붙으면 pyproj가 BoundCRS로 감싸 is_projected가 False가 되고 투영 파라미터가 Helmert 7모수에 가려진다 — strip_bound()로 벗겨서 판별하되, 수평 성분이 bound면 라벨과 무관하게 원문 WKT로 변환(보정 보존), 수직 성분의 bound(KNGeoid 지오이드)는 2D 변환에 무관하므로 무시. ② WKT1 재직렬화는 기본 신뢰도(70)로 DB 대조가 실패해 to_epsg(min_confidence=25)를 쓴다(라벨 용도, always_xy 변환에 무해).
  • B04_PreProcess_Engine_VWorld.get_epsg_from_prj() 재구현 — 문자열 분기 제거, 유틸 위임, 빈/불량 텍스트만 EPSG:5186 기본값 유지. 시그니처 불변.
  • B03_FileInput_Engine_Analyze_component_metadata()에 사다리 라벨 보강 + normalize_crs_metadata()에 BoundCRS 벗김(TOWGS84 PRJ의 수평 성분 탐색 실패 수정).
  • 검증 tmp/tests/test_common_util_crs.py13개 검사 전부 통과 (기존 스위트 포함 29 passed, ruff format·check 통과).
    • 자체검증 기록 (2026-08-31, ./venv/Scripts/python.exe -m pytest tmp/tests/ -q):
      • 업로드 LAS PRJ → 라벨 5176, 반환은 원문 WKT(bound), 변환 결과 울진 좌표 ✓
      • 업로드 노선 PRJ(AUTHORITY 없음) → 지문으로 5179, EPSG:5179 정식 변환과 1e-5도 이내 ✓
      • 표준 9종(5185~5188·5179·5174·5176·32652·4326) 왕복 라벨 일치 ✓
      • 회귀: 중부(5186)·서부(5185)·UTM52N WKT가 더는 5187로 오판되지 않음 ✓
      • 기존 COMPD_CS(KNGeoid24) PRJ → 예전과 동일한 "EPSG:5187" 문자열 반환(레거시 동등성) + 저장소 두 프로젝트 project_epsg_from_prj() 실측 EPSG:5187
      • COMPD WKT를 그대로 Transformer에 넣어도 EPSG:5187과 소수 8자리까지 동일 ✓
      • 빈/불량 텍스트 → EPSG:5186 기본값 ✓
    • 계획 대비 차이: 검사 6종 계획 → 13종으로 확대(레거시 동등성·BoundCRS 경로 추가).
    • 광역 스윕 추가 검증 (2026-08-31 사용자 요청): 한국 14종 + 해외 12종 (WebMercator·UTM·Lambert93·OSGB·NZTM·JGD2011 등) × WKT 3방언(GDAL·WKT2·ESRI) 78조합 전부 라벨·입력 일치. AUTHORITY 제거+이름 익명화 악조건 11종도 전부 정판별, 엉뚱한 코드 오판 0건. 검사 17개로 확대 — 17 passed.
  • ruff format·커밋·push 완료 (topic 브랜치 feat/prj-crs-identify).