diff --git a/B04_PreProcess/B04_PreProcess_Router.py b/B04_PreProcess/B04_PreProcess_Router.py index a1df3a3d..8615af91 100644 --- a/B04_PreProcess/B04_PreProcess_Router.py +++ b/B04_PreProcess/B04_PreProcess_Router.py @@ -22,6 +22,7 @@ from B04_PreProcess.B04_PreProcess_Engine_Extent import ( planned_route_bounds, project_epsg_from_prj, ) +from B04_PreProcess.B04_PreProcess_Engine_Ground import available_filters from B04_PreProcess.B04_PreProcess_Repository import ( clear_confirmed_surface_models, get_input_file, @@ -325,7 +326,9 @@ async def get_surface_point_cloud( source_path = structured_path if filter is not None: - if filter not in {"grid_min_z", "csf", "pmf"}: + # 필터 목록은 Ground 의 등록부 하나에서 나온다 — 여기 따로 적어 두면 + # 필터가 늘 때마다 이 화면만 400으로 막힌다(2026-09-01 실사고). + if filter not in available_filters(): return JSONResponse( status_code=400, content={"status": "error", "message": "지원하지 않는 지면 필터입니다."}, diff --git a/B04_PreProcess/B04_PreProcess_UI_Page.ts b/B04_PreProcess/B04_PreProcess_UI_Page.ts index f3154c41..41781d40 100644 --- a/B04_PreProcess/B04_PreProcess_UI_Page.ts +++ b/B04_PreProcess/B04_PreProcess_UI_Page.ts @@ -529,6 +529,14 @@ export async function renderB04Surface(root: HTMLElement): Promise { terrainViewer.setContourInterval(confirmed.contour_interval_m); renderInputFiles(inputs.files); renderStatus(status); + // 3D 좌표 환산 기준은 확정 서피스에서 먼저 받는다(수 KB). 포인트클라우드는 수십 MB라 + // 늦거나 실패할 수 있는데, 그때 노선까지 같이 사라지면 안 된다. + if (confirmed.bounds) terrainViewer.setReferenceBounds(confirmed.bounds); + // 계획노선을 3D 최고 표고 평면에도 얹는다 — 라이다가 노선을 어디까지 덮는지 + // 평면상으로 바로 보인다(2026-09-01 사용자 지시). + void fetchPlannedRoute(projectId) + .then((route) => terrainViewer.setRoute(route.points ?? [])) + .catch(() => terrainViewer.setRoute([])); viewer.setLoading("포인트 데이터 로딩 중…"); try { pointCloud = await fetchSurfacePointCloud( @@ -537,11 +545,6 @@ export async function renderB04Surface(root: HTMLElement): Promise { ); terrainViewer.setReferenceBounds(pointCloud.bounds); viewer.render(pointCloud); - // 계획노선을 3D 최고 표고 평면에도 얹는다 — 라이다가 노선을 어디까지 덮는지 - // 평면상으로 바로 보인다(2026-09-01 사용자 지시). - void fetchPlannedRoute(projectId) - .then((route) => terrainViewer.setRoute(route.points ?? [])) - .catch(() => terrainViewer.setRoute([])); // 지도(2D)는 계획노선 기준으로 연다 — 라이다 범위와 다루는 범위가 다르다. mapViewer.render(projectId, confirmed.route_bounds); } catch {