- `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>
10 KiB
10 KiB
PLAN: B04 결함 수정 6건 + 확정 흐름 주의점 보완 (2026-07-17)
활성 작업: B04 결함 수정 6건 + 확정 흐름 주의점 보완 (2026-07-17)
A. 지면 필터 미리보기가 원본 데이터를 표시 (핵심 결함)
- 현상: 지면 필터를 선택해도 필터링 후 데이터가 아닌 원본에서 50만 개를 샘플해 표시
- 원인 (확인됨):
GET .../surface/point-cloud가structured.npz(지면 필터 이전 구조화 원본)를 고정 조회 —B04_wf1_Surface_Router.py:332. 필터 파라미터 자체가 없음- 지면 필터 마스크는 분석 중 메모리에서만 생성·사용되고 영구저장되지 않음 —
B04_wf1_Surface_Engine.py:77-85(build_ground_masks→ 모델 빌드에 전달 후 소멸)
- 0_old 검증 프로그램의 방식 (준용):
create_ground_filter_cache(0_old/backend/app/analyzer.py:622-739)가 분석 시 필터링된 지면 포인트 자체를 브라우저 상한(0_old는 500만)으로 샘플해processed/ground-points.json으로 영구저장하고,GET .../ground-points(0_old/backend/app/main.py:166-170)가 캐시 파일을 그대로 서빙. 요청 시 재계산 없음 - 수정 방향 (0_old 패턴 준용):
- Engine: 분석 시 필터별 지면 포인트 캐시를
processed/ground_points_{filter}.npz로 영구저장 — 50만 규칙(초과 시 랜덤 50만, 이하 전체) 적용된 미리보기 서빙용. 메타(원본 지면 포인트 수, 샘플 수, bounds) 포함 - Router: point-cloud 엔드포인트에
filter쿼리 파라미터 추가 — 지정 시 해당 캐시 파일 서빙, 미지정 시 기존 원본(structured) 동작 유지 - Api_Fetch / UI_Page: 지면 필터 선택 변경 시
filter파라미터로 재조회 → 뷰어 렌더 - 기존 프로젝트에는 캐시 파일이 없음 → filter 요청 시 파일 부재면
structured.npz로 해당 필터만 온디맨드 재계산 후 캐시 저장(백필) - 경로(B05)·등고선 등 백엔드 분석은 종전대로 전체 필터링 데이터 기준(미리보기 캐시와 무관) 유지
- Engine: 분석 시 필터별 지면 포인트 캐시를
B. 등고선 간격 옵션 미작동
- 원인 (확인됨): 등고선은 분석 시 config 기본 간격(
contour_interval_meters=5.0m) 파일만 사전 생성 —B04_wf1_Surface_Engine_Pipeline.py:57-104. contour 엔드포인트는 파일 조회 전용이라 다른 간격 요청 시 파일이 없고, 폴백 glob이 기존 5.0m 파일을 반환 —B04_wf1_Surface_Router.py:655-662→ 간격 변경이 조용히 무시됨. 프론트 전달(interval파라미터)은 정상 —B04_wf1_Surface_UI_TerrainViewer.ts:383-385 - 수정 방향: 요청 간격의 파일이 없으면 저장된 모델 npz로 온디맨드 등고선 생성 후 파일 캐시 저장(기존
Engine_Contour함수 재사용,asyncio.to_thread). 폴백 glob은 생성 실패 시에만 사용하거나 제거
C. 스무딩 옵션 동작 불명확
- 확인된 사실: 프론트 연결은 정상(
smooth파라미터 전달 및 토글 시 재로드 —UI_TerrainViewer.ts:326-329,568-570). 스무딩은 tin/dtm 전용이며{stem}_smooth_preview.glb사전 생성 파일을 조회(Router.py:567-570). nurbs/implicit/meshfree는 토글해도 무동작이 현재 설계 - 수정 방향:
- 실행 검증: tin/dtm에서
_smooth_preview.glb·contour_*_smooth_*.json파일 실존 및 토글 시 메시 교체 여부 확인, 파일 누락 시 Pipeline 생성 경로 수정 - UX: 스무딩 미지원 기법(nurbs/implicit/meshfree) 선택 시 토글 비활성화(회색)로 "안 되는 게 아니라 해당 없음"을 명시
- 등고선도 스무딩 상태와 간격을 함께 반영(B와 연동)
- 실행 검증: tin/dtm에서
D. 2D 지도 이미지 왜곡 (그룹 컨테이너에 맞춰 늘어남)
- 원인 (확인됨):
.b04-map__image { object-fit: fill; width/height:100% }—B04_wf1_Surface_UI_Style.css:468-478. VWorld 배경 이미지가 뷰포트(가변 폭 × 고정 560px)에 종횡비 무시로 강제 인장됨. 이전에 보고된 "살짝 대각선" 현상도 이 왜곡이 원인일 가능성 높음 - 수정 방향: VWorld 요청 해상도를 뷰포트 실제 크기(종횡비)에 맞춰 요청하거나
object-fit정합 처리 + canvas GeoJSON 오버레이 좌표 변환 동기화. 수정 후에도 대각선 느낌이 남으면 투영 좌표 변환 재점검
F. 두 3D 뷰어 카메라 동기화의 스케일 불일치
- 현상: 포인트클라우드 미리보기 ↔ 지표면 표현 뷰어가 함께 움직이긴 하나 배율(스케일)이 서로 다름
- 원인 (확인됨): 카메라 상태를 비율로 주고받는데 정규화 기준이 서로 다름
- Viewer: 데이터를 최대 span=180 고정 공간으로 스케일링(
UI_Viewer.ts:202)하고distanceRatio = distance/180고정 기준(UI_Viewer.ts:165-187) - TerrainViewer: 실좌표 메시의 바운딩박스 span 기준
distance/sceneSpan(UI_TerrainViewer.ts:270-296) - 포인트클라우드 범위(현재는 원본이라 식생 포함 z-range 큼)와 지표면 메시 범위가 달라 같은 비율이 다른 배율로 나타남. A 수정 후에도 기준 데이터 범위가 완전히 같지 않으므로 잔존
- Viewer: 데이터를 최대 span=180 고정 공간으로 스케일링(
- 수정 방향: 카메라 상태를 실세계 좌표(m) 기준 공통 프레임으로 교환 — 각 뷰어가 자기 월드→씬 변환(Viewer: 180/span 배율+중심점, Terrain: sceneCenter)을 알고 있으므로, emit/apply 시 실좌표(중심 기준 오프셋 m, 거리 m)로 변환해 동기화. 축 방향 컨벤션(Viewer의 x/z/-y 스왑)도 함께 정합
G. 지표면 표현 뷰어가 컨테이너 전체를 사용하지 못함
- 원인 (확인됨): TerrainViewer 렌더 영역에 인라인
height: 520px고정(UI_TerrainViewer.ts:106) — 포인트클라우드 뷰어(.three-viewer560px,UI_Style.css:355-360)와 불일치하고, 2열 컨테이너 높이와 무관하게 고정됨 - 수정 방향: 인라인 높이 제거, 두 뷰어 동일한 CSS 규칙(컨테이너 기준 100% 또는 공통 고정값)으로 통일. ResizeObserver 기반 리사이즈는 이미 구현되어 있어(
UI_TerrainViewer.ts:587-596) CSS만 정리하면 추종함
E. 확정 흐름 주의점 보완 (2026-07-17 검증에서 발견)
enableRouteStep이 진행단계 버튼을 DOM 인덱스[2]하드코딩으로 탐색(UI_Page.ts:186-188) → 스텝 식별자/route 기반 탐색으로 변경 (스텝 순서 변경 시 무음 파손 방지)- 확정 토스트의
{smoothing}값이"-"고정(UI_Page.ts:304) → 실제 스무딩 토글 상태 연결 - B04 재진입 시(이미 확정 상태) WF2 스텝 활성화가 서버 workflowState 렌더에 의존 → 확정 → 새로고침 → 스텝 클릭 가능 여부 실행 검증, 불가하면 수정
- 잔여 확인: 지면 필터 드롭다운의
ransac제거(UI_Page.ts:54SOURCE_FILTERS) — 이전 계획 항목이나 현재 코드에 잔존 - 확정 성공 시 B05로 자동 이동 (사용자 확정, 2026-07-17): 확정 토스트 표시 후
goToWorkflowStage로 WF2(B05) 페이지 자동 전환. 스텝 수동 클릭 대기 방식 폐기 — 단,enableRouteStep의 스텝 활성화 처리는 뒤로가기/재진입 대비 유지
대상 파일
| 파일 | 작업 |
|---|---|
B04_wf1_Surface/B04_wf1_Surface_Engine.py |
필터별 지면 포인트 캐시 영구저장 (A) |
B04_wf1_Surface/B04_wf1_Surface_Router.py |
point-cloud filter 파라미터+캐시 서빙 (A), 등고선 온디맨드 생성 (B) |
B04_wf1_Surface/B04_wf1_Surface_Api_Fetch.ts |
point-cloud filter 파라미터 전달 (A) |
B04_wf1_Surface/B04_wf1_Surface_UI_Page.ts |
필터 선택 → 재조회 연결 (A), E-1·2·4 |
B04_wf1_Surface/B04_wf1_Surface_UI_Viewer.ts |
카메라 상태 실좌표 변환 (F) |
B04_wf1_Surface/B04_wf1_Surface_UI_TerrainViewer.ts |
스무딩 토글 UX (C), 카메라 상태 실좌표 변환 (F), 인라인 높이 제거 (G) |
B04_wf1_Surface/B04_wf1_Surface_UI_MapViewer.ts |
이미지 종횡비 정합 (D) |
B04_wf1_Surface/B04_wf1_Surface_UI_Style.css |
object-fit 수정 (D), 뷰어 높이 통일 (G) |
B04_wf1_Surface/B04_wf1_Surface_Engine_Pipeline.py |
(조건부) 스무딩 프리뷰 생성 누락 시 수정 (C) |
구현 체크리스트
- A-1. Engine: 분석 시 필터별
processed/ground_points_{filter}.npz캐시 저장 (50만 규칙 + 메타) - A-2. Router: point-cloud
filter파라미터 + 캐시 파일 서빙 - A-3. Router: 캐시 파일 부재 시 온디맨드 재계산·백필
- A-4. Api_Fetch/UI_Page: 필터 선택 → filter 파라미터 재조회·렌더
- B-1. Router: 요청 간격 등고선 파일 부재 시 온디맨드 생성 + 캐시 저장
- B-2. 폴백 glob 정리 (간격 무시 무음 동작 제거)
- C-1. tin/dtm 스무딩 프리뷰·등고선 파일 생성 여부 검증, 누락 시 Pipeline 수정
- C-2. 스무딩 미지원 기법에서 토글 비활성화
- D-1. VWorld 이미지 종횡비 정합 + canvas 오버레이 좌표 동기화
- F-1. Viewer/TerrainViewer: 카메라 상태를 실세계 좌표(m) 공통 프레임으로 emit/apply 변환 (축 컨벤션 정합 포함)
- F-2. 동기화 배율 일치 실행 검증 (양쪽 축척바 값 비교)
- G-1. TerrainViewer 인라인 높이 제거, 두 뷰어 높이 통일
- E-1. enableRouteStep 스텝 탐색 방식 개선
- E-2. 확정 토스트 스무딩 값 연결
- E-3. 확정 후 새로고침 시 WF2 스텝 활성화 실행 검증
- E-4.
SOURCE_FILTERS에서ransac제거 확인 - E-5. 확정 성공 시 B05 자동 이동 (
goToWorkflowStage) - 700줄 제한 및 라우터 분리:
B04_wf1_Surface_Router.py(643줄),B04_wf1_Surface_Router_GIS.py(175줄)로 분할하여 700줄 한계 준수 - GIS/VWorld 라우터 복원:
B04_wf1_Surface_Router_GIS.py유실 복구 및main.py기동 실패(ImportError) 해결
협의 완료 (2026-07-17 사용자 확정)
- 확정 후 자동 이동: 확정 성공 시 B05 자동 전환으로 확정 → E-5 반영
- A-3 백필 방식: 온디맨드 재계산 채택 — 기존 프로젝트(캐시 파일 없음)에서 필터 첫 선택 시 서버가
structured.npz로 해당 필터만 재계산해 캐시 생성 후 응답. 첫 선택에만 수 초 대기 발생, 이후 즉시 표시