- `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>
425 lines
35 KiB
Markdown
425 lines
35 KiB
Markdown
# 2026-09-03 완료 항목 이관
|
||
|
||
> 사용자가 완료 항목의 위치 정리를 요청했으며, 요청에 따라 위키 관리자의 2차 교차검증과 별도 검증보고서는 생략했다.
|
||
> `docs/raw/PLAN.md`에서 완료 체크 항목과 그 하위 원인·조치·자체검증 설명을 이관했다.
|
||
|
||
### 2026-09-03 화면 개선 (메인 창 · B05·B06 담당)
|
||
|
||
- [X] **I형 집수정 배관이 횡단도에 삼각형으로 그려짐** (사용자 항목 4).
|
||
|
||
- 원인 — `B06_Section_UI_Cross_Culvert_Solve.ts` `pipeAxisSolver.corners()` 가 관 끝단
|
||
두 꼭짓점을 마감면(I형 벽 안쪽 변) 선분 안으로 `clampToFace` 하는데, 원지반이 벽 상단
|
||
위라 관 시작점이 벽 상단에 붙으면 위·아래 교점이 **같은 끝점으로 접혀** 사각형이
|
||
삼각형이 됨. 13+4.1 실측 — 관 폴리곤 `[[594.6,418.7],[338.9,537.3],[348.5,505.4],[594.6,418.7]]`
|
||
(1번=4번 꼭짓점 동일), 집수정 벽 상단 `y=419` = 관 시작점 `y=418.7`.
|
||
- 조치 — 자른 끝단 길이가 관경보다 짧으면(비스듬히 자르면 항상 관경 이상) 접힌 것으로
|
||
보고 **축 직각 마감(fallback)** 으로 되돌림. 편집 단일 창구인 `corners()` 한 곳만 수정.
|
||
- 자체검증 — 공용 브라우저 B06(8+17.3·13+4.1 등 8개 단면) 실측:
|
||
수정 전 유입측 끝단 길이 `0.0 px`(세월교 1건 제외 전부), 수정 후 `18.7~58.4 px`
|
||
로 전부 살아남. `npm run typecheck` 통과, prettier 무변경.
|
||
- **2차 수정 (2026-09-03 사용자 지적 「측벽과 배관의 형상이 교차하고 있어야 함」)** —
|
||
1차 수정은 삼각형만 없앴을 뿐 관이 벽 위에 얹혀 벽과 만나지 않았음. ㄴ형과 대조해
|
||
(관이 바닥판 윗면에서 시작해 벽 안에 물림) 원인 확정: I형 관 하단이 벽면×원지반 교점인데
|
||
원지반이 벽 상단보다 높으면 교점이 상단으로 밀림. **교점을 벽 상단에서 관경+여유(0.5m)
|
||
아래로 제한**해 관이 벽을 관통하게 함. 벽을 키우는 안은 벽 기울기(1:0.3)로 base 가
|
||
계류측으로 밀려 벽이 7.5m 까지 자라 폐기.
|
||
- 2차 자체검증 — I형 8개 단면 관·벽 세로 겹침 `18.1~56.4 px`(수정 전 0). ㄴ형 대조는
|
||
13+4.1 을 조정창에서 ㄴ형으로 바꿔 확인 후 세션값 원복. pytest 370 passed·17 skipped.
|
||
- 육안검증 기록(아티팩트): https://claude.ai/code/artifact/c4ef706c-c3d8-461c-ae54-6c376980c043
|
||
- [X] **유토곡선 세부 항목이 리로딩 중 보였다가 사라짐** (사용자 항목 3) — 원인 규명 완료.
|
||
|
||
- 재현(공용 브라우저 30ms 폴링) — 2.0초 그림: 절토 6,908 / 성토 42,050 / 운반 5,571㎥,
|
||
평형선 6·장비 띠 9·balloon 12. 3.5초 그림: 절토 3,704 / 성토 14,881 / 운반 0㎥,
|
||
평형선 1·띠 0·balloon 1.
|
||
- 원인 — `B06_Section_UI_Page.ts:285 reconcileStaleDesigns()` 가 저장분 횡단 설계 중
|
||
현재 종단 계획선과 어긋난 측점을 일괄 재계산해 제자리 교체함. 첫 그림은 **재계산 전
|
||
저장분**(20m 구간당 성토 860㎥ — 임도에 불가능한 값), 둘째가 정본. 캐시 덮어쓰기·
|
||
숨김·토글 문제 아님(범례는 두 시점 모두 「토량 분배」 켜짐).
|
||
- 벌룬이 정본 상태에서 안 생기는 이유 — 성토 14,881 vs 절토 3,704(4배)라 누가토량 곡선이
|
||
0선을 한 번도 넘지 않아 평형선 계단이 서지 않음. 극값 가지치기 기준(범위×2%) 탓이
|
||
아님 — 실무 6건은 같은 기준으로도 극값이 14~53개 남음.
|
||
- 실무 원본 대조(`유토곡선.MASS` 6건 파싱) — 최종 누가토량 **+49 ~ +324㎥**, 0선 교차
|
||
3~17회. 용화는 **−11,094㎥ · 교차 0회**. 실무 `EARTH.DAT` 헤더 6건 전부 무대 20.0 /
|
||
도자 **60.0** m (현행 구현은 20/70).
|
||
- 조치 — 사용자 확정(2026-09-03 「절·성토 불균형 판정은 사용자 몫, 자동 조정 금지」)에
|
||
따라 **진단만 노출**: 유토곡선 요약줄에 「최종 누가토량」 칩 신설(툴팁에 균형 의미와
|
||
평형선 미생성 사유). B05·B06 공용 함수라 양쪽에 함께 뜸.
|
||
- 지식DB — [유토곡선_토량배분](../../resources/knowledge/technical_info/01_임도/03_계산정보/유토곡선_토량배분.md)
|
||
신설(실무 6건 관측표·장비 한계거리 후보·근거 공백 명시), 미결 20·21 등재.
|
||
- 자체검증 — 공용 브라우저 실측: 요약 칩이
|
||
`절토(자연) 3,704.6㎥ · 성토 14,881.8㎥ · 토취 11,094.6㎥ · 최종 누가토량 −11,094.6㎥ · 운반토량 계 0㎥ · 운반·성토 검산 −3,787㎥` 로 표시됨. `npm run typecheck` 통과,
|
||
prettier 통과.
|
||
- [X] **옛 계획고 유토곡선 노출 차단 + 사면 미교차 경고** (2026-09-03 사용자 확정).
|
||
|
||
- 「새 값만 보여주기」 — 저장 횡단이 지금 계획선과 어긋나면(재계산 예약) 유토곡선을
|
||
그리지 않고 안내만 띄움. B05·B06 양쪽 적용(`staleDesignChainages` 공용 판정).
|
||
- 「사면 미교차는 경고로 대체」 — 사면이 계산 반폭(±20m) 끝까지 원지반과 안 만나 면적이
|
||
잘린 측점에 카드 경고. 판정은 면적을 내는 엔진 한 곳(`B06_Section_Engine_Design`)이
|
||
`slope_unclosed` 로 내림 — 화면·수량·도면이 같은 기준을 봄. 계산은 무수정.
|
||
- 실측 근거 — 용화 65측점 중 **56개가 낡음**, 계획고 차 −9.36~+5.83m(예: 0+20 저장
|
||
875.36 → 현재 870.26, 저장분 성토 단면 85.9㎡ / 43+0 지점 256.4㎡).
|
||
- 자체검증 — 공용 브라우저: 2.6초 「재계산 중」 안내만(옛 값 미노출), 4.4초 정본 표시,
|
||
사면 미교차 경고 13/65측점. `pytest 366 passed·17 skipped`, typecheck·prettier 통과.
|
||
- [X] **B05·B06 유토곡선 일원화** (2026-09-03 사용자 지시 「하나의 데이터를 두 페이지에
|
||
보여 주는 기능이니 로직·템플릿이 다르면 일원화」). 갈림 3곳을 모두 한 벌로.
|
||
|
||
- **보는 노선** — B05는 최신 경로(`get_latest_route`), B06은 최신 **확정** 경로만 열어
|
||
노선을 다시 탐색한 프로젝트에서 서로 다른 노선을 봤음. 실측: B05 route 126(DRAFT) /
|
||
B06 route 125(CONFIRMED), 같은 20m 측점 계획고 870.26 ↔ 875.36 · 성토 4.82㎡ ↔ 85.9㎡.
|
||
→ `get_workflow_route_context()`(최신 경로) 신설, B06 화면 context가 사용.
|
||
납품 도면(B07)이 쓰는 확정 전용 창구는 그대로 둠.
|
||
- **횡단 재계산 창구** — 호출이 두 벌이라 인자가 갈림(B06만 표준 단면값·암 경계 오프셋
|
||
전달, 보존 사용자값 2개 ↔ 7개). → `B06_Section_Cross_Refresh.refreshCrossDesigns()`
|
||
하나로 통합, 세션 편집값은 저장소에서 직접 읽어 패널 없는 B05도 같은 값을 보냄.
|
||
- **낡음 판정** — 「옛 암 2단계 필드 누락」 조건이 B06 페이지에만 있어 B05는 재계산을
|
||
건너뜀(실측 절토 합 228.52㎡ ↔ 270.12㎡). → 공용 `staleDesignChainages()` 안으로 이관.
|
||
- 자체검증 — 공용 브라우저 실측: 두 화면 모두 route 126, 요약줄 문자열 **완전 일치**
|
||
(`절토(자연) 4,526.8㎥ · 성토 14,881.8㎥ · 토취 10,213.3㎥ · 최종 누가토량 −10,213.3㎥ · 운반토량 계 0㎥ · 운반·성토 검산 −4,669㎥`). `pytest 370 passed·17 skipped`
|
||
(일원화 소스검사 4건 신설 `tmp/tests/test_masshaul_single_source.py`, 기존 stale 규칙
|
||
테스트 1건은 조건 이관에 맞춰 갱신), typecheck·prettier·ruff 통과.
|
||
|
||
### 초기 계산 실패 처리 후속
|
||
|
||
- [X] `initial_design.failed` 마커 — **백필·재확정 적용 둘 다 안 함**(2026-09-03 사용자 결정).
|
||
새 실패만 마커를 남기는 현행 유지.
|
||
|
||
### LAS 없는 설계 — 곡선 경고 판정 후속
|
||
|
||
- [X] 지표면 종류별 계곡 시설 차이 — **원인 조사 완료**(2026-09-03).
|
||
- 시설 종류는 유효직경 하나로 갈린다: 1,500mm 초과 = BOX암거, 2,000mm 초과 = 세월교,
|
||
그 이하는 규격 스냅(800·1000·1200·1500). 임계 유량 실측 — BOX `3.711 ㎥/s`,
|
||
D800 `1.056 ㎥/s`.
|
||
- 저장 산출물 대조(같은 노선, 두 번의 LAS 해석): **200.9m 유역이 임계 위에 아슬아슬**하다 —
|
||
면적 28,907㎡ → D `1,529.3mm`, 29,209㎡ → D `1,537.3mm`. 임계 1,500mm 를 **2%** 차이로
|
||
넘는다. 면적이 1~2%만 작아지면 그대로 관(D1500)으로 내려간다. 같은 LAS 해석끼리도
|
||
면적이 1.0% 흔들린다(격자·트림 차이).
|
||
- 반면 관측된 **BOX → 관D800** 은 그 흔들림으로 설명되지 않는다. D800 이 되려면 설계유량이
|
||
3.5배(면적 기준 약 1/3.5) 줄어야 한다 — 표고 해상도 차이가 아니라 **유역 분할 자체가
|
||
달라진 것**이다. 같은 관측에서 4번째 시설 자리가 275.71m → 297.71m 로 옮겨진 것이 그
|
||
신호(관 위치가 바뀌면 유역 귀속이 통째로 재배분된다).
|
||
- 149.7m 유역은 414,106㎡ · D `4,719mm` 로 세월교 판정 — 관측과 일치.
|
||
|
||
### B08 CAD 후속
|
||
|
||
- [X] 도각 편집 안내 띠 — **이미 해결돼 있음**(2026-09-02 사이드바 액션 1행으로 이동).
|
||
2026-09-03 화면 실측: 띠는 `.b07-drawing-actions` 안(사이드바 하단 y=1243)에 평소 숨김
|
||
상태로 있어 CAD 리본과 겹칠 수 없음. 코드 변경 없음.
|
||
- [X] **SVG 서명 — CAD 벡터로 변환**(2026-09-03 사용자 결정). `_Engine_Cad_Svg` 신설(path
|
||
M·L·H·V·C·Q·S·T·Z, 곡선 16분할, viewBox 비율 유지·y 뒤집기). 래스터는 종전대로 ImageEntity.
|
||
- **화면 검증 불가**(2026-09-03) — 회사 자산 폴더(`storage/1/assets/`)의 서명·로고가
|
||
**전부 PNG**라 SVG 경로를 탈 자산이 하나도 없다. 단위 검증
|
||
(`tmp/tests/test_b07_signature_vector.py` 5건)만 선 상태. 화면으로 보려면 SVG 서명을
|
||
한 장 올려야 하므로 **사용자 판단 대기**(시험용 SVG 업로드 여부).
|
||
|
||
### B08 횡단도·장 배치 후속
|
||
|
||
- [x] **장 단위 확정 흐름 실측**(2026-09-03) — 용화 검증본 `d6997dd9` 3장(`cross_s00220m`)을
|
||
실제로 확정해 결함 3건을 찾아 고침(커밋 `4fdbcaf0`).
|
||
- ① 수량표 역추출이 측점을 구분하지 않음 — `_table_values_from_cells()` 가 도면의 표를
|
||
전부 훑어 **마지막 값**을 모든 측점에 기록(실측: 4측점 전부 지반고 `837.21`, 도면에는
|
||
840.87/840.33/836.45/837.21). 표 엔티티 id `uuid5(_ENTITY_NS, f"{drawing_id}:qtable")`
|
||
로 그 측점 표만 읽고, 못 찾으면 옛 도면 폴백.
|
||
- ② 계획고가 통째로 빔 — 장 배치 입력 원본에 계획고가 없어 21항목 중 지반고 1개만 채워짐.
|
||
`_quantity_table(source, design)` 이 횡단 설계의 `design_elevation_m` 도 보게 함.
|
||
- ③ 확정 해제(invalidate) 404 — 도면 목록을 `designs` 없이 만들어 장 나눔이 달라짐.
|
||
목록·확정과 같은 인자를 쓰게 함.
|
||
- 자체검증(백엔드 재시작 후 실동작) — invalidate `404 → 200`, 표 값이 측점마다 다름
|
||
(`ground=840.87 planned=840.87 fill=0.00` · `ground=831.72 planned=836.64 fill=4.92`),
|
||
`manifest.json.quantity_tables` 5측점(220·240·260·264·280) 각각 4/21 항목 채움
|
||
(나머지 17칸은 CAD 에서 사용자가 채우는 자리). 시험 확정은 전부 해제해 원상복구
|
||
(확정 남은 도면 `[]`). pytest 383 passed·17 skipped.
|
||
- 관찰(결함 아님) — 확정하면 설계 재계산으로 **장 나눔이 바뀜**(3장 220~264m → 220~280m).
|
||
확정 시점의 장 구성을 고정할지는 판단 대기.
|
||
- [X] **돌쌓기 해칭 — 경계로 잘라 싣기**(2026-09-03 사용자 결정). 수확기가 `g[clip-path]` 를
|
||
통째로 건너뛰어 형태 해칭이 CAD 에 하나도 안 실렸다. 선분–폴리곤 교차로 안쪽 조각만 남기고
|
||
클립 안 원은 36각으로 펴서 자른다.
|
||
- **화면 검증에서 2차 결함 발견·수정**(2026-09-03, 커밋 `0f5b4e4d` — 자동 폴백 커밋에
|
||
묶여 메시지가 `auto:` 로 남음). 클립 건너뛰기만 고쳤을 뿐 수확기 selector 가
|
||
`polygon, polyline, line, circle, text` 라 **`rect` 를 아예 안 봤다**. 돌쌓기 돌·돌망태
|
||
칸은 `cell()` 이 `rect` + `rotate(벽기울기)` 로 그리므로 주 표현이 통째로 빠졌다.
|
||
실측(용화 route 126 B06 화면) — 형태 해칭 80개 = `line` 31 + **`rect` 49**(61%),
|
||
264.06 카드는 `rect` 4(돌쌓기(메) 4켜) + `line` 1.
|
||
- 조치 — selector 에 `rect` 추가, `rectPoints()` 로 네 모서리 점열 변환(`rotate(각도 cx cy)`
|
||
적용, `rx` 무시). 회전을 빼면 기운 돌이 벽 폴리곤을 벗어나 클립에 전부 잘린다.
|
||
- 자체검증 — 3장(220~280m) CAD 구조물 엔티티 **14 → 22개**(돌 8 = 벽 2매 × 4켜).
|
||
돌 상자가 켜마다 가로 1mm 씩 밀려 벽 경사를 따름(`-30,-168,-25,-163` → `-34,-154,-29,-149`).
|
||
`tmp/tests/test_cad_rect_harvest.mjs` 4건, pytest 383 passed·17 skipped, typecheck 통과.
|
||
- [X] **장 선택 시 정보 패널 표기 정리**(2026-09-03). 장에는 측점 단위 값이 없는데 제목이
|
||
「측점 3장 (220~264m)」이었다 — 제목을 「장」으로 바꾸고 안내 문구를 넣었다. 판정은 도면
|
||
id(`cross_s…`)로 한다(`chainage_m` 은 장에도 첫 측점 값이 실려 옴).
|
||
|
||
### B08 토적도·유역도 후속
|
||
|
||
- [X] **토적도 축척 = 길이별 자동**(2026-09-03 사용자 결정). `auto_scale_h()` — 후보
|
||
1:500~1:6,000 중 A1 가용 폭 700mm 에 드는 가장 큰 그림. 실측 40m→1:500 · 용화 1,106m→
|
||
1:2,000 · 3,465m→1:5,000. 세로는 종이 1mm=50㎥ 고정.
|
||
- [x] **유역 정보표 측점 표기 통일**(2026-09-03, 커밋 `e29e3cab`) — 토적도와 같은 `n+ 0.0`
|
||
형식으로 맞춤. `station_plus_label()` 을 `_Engine_Cad` 로 공용 이관해 두 도면이 한 함수를 씀.
|
||
자체검증 — `tmp/tests/test_b07_masshaul_basin.py` 갱신·통과. **화면 실측 완료**(2026-09-03,
|
||
「S자유역검증」 `8879c53b` 유역도) — 정보표 48개 전부 `(1) 4+ 18.3` · `(2) 9+ 16.1` …
|
||
`(48) 221+ 9.9` 형식.
|
||
- [X] **납품 도면 표기 8행 전부 반영**(2026-09-03 사용자 결정) — 종무대 · `Q= ` 한 칸 · 계단형 지시선 · 평형선·경계현 빨강 · `120+ 0.0` · 표 눈금(정규 빨강·추가 회색) · 행 이름 3.2mm 자간 · `0+16.90`.
|
||
- 자체검증(2026-09-03, 「구조물검증-LAS」 `2f940d8a` 토적도 엔티티 실측) — **8행 중 6행 확인**:
|
||
`Q= 4491.46M3`(한 칸) · 계단형 지시선 `(301.9,-99.8)→(291.8,-99.8)→(291.8,0)`(수평 뒤 수직) ·
|
||
측점 `0+ 0.0`~`17+ 10.1` · 표 눈금 빨강 18 / 회색 5(회색 5 = 추가 측점 5개와 일치) ·
|
||
행 라벨 `누 가 토 량`·`측 점` 3.2mm 자간 · `M.N= 0+0.00`(소수 2자리).
|
||
축척은 `SCALE H=1:600 V=1:50,000` 로 자동 선택.
|
||
- **남은 2행은 사례 없음** — 종무대(장비 이름)와 평형선·경계현 빨강은 이 프로젝트에 운반
|
||
블록이 없어 도면에 그려지지 않음. 코드 상수는 `BALANCE_COLOR = BAND_CHORD_COLOR =
|
||
"#ff4d4d"` 로 확인. 아래 「운반 블록이 있는 실노선에서…」 항목에서 함께 볼 것.
|
||
|
||
| 항목 | 납품 도면 | 현재 |
|
||
| -------------- | -------------------- | --------------- |
|
||
| 장비 이름 | 종무대 | 무대 |
|
||
| 값 표기 | `Q= 162.41M3` | `Q=162.41M3` |
|
||
| 지시선 | 계단형·모서리 접점 | 직선·아래 중앙 |
|
||
| 평형선·경계현 | 빨강 | 흰색·노랑 |
|
||
| 측점 | `120+ 0.0` | `No.120` |
|
||
| 표 눈금 | 정규 빨강·추가 회색 | 없음 |
|
||
| 행 라벨 | 큰 글씨·자간 벌림 | 2.2mm 본문 크기 |
|
||
| M.N 소수 | `0+16.90` | `0+16.9` |
|
||
|
||
### B05 종단 계획선 개편 — 검증 후속 (2026-09-02 laptop-main 화면 검증에서 발견)
|
||
|
||
화면 검증 자체는 완료(실측 수치는 `docs/raw/plans/2026-09-02_plan_user_verified_completed_items_2.md`
|
||
「B05 종단 계획선 편집」). 아래 4건은 그 과정에서 나온 **미해결**이다.
|
||
|
||
완료된 최소고 가드와 구조물 위치 되돌리기는
|
||
`docs/raw/plans/2026-09-02_plan_B05_profile_edit_followup_completed.md`로 이동했다.
|
||
|
||
- 취소 — ~~규칙 측점은 선택이 안 돼 방향키 상하도 안 먹는다~~ **오검(2026-09-02 재확인)**.
|
||
`_Profile_Panel.selectStation` 은 같은 측점을 다시 누르면 선택을 푸는 토글이고,
|
||
앞선 검증이 240.000 을 두 번 눌러 해제된 상태에서 ArrowUp 을 보낸 것이었다.
|
||
한 번만 누르면 `b06-chart__station--selected` 가 붙고 ArrowUp 이 오프셋 0.1 을 만든다.
|
||
규칙 측점도 정상 — 코드 변경 없음.
|
||
|
||
- [X] **`shiftSegment`·`shiftMovingPoints` — 유지**(2026-09-03 사용자 결정). 정리하지 않음. 새 [쉬프트]는
|
||
`shiftStraightRuns` 를 쓴다. `_Profile_Alignment.ts` 두 함수의 파일 밖 참조 0건.
|
||
「기하 함수는 남김」 방침이라 유지 중 — 되쓸 계획이 없으면 정리 대상(사용자 확인 후).
|
||
|
||
- 참고 — **`/route/confirm`([저장])은 계획선을 재산출하지 않는다.** 저장 경로는
|
||
`_Router_Lifecycle.py` 가 기존 `longitudinal.json` 에 상단측 변경분만 합쳐 다시 쓴다.
|
||
새 초기 계획선을 보려면 **[경로 계산]**(`/route/solve`)이 필요하다 — 옛 프로젝트를 열어
|
||
기본이 안 바뀐 것처럼 보이는 것은 이 때문이고 결함이 아니다.
|
||
|
||
### B05/B06 구조물 3D 판단 대기
|
||
|
||
완료된 패치·마스크 수정은 `docs/raw/plans/2026-09-02_plan_user_verified_completed_items.md`로 이관했다. 2D 면적·유토곡선 산식은 분리 보류이므로 건드리지 않는다.
|
||
|
||
- [X] **BOX 날개 사이 — 현행(원지반) 유지**(2026-09-03 사용자 결정). 코드 변경 없음.
|
||
- [X] **세월교 좌측 접근선 — 패치로 덮음**(2026-09-03 사용자 결정). 접근선(노견 → 벽 상단)은
|
||
벽보다 위라 덮어도 관 구멍·L자 통로를 막지 않는다. 벽 전면·유로는 종전대로 리본에 담지
|
||
않는다. 접근선 줄을 `patchPoints` 앞에 담고 `fillRuns` 에 한 장으로 실어 「구간 1줄 = 리본
|
||
1장」 규칙을 지킨다.
|
||
- 자체검증(2026-09-03, 용화 route 126) — `fordSilhouettes()` 를 실제 세월교 2측점
|
||
(177.33m·358.92m)에 돌려 **첫 리본이 노견에서 시작**함을 확인: 우측 `(-2, 851.18)`
|
||
= `road_edges.right`, 좌측 `(2, 851.30)` = `road_edges.left`, 면마다 `fillRuns` 2장
|
||
(접근선 1 + 성토 1). 3D 픽셀 육안은 카메라를 그 측점으로 몰아야 해 미실시 —
|
||
리본 데이터로 판정함.
|
||
|
||
### B05/B06 700줄 제한 위반 정리
|
||
|
||
- [X] `B06_Section_UI_Section_View.ts` 751 → **689줄** — 유토곡선 조립을 `_MassHaul` 로 분리.
|
||
- [X] `B06_Section_UI_Cross_View.ts` 784 → **698줄** — 카드 제목·하단행을 `_Cross_Card_Chrome`,
|
||
실효 반폭 계산을 `_Cross_View_Metrics`, 줌 상태 맵을 `_Cross_View_Zoom` 으로.
|
||
- [X] `B05_Profile_UI_Profile_Panel.ts` — 현재 **699줄**로 제한 안(별도 작업 불필요).
|
||
- [X] `B05_Profile_UI_Structures_Panel.ts` 1,078 → **1,024줄** — 폼 뼈대를 `_Structures_Form`
|
||
으로 분리(1차).
|
||
- 자체검증 — 분리 3건의 **화면 실동작 확인**(2026-09-03, 용화 route 126):
|
||
B06 횡단 카드 65장 전부 header·footer 생성(`_Cross_Card_Chrome`), 유토곡선 패널 표시
|
||
(`.b06-masshaul`, `_Section_View_MassHaul`), B05 구조물 배치 폼 본문이
|
||
`grid → position-row → divider → grid(옵션) → 시설 서브폼 → 메모 → [추가][삭제][리셋]`
|
||
순서로 조립되고 목록 11건 표시(`_Structures_Form`).
|
||
|
||
### B04 세부유역 중첩·빈공간 — 현행 반영 여부 확인 (2026-09-03, 보조폴더)
|
||
|
||
사용자 지시: 로직은 그대로 두고, **S자 노선에서 아래 세부유역이 위 세부유역을 포함하는
|
||
경우를 현행이 반영하는지 확인만** 할 것.
|
||
|
||
- [X] **확인 결과 — 셀 단계는 반영, 내보내기 단계에서 소실**.
|
||
`assemble_basins`(`common_util/common_util_drainage_detail.py:508`)의 라벨 격자는
|
||
셀마다 관 하나만 배정하므로 포함 관계(도넛)가 정확히 살아 있고,
|
||
`polygonize_labels`(`B04_PreProcess/B04_PreProcess_Engine_Watershed_Flow.py:526`)도
|
||
구멍을 가진 폴리곤을 낸다. 그러나 `largest_ring:563`이 **외곽 링 하나만** 뽑고
|
||
`WatershedBasin.boundary_xy`(`:107`)·API `polygon_lonlat`
|
||
(`B04_PreProcess_Router_Basins.py:164,195`)가 **단일 링 자료형**이라 구멍·조각이
|
||
실릴 자리 자체가 없음. 즉 화면에서는 아래 유역이 위 유역을 통째로 덮음.
|
||
**검증**(`tmp/tests/test_basin_boundary_holes.py`, 1m 격자 합성 사례 3건, 3 passed):
|
||
① 도넛 — 갇힌 위 유역 256㎡ 전체가 아래 유역 링에 중첩
|
||
② 조각 — 한 관 유역이 두 조각(225㎡+144㎡)이면 작은 144㎡ 소실 = 빈공간
|
||
③ 유역별 독립 simplify(2.0m) — 들쭉날쭉한 공유 경계에서 중첩 18.2㎡ · 틈 35.2㎡
|
||
(전체 6400㎡ 대비 0.8%). 규칙적 계단 경계에서는 재현 안 됨(양쪽이 같게 단순화).
|
||
- [X] **후속 완료(2026-09-03)**: 자료형을 링 목록으로 넓힘.
|
||
`polygon_parts()` 신설(조각마다 [외곽, 구멍...], 넓은 조각 먼저) ·
|
||
`WatershedBasin.boundary_parts` 로 교체하고 `boundary_xy`(가장 넓은 조각의 외곽) ·
|
||
`boundary_rings`(편 링 목록)는 파생 속성으로 남겨 옛 소비처 무손상 ·
|
||
API 에 `polygon_rings_lonlat` 추가 · 저장 GeoJSON 은 구멍을 가진 Polygon, 조각이
|
||
여럿이면 MultiPolygon · 캔버스 3곳(B04 유역화면 채움·선택, B05 배수유역도 채움·선택)은
|
||
even-odd 로 한 번에 채우고 `pointInRings()` 로 판정(구멍 안을 눌러도 바깥 유역이
|
||
잡히지 않음). 중복이던 지역 `pointInRing` 은 삭제하고 공용 것으로 통일.
|
||
**검증**: 단위 5건 신규(`tmp/tests/test_basin_boundary_rings.py` — 도넛 구멍 보존,
|
||
조각 2개 보존, 파생 속성, 빈 경계, **조립 경로 전체에서 유역 하나가 링 2개**),
|
||
전체 168 passed. 브라우저 — API 가 22개 유역에 링 목록을 실어 보냄(경계 없는 1개 제외),
|
||
캔버스 even-odd 실측(가운데 알파 0 / 고리 255, nonzero 는 255)로 구멍이 실제로 뚫림.
|
||
1차 전체 배수유역(분수령)은 `largest_ring` 그대로 — 외곽선 한 줄이 맞는 자리.
|
||
- [X] **S자 노선 실사례 검증(2026-09-03, 사용자 지시)**: 용화 지형 위에 스위치백 3구간
|
||
합성 노선(CSV, 정점 439·연장 4,528m)을 만들어 신규 프로젝트로 자동 체인까지 완주.
|
||
결과 관 48개·세부유역 48개. 도넛은 1건 나왔으나 1㎡짜리 simplify 부스러기였고,
|
||
**진짜 빈공간의 원인은 최소면적 필터**로 드러남 — 100㎡ 미만 유역은 폴리곤이 아예
|
||
안 만들어져 화면에서 통째로 사라졌음(용화 22개 중 1개, S자 48개 중 1개).
|
||
- [X] **최소면적 필터 제거(세부유역 한정)**: `assemble_basins` 가
|
||
`polygonize_labels(..., min_area_m2=0.0)` 로 부름. 실측 면적 오차 용화 5.76%→1.86%,
|
||
S자 3.56%→1.42%, 경계 없는 유역 1개→0개, 좌표점은 583→622·806→829 로 거의 그대로.
|
||
1차 전체 배수유역·다른 호출부의 기본값(100㎡)은 손대지 않음. 전체 168 passed.
|
||
- [X] **단순화 허용오차 2.0m → 1.0m** (2026-09-03 사용자 결정, 메인 창 경유).
|
||
격자가 1m(`DRAINAGE_GRID_SIZE_M`)라 경계가 1m 계단이므로 허용오차를 격자 한 칸에
|
||
맞춤 — 형상 손실이 격자 오차 안으로 들어감. 「공유 경계를 함께 단순화」(라벨 경계를
|
||
선분 그래프로 한 번만 단순화)는 작업량 대비 우선순위가 밀려 이번엔 채택 안 함.
|
||
**실측**(min_area=0 상태에서 비교):
|
||
|
||
| 허용오차 | 좌표점(용화/S자) | 면적오차(용화/S자) | 유역끼리 중첩(용화/S자) | 틈(용화/S자) |
|
||
| -------------------- | ----------------------- | ----------------------- | ----------------------- | ----------------------- |
|
||
| 2.0m(옛) | 622 / 829 | 1.86% / 1.42% | 1,043㎡ / 1,373㎡ | 1,184㎡ / 2,579㎡ |
|
||
| **1.0m(채택)** | **1,749 / 1,987** | **1.01% / 0.67%** | **243㎡ / 373㎡** | **369㎡ / 668㎡** |
|
||
| 0.5m | 10,215 / 12,294 | 0.00% / 0.00% | 148㎡ / 129㎡ | 296㎡ / 259㎡ |
|
||
| 0.0m | 12,403 / 14,558 | 0.00% | 0㎡ | 0㎡ |
|
||
|
||
0.5m 이하는 1m 계단 점을 못 지워 좌표점만 6배로 튐. 브라우저 실측도 같은 값
|
||
(API 좌표점 용화 1,750 · S자 1,987, 경계 없는 유역 0개), 확대해도 계단이 도드라지지
|
||
않음. 테스트 159 passed(B07 항목 아래 별도 기록한 1건 제외).
|
||
- [X] **병합 뒤 깨진 로컬 테스트 복구**(2026-09-03): `tmp/tests/test_b07_masshaul_basin.py`
|
||
가 사라진 `MM_H` 를 import 해 수집 단계에서 전체 실행이 막혔음. 메인 창이 알려 준
|
||
대로 고침 — `auto_scale_h()` 로 축척을 얻고(시험 노선 40m → 1:500, `MM_H = 1000/500`),
|
||
표기 6곳을 현행으로(`종무대`·`Q= 600.00M3`·`L= 18.50M`·`EA= 400.00M3`·
|
||
`M.N= 1+10.00`·`SCALE H=1:500 V=1:50,000`). 축척 규칙을 굳히는 시험도 추가
|
||
(40m→500 · 1,106m→2,000 · 3,465m→5,000 · 길이 0이면 설정 기본값 2,000).
|
||
`tmp/tests` 는 git 밖이라 커밋 없음. 전체 **169 passed**.
|
||
|
||
### B03 계획노선 shapefile — 변환 CSV 정본화 (2026-09-03, 보조폴더)
|
||
|
||
사용자 확답: 프론트엔드는 **올린 파일 그대로 표시**, 백엔드는 **CSV 로 변환해 사용**하고
|
||
그 CSV 를 **초기값(`initial_snapshot/`) 정본**으로 남김. 좌표는 **사업지 좌표계 +
|
||
트림·조밀화 후**(2026-09-03 사용자 확정).
|
||
|
||
현행 조사 결과 — 이미 되어 있는 것(작업 불필요):
|
||
슬롯 라벨 `계획노선 도형`(CSV 표기 아님) · `.csv`/`.shp` 동시 수용 · shx/dbf/cpg/route_prj
|
||
슬롯 · shp 판독기(`B03_FileInput_Engine_Shapefile.py`) · shp 우선 선택
|
||
(`find_planned_route_file`) · 좌표계 변환·트림·조밀화 단일 창구
|
||
(`common_util_route_geometry.py:215 load_design_route`).
|
||
|
||
- [X] 초기값 CSV 기록 — `common_util_initial_snapshot.py` 에
|
||
`planned_route.csv`(sequence,x,y) 를 `save_initial_snapshot()` 이 함께 씀.
|
||
값은 체인 2단계가 이미 만든 `points`(사업지 좌표계·트림·조밀화 후)를 그대로 받음 —
|
||
재계산·서피스 샘플러 재구축 없음.
|
||
- [X] 체인 연결 — `B03_FileInput_Service_Chain.py` 스냅샷 블록이 `points` 를 넘김.
|
||
- [X] 정본 사용 — `load_design_route()` 는 **surface_params 가 주어진 호출에 한해**
|
||
초기값 CSV 가 있으면 그것을 읽고 반환(재판독·재투영·트림 생략).
|
||
`surface_params=None` 호출(도엽 범위 산출 `B04_PreProcess_Engine_SheetSurface.py:492`)은
|
||
트림 전 원본이 필요하므로 종전 경로 유지.
|
||
- [X] 무효화 규약 확인 — 지표면·노선이 바뀌면 `discard_initial_snapshot()` 이 폴더째
|
||
지우므로 CSV 도 함께 사라져 자동으로 shp 재판독 경로로 되돌아감.
|
||
- [X] **자체검증 완료** (2026-09-03, 보조폴더 8001·5174)
|
||
① 단위 4건 `tmp/tests/test_design_route_csv_master.py` — CSV 왕복 좌표 일치,
|
||
정본 우선, 트림 전 호출은 정본 미사용, 스냅샷 폐기 시 경로 닫힘. 전체 158 passed.
|
||
② 실사용 경로 — 공용 브라우저에서 프로젝트 신규 등록 → 용화 예정노선 shapefile
|
||
5개 + 지형 PRJ·TFW 업로드 → [LAS 없이 설계] 체크 → 업로드 → 자동 체인 완료.
|
||
`initial_snapshot/planned_route.csv` 생성됨(643행). 정본 경로와 원본 shp 경로를
|
||
맞대 보니 **정점 643개 동일, 최대 좌표차 0.00007m, 연장 2136.2m 동일**.
|
||
B05 화면에 종단 계획선·배수유역도(관 22개·세부유역 22개)가 정상 표시.
|
||
③ 프론트 표시 — 슬롯 카드가 올린 파일명을 그대로 보임(`대상지_일월.용화.2.2.shp`
|
||
외 4개), 라벨은 `계획노선 도형`.
|
||
|
||
### LAS 없는 설계 — 도엽 서피스가 노선 원본 좌표계로 만들어지던 문제 (2026-09-03, 보조폴더)
|
||
|
||
**증상**: shapefile 노선(EPSG:5179) + 지형 PRJ(EPSG:5176)로 [LAS 없이 설계]를 돌리면
|
||
자동 체인이 `노선 트림: 노선 전체가 지표면 밖입니다` 로 중단됨 — 실측 재현.
|
||
|
||
**원인**: `B04_PreProcess_Engine_SheetSurface.py:503 run_sheet_surface_analysis` 만
|
||
`read_planned_route()` 로 노선을 **원본 좌표 그대로** 읽어 도엽 서피스를 5179 자리에 만들고
|
||
(실측: 서피스 x 1,141,951~1,143,784), 설계 계통 `load_design_route()` 는 노선을 사업지
|
||
좌표계 5176(x 208,402~209,637)으로 옮기므로 두 자리가 어긋나 트림이 노선을 통째로 지움.
|
||
같은 파일의 `build_sheet_surface_from_route()` 는 이미 `load_design_route()` 를 쓰고 있어
|
||
LAS 경로에서는 나지 않던 문제.
|
||
|
||
- [X] `run_sheet_surface_analysis()` 도 `load_design_route()` 로 읽도록 창구 통일,
|
||
좌표계는 `planned.crs_input or project_epsg_from_prj()` 를 그대로 사용
|
||
(EPSG 라벨 대신 PRJ 원문 WKT 가 실려 TOWGS84 보정이 보존됨).
|
||
- [X] 도엽 확보(`download_geodata`)의 PRJ 탐색 폴더를 노선 세트(`input/shp/`)에서
|
||
지형 PRJ 폴더(`input/prj/`)로 교정 — 노선 PRJ 가 잡히던 자리.
|
||
- [X] **검증**: 수정 후 같은 자료로 재실행 → 체인 완주(노선 643점·2136.2m, 관 22개,
|
||
세부유역 22개). 전체 테스트 158 passed.
|
||
|
||
### B03 [파일 업로드] 가 잠긴 채 남던 문제 (2026-09-03, 보조폴더)
|
||
|
||
**증상**: 필수 파일을 다 골랐는데도 [파일 업로드] 가 비활성. 새로고침하거나 파일을 하나 더
|
||
고르면 풀림.
|
||
|
||
**원인**(첫 추정 정정): 프로젝트 ID 캐시가 아니었음 — 파일 선택 경로가
|
||
`detectPausedUploads()` 에서 ID를 다시 읽어 스스로 풀림. 진짜 자리는 **[LAS 없이 설계]
|
||
토글**. 이 토글이 LAS 카드의 필수 여부를 바꾸는데(`isSlotRequired`), change 핸들러가
|
||
`updateUploadButton()` 을 부르지 않아 버튼 판정이 옛 상태로 남음. **파일을 먼저 고르고
|
||
토글을 나중에 켜는 순서**에서만 재현돼 처음엔 ID 문제로 보였음.
|
||
|
||
- [X] `lasFreeCheck` change 핸들러에 `updateUploadButton()` 추가 (4줄).
|
||
- [X] **검증**(공용 브라우저, 저장된 토글 표시를 지워 첫 진입 상태로 재현):
|
||
① 파일 7개만 고른 상태 → 비활성 + "필수 카드를 모두 채우세요 … LAS/LAZ …"
|
||
② [LAS 없이 설계] 켠 직후 → **즉시 활성**, 오류 문구 사라짐
|
||
③ 다시 끄면 → 즉시 비활성 + 같은 안내. typecheck 통과.
|
||
|
||
### B04 세부 배수유역 — 종단 높낮이 흐름 반영 (2026-09-03, 보조폴더)
|
||
|
||
사용자 재정의(2026-09-03): "세밀유역" 표현은 접고, **배수유역 = 횡단배수 지점으로 들어오는
|
||
유역**. 빠진 것은 **종단 계획노선의 높낮이에 따른 흐름** — 용화에서 낮은 도로측 유역이
|
||
높은 쪽으로 흐르는 것처럼 표현됨.
|
||
|
||
**진단(용화 실측, 프로젝트 `shp정본검증2`)**: `assign_road_cells_to_pipes` 의 내리막 추적이
|
||
한 칸 이웃만 보는 국소 하강이라 1m 간격 계획고의 미세 요철에 걸려 멈춤 — 측점 2,138개 중
|
||
**1,898개(88.8%)가 저점에 갇힘**. 갇힌 측점은 흐름이 아니라 **누가거리 최근접**으로 관에
|
||
붙어, 도로 셀 11,312개 중 **4,886개(43.2%)가 자기보다 높은 관에 배정**(최대 6.82m).
|
||
추적이 성사된 측점의 오르막은 0.8%(최대 0.09m)라 추적식 자체는 정상.
|
||
|
||
- [X] 배정 규칙 교체 — **관 사이 마루(구간 최고점)가 분수령**. 1차원에서 물은 마루를 넘지
|
||
못하므로 마루 왼쪽은 앞 관, 오른쪽은 뒤 관, 첫 관 앞·마지막 관 뒤는 그 관이 받음.
|
||
미세 요철에 면역 (사용자 확정).
|
||
- [X] 관 없는 저점 126개는 **그대로 둠** (사용자 확정) — 대부분 계획고 미세 요철이지
|
||
진짜 사그가 아니고, 마루 분할이 자동으로 무시함.
|
||
- [X] **자체검증** ① 단위 5건 `tmp/tests/test_ditch_ridge_assignment.py` — 마루가 경계,
|
||
±3cm 톱니에도 배정 불변, 사그는 낮은 쪽으로, 첫·끝 구간, 관 순서 보존. 전체 163 passed.
|
||
② 실측 재계산: 오르막 배정 **43.2% → 17.6%**, 최대 상승 6.82m → 4.15m.
|
||
③ 잔여 1,993셀은 전부 **사그에 고였다가 더 낮은 장벽(=배정된 관) 쪽으로 넘치는**
|
||
경우임을 확인(어긋남 0개) — 물리적으로 옳은 배정이라 남겨 둠.
|
||
④ 화면: B05 배수유역도 [유역 다시 나누기] 후 유역 면적이 실제로 바뀜
|
||
(관1 1.35ha → 1.07ha, 관3 2,545㎡ → 3,661㎡, 관4 23.34ha 세월교 제안).
|
||
|
||
### B04 지표면 3D 뷰어 방위 콤파스 (2026-09-03, 보조폴더)
|
||
|
||
사용자 확인: 대상은 **B04 지표면 3D 뷰어** (B03 에는 3D 화면이 없음).
|
||
|
||
- [X] `B04_PreProcess_UI_Compass.ts` 신설 — 카메라 오프셋으로 도북 각도를 내는 작은 모듈.
|
||
뷰어 좌표 규약이 `x, 높이, -y` 라 세계 북쪽은 `-z`, 화면 회전각은
|
||
`atan2(offset.x, offset.z)`. 뷰어 파일이 이미 946줄이라 별도 파일로 뺌(700줄 제한).
|
||
- [X] `B04_PreProcess_UI_TerrainViewer.ts` 배선 3줄 — 뷰어 우하단(축척 막대 반대편)에 얹고
|
||
애니메이션 루프에서 각도 갱신(0.5° 미만 변화는 건너뜀). 지표면이 보일 때만 표시.
|
||
- [X] CSS — `.b04-surface__compass*` (테마 토큰 사용, 라이트·다크 공용).
|
||
- [X] **자체검증**: `npm run typecheck` 통과. 공용 브라우저에서 ① [상단] 시점 회전각
|
||
`matrix(1,0,0,1,0,0)` = 0° (바늘이 화면 위 = 북쪽, 북쪽 위인 2D 지도와 같은 방향)
|
||
② 캔버스를 220px 드래그하니 `matrix(-0.78152,-0.62388,…)` = 218.6° 로 카메라와 함께
|
||
회전 ③ 상단·하단 두 3D 뷰어 각각에 하나씩(총 2개) 표시. 검증 후 시점은 기본(사시도)
|
||
으로 되돌려 둠.
|
||
|
||
### 프로젝트 작업 좌표계 일원화 (2026-08-31 신규)
|
||
|
||
- [X] **작업 좌표계 = 지형 PRJ 로 확정**(2026-09-03 사용자 결정 — 서피스 격자가 모델좌표의
|
||
주인이라 현행 유지). 「노선 .prj 우선」은 노선 UTM-K / 지형 동부원점 Bessel 로 실제 좌표계가
|
||
달라 서피스·격자를 통째로 재투영해야 해 폐기.
|
||
- [X] **폴백 사다리를 창구 하나로 통합** — `common_util_crs.resolve_project_crs()` 신설.
|
||
① 노선 crs_input ② 파일 라벨(원본 좌표를 읽는 자리만) ③ 지형 PRJ ④ DB epsg ⑤ EPSG:5186.
|
||
`_route_center_lonlat` 이 CSV 라벨을 그대로 변환에 쓰던 자리를 이 사다리로 교체.
|
||
`tmp/tests/test_project_crs_resolution.py` 5건 신설.
|
||
- [X] **트림 실패 진단** — 지표면 트림이 노선을 통째로 지우면 노선·지표면 bbox 를 함께 로그에
|
||
남긴다(겹침 0이면 좌표계, 일부 겹치면 측량 범위 문제).
|
||
- [ ] ~~`planned.epsg or 5186` 폴백이 여섯 군데 흩어져 있다~~ (완료 — 위 항목):
|
||
`B04_PreProcess_Engine_SheetSurface.py:467·496`, `B04_PreProcess_Router_Watershed.py:186·253`,
|
||
`B04_PreProcess_Router_Inflow.py:84`, `common_util_drainage_context.py:98`.
|
||
`B04_PreProcess_Engine_Extent.py:147-152`, `B04_PreProcess_Engine_GisVector.py:148`도 5186 기본값.
|