diff --git a/common_util/common_util_crs.py b/common_util/common_util_crs.py index 35ff8b5b..fb56efbe 100644 --- a/common_util/common_util_crs.py +++ b/common_util/common_util_crs.py @@ -124,18 +124,45 @@ def identify_epsg(crs: CRS, wkt_text: str | None = None) -> int | None: return None +_TERRAIN_DATA_GLOBS = ("las/*", "laz/*", "tif/*", "tfw/*") + + def find_project_prj(project_root: Path) -> Path | None: """프로젝트 **작업 좌표계**를 정하는 PRJ를 고른다. 자료가 둘 이상의 좌표계로 들어온다(실측 2026-08-31 — 노선 shapefile은 UTM-K, - 지형은 동부원점 Bessel). 서피스 격자가 모델좌표의 주인이므로 지형 PRJ가 우선이고, - 노선 PRJ는 shapefile 세트 폴더(`input/shp/`) 안에 있어 여기서 섞이지 않는다. - 파일명 정렬 순서에 기대던 옛 `glob()[0]`을 대신한다. + 지형은 동부원점 Bessel). 서피스 격자가 모델좌표의 주인이므로 **지형 PRJ**를 쓴다. + 노선 PRJ는 shapefile 세트 폴더(`input/shp/`)에 있어 여기서 섞이지 않는다. + + `input/prj/`에도 PRJ가 여럿 쌓인다 — 자료를 다시 올려도 파일명이 다르면 옛 PRJ가 + 남기 때문이다. 이름 정렬로 고르면 잔재를 집는다(실측 2026-08-31: 옛 `result.prj` + (5187)가 새 `용화.prj`(5176)보다 앞서 뽑혀 노선이 Y로 100,000m 어긋났고 B05 + 경로 계산이 400으로 실패했다). 그래서 **지금 쓰는 지형 자료(LAS·TIF·TFW)와 + basename이 같은 PRJ**를 먼저 찾고, 못 찾으면 가장 최근 것을 쓴다. """ - terrain = sorted(project_root.glob("B03_FileInput/input/prj/*.prj")) - if terrain: - return terrain[0] + prj_dir = project_root / "B03_FileInput" / "input" / "prj" + candidates = sorted(prj_dir.glob("*.prj")) if prj_dir.is_dir() else [] + if candidates: + if len(candidates) == 1: + return candidates[0] + input_root = project_root / "B03_FileInput" / "input" + terrain_stems = { + path.stem + for pattern in _TERRAIN_DATA_GLOBS + for path in input_root.glob(pattern) + if path.is_file() + } + paired = [path for path in candidates if path.stem in terrain_stems] + pool = paired or candidates + chosen = max(pool, key=lambda path: path.stat().st_mtime) + if not paired: + logger.warning( + "지형 자료와 짝이 되는 PRJ를 찾지 못해 가장 최근 PRJ를 씁니다: %s", chosen.name + ) + return chosen remainder = sorted(project_root.glob("B03_FileInput/**/*.prj")) + # 노선 세트 폴더의 PRJ는 노선 좌표계라 프로젝트 좌표계가 될 수 없다. + remainder = [path for path in remainder if path.parent.name != "shp"] or remainder return remainder[0] if remainder else None