--- status: stable page_id: B04_wf1_Surface related_pages: ["[[B04_wf1_Surface/B04_frontend]]", "[[B04_wf1_Surface/B04_api]]", "[[B04_wf1_Surface/B04_db]]", "[[B04_wf1_Surface/B04_dependencies]]", "[[B03_FileInput/B03_backend]]", "[[B05_wf2_Route/B05_backend]]"] last_updated: 2026-07-12 --- # B04_wf1_Surface — Backend WF1 지표면 분석. LAS 구조화 → 지면 필터 → 지표면 5종 모델 생성 → 스무딩/등고선. 무거운 연산은 `asyncio.to_thread`로 실행. ## 파일 구성 (오케스트레이터/저장소/라우터) | 파일 | 위치 | 역할 | |---|---|---| | `B04_wf1_Surface_Router.py` | `B04_wf1_Surface_Router.py:1-739` | `/api/projects` 12개 엔드포인트 → [[B04_wf1_Surface/B04_api]] | | `B04_wf1_Surface_Schema.py` | `B04_wf1_Surface_Schema.py:1-113` | 요청/응답 검증 | | `B04_wf1_Surface_Repository.py` | `B04_wf1_Surface_Repository.py:1-236` | processed_point_cloud/surface_models Raw SQL | | `B04_wf1_Surface_Engine.py` | `B04_wf1_Surface_Engine.py:27` | `run_surface_analysis()` 오케스트레이터(구조화→필터→모델빌드) | ## 엔진 서브모듈 | 파일 | 역할 | |---|---| | `..._Engine_Structurize.py` | LAS/LAZ 구조화(structured.npz) | | `..._Engine_Ground.py` | 지면 마스크 생성/요약(`build_ground_masks`, `summarize_masks`) | | `..._Engine_Filter_Grid/CSF/PMF/RANSAC.py` | 지면 필터 4종 | | `..._Engine_Pipeline.py` | `build_all_terrain_models()` 지표면 모델 파이프라인 + manifest | | `..._Engine_ModelContext.py` | 모델 공통 컨텍스트/메시 유틸 | | `..._Engine_ModelBuild.py` | TIN/DTM/NURBS/implicit/meshfree 생성 | | `..._Engine_Smooth.py` | DTM/TIN 스무딩 | | `..._Engine_Contour.py` | 등고선 생성 | | `..._Engine_GisVector.py` / `..._Engine_VWorld.py` / `..._Engine_MvtHelper.py` | GIS 벡터 / VWorld 배경지도 / MVT 헬퍼 | ## 주요 함수 (Router) | 함수 | 위치 | 역할 | |---|---|---| | `analyze_surface()` | `B04_wf1_Surface_Router.py:147` | 분석 실행: start_stage→to_thread(run_surface_analysis)→DB저장→complete_stage | | `save_surface_analysis_to_db()` | `B04_wf1_Surface_Router.py:90` | processed_point_cloud + surface_models INSERT (호출자 트랜잭션) | | `get_wf1_analysis_status()` | `B04_wf1_Surface_Router.py:372` | 상태 조회(project_workflow_stages 우선, 폴백) | | `update_project_status()` | `B04_wf1_Surface_Router.py:76` | ⚠️ 정의만 있고 **호출처 없음**(죽은 코드, grep 확인) | ## 워크플로우 상태 전이 analyze 흐름에서 `project_workflow_stages`(stage 1) 전이: - `start_stage(cursor, project_id, 1, params)` — `B04_wf1_Surface_Router.py:168` - `complete_stage(cursor, project_id, 1)` — `B04_wf1_Surface_Router.py:209` - `fail_stage(cursor, project_id, 1, err)` — `B04_wf1_Surface_Router.py:227,233` → SSOT 정의·전파 규칙 → [[workflow_state]] ## ⚠️ 레거시 폴백 (416,420줄) `get_wf1_analysis_status()`는 `project_workflow_stages`를 **우선** 조회하고, 행이 없을 때만(백필 미작동 대비) `projects.status` 문자열 비교로 폴백: - 416줄 `project_status == "WF1_COMPLETE"`, 420줄 `"WF1_ANALYZING"` (`B04_wf1_Surface_Router.py:412-427`) 이전 wiki는 "구형 잔재, 정리 필요"로 표기했으나, 실제로는 정상 경로가 아닌 **방어적 폴백**. SSOT가 안정화되면 제거 가능하나 현재는 백필 안전장치로 동작 중. ## 책임 LAS 구조화·지면 필터 → 변환 포인트클라우드 저장 → 지표면 5종 모델 생성 → 스무딩/등고선/미리보기 → 모델 확정 및 하위 단계(B05) stale 전파([[workflow_state]]). ## 의존성 - [[common_util]] — `common_util_workflow_state`(start/complete/fail_stage), 저장소 경로 헬퍼 - 외부 라이브러리 → [[B04_wf1_Surface/B04_dependencies]] - DB → [[B04_wf1_Surface/B04_db]] - config: `SURFACE_MODEL_SOURCE_FILTERS`, `SURFACE_MODEL_PRECOMPUTE`, `build_surface_model_config`