Merge remote-tracking branch 'origin/feat/b03-route-shapefile' into feat/b07-cover-template
# Conflicts: # B03_FileInput/B03_FileInput_Service_Chain.py
This commit is contained in:
@@ -301,11 +301,16 @@ def download_geodata(
|
||||
실패해도 예외를 밖으로 던지지 않는다 — 분석 본체를 막지 않는다.
|
||||
"""
|
||||
try:
|
||||
# 입력 파일과 같은 폴더의 .prj를 우선 사용 (PLAN E-1: 전체 재귀 glob 제거)
|
||||
prj_candidates = sorted(prj_search_dir.glob("*.prj")) or sorted(
|
||||
project_root.glob("B03_FileInput/**/*.prj")
|
||||
# 입력 파일과 같은 폴더의 .prj를 우선 사용 (PLAN E-1: 전체 재귀 glob 제거).
|
||||
# 없으면 지형 PRJ — 노선 shapefile 세트의 PRJ가 섞이지 않도록 고른다(2026-08-31).
|
||||
from common_util.common_util_crs import find_project_prj
|
||||
|
||||
prj_candidates = sorted(prj_search_dir.glob("*.prj"))
|
||||
prj_path = (
|
||||
prj_candidates[0]
|
||||
if prj_candidates
|
||||
else (find_project_prj(project_root) or project_root / "result.prj")
|
||||
)
|
||||
prj_path = prj_candidates[0] if prj_candidates else project_root / "result.prj"
|
||||
|
||||
from B04_PreProcess.B04_PreProcess_Engine_Extent import (
|
||||
download_extent,
|
||||
|
||||
@@ -144,10 +144,16 @@ def planned_route_bounds(project_root: Path, target_epsg: str) -> dict[str, floa
|
||||
|
||||
|
||||
def project_epsg_from_prj(project_root: Path) -> str:
|
||||
"""프로젝트 PRJ에서 좌표계를 읽는다. 없으면 중부원점(EPSG:5186)."""
|
||||
"""프로젝트 PRJ에서 좌표계를 읽는다. 없으면 중부원점(EPSG:5186).
|
||||
|
||||
PRJ가 둘 이상 올라오므로(노선 세트 + 지형) 지형 PRJ를 고른다 — `find_project_prj`.
|
||||
"""
|
||||
from common_util.common_util_crs import find_project_prj
|
||||
|
||||
from .B04_PreProcess_Engine_VWorld import get_epsg_from_prj
|
||||
|
||||
for prj_path in sorted(project_root.glob("B03_FileInput/**/*.prj")):
|
||||
prj_path = find_project_prj(project_root)
|
||||
if prj_path is not None:
|
||||
return get_epsg_from_prj(prj_path.read_text(encoding="utf-8", errors="ignore"))
|
||||
return "EPSG:5186"
|
||||
|
||||
|
||||
@@ -451,14 +451,14 @@ def build_sheet_surface_from_route(
|
||||
"""B03 업로드 계획노선 CSV를 찾아 방식별 도엽 서피스를 만든다. 없으면 빈 목록."""
|
||||
from common_util.common_util_route_geometry import (
|
||||
find_planned_route_file,
|
||||
read_planned_route_csv,
|
||||
read_planned_route,
|
||||
)
|
||||
|
||||
route_file = find_planned_route_file(project_root / "B03_FileInput" / "input")
|
||||
if route_file is None:
|
||||
logger.warning("도엽 서피스: 계획 노선 파일이 없습니다.")
|
||||
return []
|
||||
planned = read_planned_route_csv(route_file)
|
||||
planned = read_planned_route(route_file)
|
||||
if planned is None or len(planned.vertices) < 2:
|
||||
logger.warning("도엽 서피스: 계획 노선 파일을 읽지 못했습니다: %s", route_file.name)
|
||||
return []
|
||||
@@ -478,7 +478,7 @@ def run_sheet_surface_analysis(
|
||||
|
||||
반환 형식은 `run_surface_analysis()`와 같다(save_surface_analysis_to_db 호환).
|
||||
"""
|
||||
from common_util.common_util_route_geometry import read_planned_route_csv
|
||||
from common_util.common_util_route_geometry import read_planned_route
|
||||
|
||||
def _report(percent: int, stage: str, message: str) -> None:
|
||||
if on_progress is not None:
|
||||
@@ -490,7 +490,7 @@ def run_sheet_surface_analysis(
|
||||
processed_dir.mkdir(parents=True, exist_ok=True)
|
||||
models_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
planned = read_planned_route_csv(route_csv_path)
|
||||
planned = read_planned_route(route_csv_path)
|
||||
if planned is None or len(planned.vertices) < 2:
|
||||
raise ValueError(f"계획 노선 파일을 읽지 못했습니다: {route_csv_path.name}")
|
||||
epsg = planned.epsg or 5186
|
||||
|
||||
@@ -250,7 +250,7 @@ async def get_planned_route(project_id: UUID) -> dict[str, Any] | JSONResponse:
|
||||
from B04_PreProcess.B04_PreProcess_Engine_Extent import project_epsg_from_prj
|
||||
from common_util.common_util_route_geometry import (
|
||||
find_planned_route_file,
|
||||
read_planned_route_csv,
|
||||
read_planned_route,
|
||||
)
|
||||
|
||||
pool = get_db_pool()
|
||||
@@ -259,7 +259,7 @@ async def get_planned_route(project_id: UUID) -> dict[str, Any] | JSONResponse:
|
||||
stored_path = await get_project_storage_relative_path(connection, project_id)
|
||||
project_root = Path(resolve_stored_project_path(stored_path))
|
||||
route_file = find_planned_route_file(project_root / "B03_FileInput" / "input")
|
||||
planned = read_planned_route_csv(route_file) if route_file else None
|
||||
planned = read_planned_route(route_file) if route_file else None
|
||||
if planned is None or len(planned.vertices) < 2:
|
||||
return {"status": "success", "points": []}
|
||||
|
||||
@@ -267,7 +267,7 @@ async def get_planned_route(project_id: UUID) -> dict[str, Any] | JSONResponse:
|
||||
# 그것이 프로젝트 좌표계와 다르면 여기서 한 번 옮긴다.
|
||||
target_epsg = project_epsg_from_prj(project_root)
|
||||
points = [(float(vertex.x), float(vertex.y)) for vertex in planned.vertices]
|
||||
source_epsg = f"EPSG:{planned.epsg}" if planned.epsg else target_epsg
|
||||
source_epsg = planned.crs_input or target_epsg
|
||||
if source_epsg != target_epsg:
|
||||
from pyproj import Transformer
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ from B04_PreProcess.B04_PreProcess_Engine_Watershed_Grid import GridSpec
|
||||
from B05_Profile.B05_Profile_Repository import get_surface_crs_epsg
|
||||
from common_util.common_util_route_geometry import (
|
||||
find_planned_route_file,
|
||||
read_planned_route_csv,
|
||||
read_planned_route,
|
||||
)
|
||||
from common_util.common_util_storage import resolve_stored_project_path
|
||||
from config.config_db import get_db_pool
|
||||
@@ -80,7 +80,7 @@ async def _resolve_epsg(project_id: UUID, stored_path: str) -> str:
|
||||
epsg = await get_surface_crs_epsg(connection, project_id, 0)
|
||||
project_root = Path(resolve_stored_project_path(stored_path))
|
||||
route_file = find_planned_route_file(project_root / "B03_FileInput" / "input")
|
||||
planned = read_planned_route_csv(route_file) if route_file else None
|
||||
planned = read_planned_route(route_file) if route_file else None
|
||||
source = (planned.epsg if planned else None) or epsg or 5186
|
||||
return f"EPSG:{source}"
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ from B05_Profile.B05_Profile_Repository import get_surface_crs_epsg
|
||||
from common_util.common_util_route_geometry import (
|
||||
StructureCandidate,
|
||||
find_planned_route_file,
|
||||
read_planned_route_csv,
|
||||
read_planned_route,
|
||||
)
|
||||
from common_util.common_util_storage import resolve_stored_project_path
|
||||
from common_util.common_util_wamis_rainfall import (
|
||||
@@ -172,7 +172,7 @@ async def _prepare(project_id: UUID) -> dict[str, Any] | JSONResponse:
|
||||
status_code=404,
|
||||
content={"status": "error", "message": "계획 노선 파일이 업로드되지 않았습니다."},
|
||||
)
|
||||
planned = read_planned_route_csv(route_file)
|
||||
planned = read_planned_route(route_file)
|
||||
if planned is None or len(planned.vertices) < 2:
|
||||
return JSONResponse(
|
||||
status_code=400,
|
||||
@@ -246,7 +246,7 @@ def _route_center_lonlat(stored_path: str, fallback_epsg: int | None) -> tuple[f
|
||||
route_file = find_planned_route_file(_route_input_dir(stored_path))
|
||||
if route_file is None:
|
||||
return None
|
||||
planned = read_planned_route_csv(route_file)
|
||||
planned = read_planned_route(route_file)
|
||||
if planned is None or not planned.vertices:
|
||||
return None
|
||||
middle = planned.vertices[len(planned.vertices) // 2]
|
||||
|
||||
Reference in New Issue
Block a user