- `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>
13 KiB
13 KiB
status, page_id, related_pages, last_updated, source
| status | page_id | related_pages | last_updated | source | |||||
|---|---|---|---|---|---|---|---|---|---|
| stable | B04_PreProcess | 2026-08-30 |
|
B04_PreProcess — Backend
WF1 지표면 분석. LAS 구조화 → 지면 필터 → 지표면 5종 모델 생성 → 스무딩/등고선. 무거운 연산은 asyncio.to_thread로 실행. 또한 프로젝트 bounds 기준 1:5,000 수치지형도 도엽 3x3 자동 취득 및 등고선 하강 기반 배수유역 1차 해석 영구저장 캐싱을 전담. B04/B05 배수유역 설계 및 관 편집 데이터 소스(SSOT)가 B04로 단일화되어 관련 API 서빙을 전담합니다.
파일 구성 (오케스트레이터/저장소/라우터)
| 파일 | 위치 | 역할 |
|---|---|---|
B04_PreProcess_Router.py |
B04_PreProcess_Router.py |
/api/projects 핵심 분석/모델/확정 엔드포인트 및 GET /confirmed (0.4KB 확정 지표면 요약, 0.018s 응답) (700줄 한계 규정 준수). |
B04_PreProcess_Router_GIS.py |
B04_PreProcess_Router_GIS.py |
VWorld 이미지, GeoJSON, MVT 타일, 원청 계획선 좌표(GET /planned-route), 도엽 벡터 레이어 (raw byte direct 전송 + ETag 적용) 라우터. |
B04_PreProcess_Router_Contour.py |
B04_PreProcess_Router_Contour.py |
등고선 생성 및 캐시 다운로드 서빙 라우터 (700줄 한계 규정 준수). |
B04_PreProcess_Router_Watershed.py |
B04_PreProcess_Router_Watershed.py |
GET /{project_id}/drainage/primary-region 배수유역 1차 해석 및 WAMIS 관측소 수급/지역 분기(본토 관측소 반경10km 최대지점, 제주 등우선) 라우터. |
B04_PreProcess_Router_Inflow.py |
B04_PreProcess_Router_Inflow.py |
[신설/2026-08-01] GET /{project_id}/drainage/road-inflow 도로 유입 흐름 강도 1m 해상도 곡선, 유입 집중점 마커 및 기여 셀 외곽선 폴리곤 라우터 (700줄 한계 규정 준수). |
B04_PreProcess_Router_Basins.py |
B04_PreProcess_Router_Basins.py |
[신설/2026-08-01] 관 매설 지점 및 세부유역 분할 연산 제어 라우터 (GET/POST/PUT/DELETE /{project_id}/drainage/basins). (B04/B05 배수 데이터 일원화 통합 라우터) |
B04_PreProcess_Schema.py |
B04_PreProcess_Schema.py |
요청/응답 Pydantic 검증 |
B04_PreProcess_Repository.py |
B04_PreProcess_Repository.py |
processed_point_cloud/surface_models Raw SQL 및 DB 트랜잭션 헬퍼 |
B04_PreProcess_Engine.py |
B04_PreProcess_Engine.py |
run_surface_analysis() 오케스트레이터, 노선 시/종점 기반 도엽 선정(neighbors_for_points()), 잔재 zip 정리(prune_sheets()) |
엔진 서브모듈
| 파일 | 역할 |
|---|---|
..._Engine_Structurize.py |
LAS/LAZ 구조화(structured.npz) 및 입력 정체성(파일명+크기+mtime) 캐시 가드 적용 |
..._Engine_Ground.py |
지면 마스크 생성/요약(build_ground_masks, summarize_masks) |
..._Engine_Filter_Grid/CSF/PMF.py |
지면 필터 3종 |
..._Engine_Pipeline.py |
build_all_terrain_models() 지표면 모델 파이프라인 + dtm 우선 빌드 + manifest |
..._Engine_ModelContext.py |
모델 공통 컨텍스트/메시 유틸 |
..._Engine_ModelBuild.py |
TIN/DTM/NURBS/implicit/meshfree 생성 |
..._Engine_Smooth.py |
DTM/TIN 스무딩 |
..._Engine_Contour.py |
저장 TIN faces·meshfree 단일 Delaunay를 공용 rasterize_triangle_mesh()로 직접 격자화. float32 UTM 축은 searchsorted로 처리하며 15유닛·스무딩을 유지한다. 2026-08-17 검증에서 등고선 27분 39초→77.6초, meshfree·dtm 완전 일치, TIN 정점 −0.03~−0.07%(화면 확인 후속). |
..._Engine_Watershed_Grid.py |
[배수유역 하강] 격자 규격, 1차 영역, 셀 마스크 |
..._Engine_Watershed_Stream.py |
[배수유역 하강] 세류망 노딩·도로 절단·상류 추출 |
..._Engine_Watershed_Descent.py |
[배수유역 하강] 등고선 하강 potential·방위(32방위) 산출 |
..._Engine_Watershed_Flow.py |
[배수유역 하강] 세류 burn, 사슬 추적 적/청 판정 |
..._Engine_Watershed_Analyze.py |
[배수유역 하강] ①~⑧ 배수유역 오케스트레이션 + 유입 집중점 find_inflow_hotspots() 산출 + 평균 화살표(10m ... 원형 평균) 백엔드 산출 |
주요 함수 (Router / Repository / Engine / Utility)
| 함수 | 위치 | 역할 |
|---|---|---|
get_road_inflow() |
B04_PreProcess_Router_Inflow.py |
GET /api/projects/{id}/drainage/road-inflow: 도로 유입 흐름 강도 1m 해상도 노출 및 기여 셀 외곽선 폴리곤(polygonize_labels) 조회 |
find_inflow_hotspots() |
B04_PreProcess_Engine_Watershed_Analyze.py |
관 최소 간격(20m) 양 편측 제외 그리디 기반 유입 집중점 마커 위치 산출 |
get_planned_route() |
B04_PreProcess_Router_GIS.py |
GET /api/projects/{id}/planned-route: 2D 배경 지도 표기용 B03 원청 계획노선 CSV 2D 좌표 추출 및 CRS 변환 API |
get_confirmed_surface() |
B04_PreProcess_Router.py:372 |
GET /api/projects/{id}/surface/confirmed: B05 수신량 절감을 위한 0.4KB 확정 지표면 요약 fast-path API |
get_drainage_basins() |
B04_PreProcess_Router_Basins.py |
GET /api/projects/{id}/drainage/basins: 관 매설 정보(pipe_points.json) 및 세부유역(04_detailed_basins.geojson) 데이터 조회 API (B04/B05 공용) |
update_drainage_basins() |
B04_PreProcess_Router_Basins.py |
POST /api/projects/{id}/drainage/basins: 관 매설 포인트 편집 및 임시 세부유역 분할 계산 API (common_util_drainage_detail 공용 엔진 연동, B04/B05 공용) |
confirm_drainage_basins() |
B04_PreProcess_Router_Basins.py |
PUT /api/projects/{id}/drainage/basins: 세부 배수유역 구조 확정 및 pipe_points.json/04_detailed_basins.geojson 최종 영구보존 API (B04/B05 공용) |
delete_drainage_basins() |
B04_PreProcess_Router_Basins.py |
[신설/2026-08-02] DELETE /api/projects/{id}/drainage/basins: 관 매설 저장분 및 세부유역 GeoJSON 물리적 디스크 삭제 및 자동배치 갱신 API (B04/B05 공용) |
_apply_recommendations() |
B04_PreProcess_Router_Basins.py |
자동 배치 관에 추천 관경·시설을 넣고 사용자 변경값·기존 옵션을 보호 |
analyze_surface() |
B04_PreProcess_Router.py:88 |
분석 실행: start_stage → clear_confirmed_surface_models → to_thread(run_surface_analysis) → save_surface_analysis_to_db |
confirm_surface() |
B04_PreProcess_Router.py:206 |
모델 수동 확정: 트랜잭션 내에서 기존 CONFIRMED 행들을 COMPLETE로 되돌리고, 선택된 모델을 CONFIRMED로 변경 후 complete_stage 호출 (SYSTEM_ADMIN 전용) |
confirm_surface_selection() |
B04_PreProcess_Service.py:39 |
재사용 가능한 확정 서비스 헬퍼: CONFIRMED 처리, stage 1 params 스냅샷 저장 및 complete_stage(1) 수행 (API 및 자동 확정이 공유) |
get_surface_confirmation_params() |
common_util_surface_confirmation.py:42 |
확정 params 스냅샷 조회: 스냅샷이 존재하면 이를 우선 사용하고, 없으면 config 기본값으로 폴백 조회 (B05 등 연동 경로 통합 경유) |
merge_surface_confirmation_params() |
common_util_surface_confirmation.py:66 |
기존 stage 1 params에 확정 선택값 전체를 병합 저장 |
save_surface_analysis_to_db() |
B04_PreProcess_Repository.py:336 |
processed_point_cloud + surface_models INSERT (호출자 트랜잭션) |
delete_project_surface_models() |
B04_PreProcess_Repository.py:321 |
재분석 시 이전 세대의 유령 모델 정보 누적 방지를 위해 기존 surface_models 삭제 |
get_wf1_analysis_status() |
B04_PreProcess_Router.py:369 |
상태 조회(project_workflow_stages 우선, 폴백) |
_cache_contours_safely() |
B04_PreProcess_Engine_Pipeline.py:111 |
등고선 캐시 오류 발생 시에도 모델 빌드 프로세스가 롤백되지 않도록 경고 로깅 처리 |
수치지형도 도엽 오버레이 아키텍처 (2026-07-26, 2026-08-01 S8 개편)
- 도엽 zip 영구보존 및 processed/map_sheets/: VWorld를 통해 다운로드한 도엽 zip 원본 및 인덱스 메타(
map_sheets_index.json)는{프로젝트 영구저장소}/B04_PreProcess/processed/map_sheets/경로에 보관하며,prune_sheets()를 통해 21개 비대상 잔재 zip을 자동 정리합니다. - 노선 시/종점 기준 도엽 선정: 기존 LAS 전체 bounds 기반 도엽 선정 대신
neighbors_for_points()를 구현하여 계획노선 시/종점 좌표 기반 도엽 합집합을 선정하여 불필요한 도엽 수집을 최소화합니다. - 크롭 철회 및 raw byte 서빙: 사용자 요청에 따라 도엽 잘라내기(크롭)를 철회하고 원본 등고선 전송을 유지하며, JSON 재직렬화 대신 raw byte direct 전송 및 ETag 304 응답 처리(
B04_PreProcess_Router_GIS.py, 2.0s -> 0.006s)를 적용했습니다. - 위성사진 범위 확대 (
SURFACE_MAP_MARGIN_TILES = 3): 위성사진 타일 여유폭을 3타일로 확장하고 타임스탬프(_t=)를 제거하여 ETag/304 응답을 활성화했습니다. - VWorld 취득 자동화: 검색 API(무로그인)와 다운로드 API(자격증명
.envVWORLD_LOGIN_ID/PW활용 세션 로그인)를 파이썬 백엔드에서 오케스트레이션하여, 세션 만료 시에도 무인 구동하도록 재로그인 1회 재시도 정책을 포함합니다.
워크플로우 상태 전이 및 자동 확정
일반 역할(role != "SYSTEM_ADMIN")인 경우 B03 분석이 끝난 시점에 백엔드에서 비동기 스레드 바깥(B03_FileInput_Service_WF1.py)에서 confirm_surface_selection()을 자동 호출하여 모델을 자동 확정하고 stage 1 COMPLETE를 격발합니다.
- complete_stage(1) 호출 지점 일원화: 기존 B03 라우터에서 분석 직후 stage 1 COMPLETE를 시키던 결함을 해결하고, 수동/자동 확정 서비스 내부로 일원화하였습니다.
- 스텝바 disabled 및 진입 가드: 일반 사용자는 B04 페이지 진입이 차단되며(disabled 처리), URL 강제 진입 시 stage 1 완료 여부에 따라 B05 또는 B03으로 분기 리다이렉트됩니다.
- uvicorn 로깅 부작용 완치: status API 폴링에 따른 access_log 전면 차단 옵션(
access_log=False)을 롤백하고, 일반 사용자 B04 진입 차단으로 인해 근본적인 로깅 비대화 문제가 해결되었습니다.
⚙️ 설정 및 환경 파일 정합성
- .env: uvicorn 자동 리로드로 인해 백그라운드 분석 스레드가 침묵 소멸하는 리스크 차단을 위해
DEBUG=False로 변경 - config/config_system.py:
SURFACE_CONFIRM_DEFAULT_FILTER="csf",SURFACE_CONFIRM_DEFAULT_METHOD="dtm"등 자동 확정 기본값 설정 관리SURFACE_MODEL_PRECOMPUTE순서에서dtm최우선 빌드되도록 조정- 수치 정합성 기준치 old 버전 값(implicit/TIN/meshfree 등)으로 원복
- 기본 등고선 사전 캐시 간격을 1.0m로 유지하도록
SURFACE_CONTOUR_INTERVAL_M=1.0설정
- requirements.txt: 현행
scipy==1.18.0. meshfree Delaunay 생성에는 사용하지만 등고선 격자 평가의find_simplex병목은 직접 삼각망 래스터화로 우회
📋 구현 예외 처리 검토 항목 (PLAN)
- 자동 확정 세션 분리: 백그라운드 스레드 에러 방지를 위해
confirm_surface트랜잭션을 로그인 세션 의존성 없이 DB 커넥션과 파라미터만 받는 독립 비동기 함수로 격리 설계. - 등고선 간격 포맷 통일: 부동소수점 오차로 인한 캐시 미인식 및 중복 연산 방지를 위해 등고선 간격은 API 및 파일 경로 조회 시 항상 소수점 1자리(예:
1.0)로 포맷팅하여 통일.
2D/GIS 미표시 원인 분석 및 조치
- PRJ 파일 부재로 인한 지도 다운로드 silent 스킵:
B04_PreProcess_Engine_VWorld.py의download_vworld_satellite_map이.prj파일 부재 시 별도 예외 없이 즉시None을 반환하여 위성 지도 및 메타데이터 생성이 무산됨. - 좌표계 불일치(5186 ↔ 5187)로 인한 WFS API 빈 피처 반환:
.prj파일이 없어 기본 투영을EPSG:5186(중부원점)으로 가정하여 좌표 변환을 하였으나, 업로드 데이터의 실제 투영계는EPSG:5187(동부원점)이었음. 이에 따라 BBOX 범위가 실제 범위에서 완전히 왜곡(바다 등)되어 브이월드 WFS API가 빈 GeoJSON 파일만 생성함. - 검증 및 해결: 수동 진단 스크립트(
scratch/test_vworld_download.py)를 통해 정확한 PRJ 경로(B03_FileInput/input/prj/result.prj)와 정합 좌표계를 입력한 경우 위성 지도와 국가 GIS 벡터 데이터들이 모두 정상적으로 다운로드됨을 확인함.