Files
Aislo/docs/raw/plans/2026-09-04_plan_user_verified_completed_items.md
T
eomsangdonandClaude Opus 5 eb30b774f8 chore(docs): docs 폴더 git 추적 전환 · PLAN·OWNERS 최상위 이관
- `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>
2026-09-09 18:19:07 +09:00

82 KiB
Raw Blame History

2026-09-04 사용자 검증 완료 항목

docs/raw/PLAN.md에서 2026-09-04에 사용자 검증 완료로 확정된 구간을 이관했다. B05 초기화 범위 확대 — 전체 결과 보존 (2026-09-04 지시)는 미완료·판단 대기 항목이 있어 제외했다. 위키 반영: docs/wiki/concepts/completed_2026-09-04.md

계획노선 표기 정리 — CSV 문구 걷어내기 (2026-09-04 구현 완료 · 검증 대기)

사용자 지시(2026-09-04) — 「사용자는 CSV 를 쓰지 않음. 내부 코드 주석에 그런 내용이 있으면 삭제」.

  • 실제 사용자 입력은 shapefile 이고, CSV 는 내부 정본 한 벌(planned_route.csv)로만 씀.

  • 「B03 이 업로드한 원청 계획노선 CSV」식 주석이 여러 곳에 남아 입력 형식을 오해하게 함.

  • 주석 문구 정리 — 사용자 입력을 CSV 로 적은 주석을 「계획노선(정본)」으로 고침. 고친 곳은 common_util_drainage_context.py · common_util_drainage_pipes.py · B05_Profile_Engine_Sections.py · B03_FileInput_Service_Chain.py · B04_PreProcess_Api_Fetch.ts. 내부 정본 파일(planned_route.csv)을 가리키는 자리는 그대로 둠.

  • 화면 문구 확인 — 업로드 오류 문구를 「계획노선 파일(shapefile 의 .shp 또는 .csv)을 정확히 1개 포함해야 합니다」로 고침. 그 자리 판정이 .csv 개수만 세고 있어 shapefile 입력을 막던 것도 같이 맞춤(.csv·.shp 합쳐 1개 — 이미 다른 경로가 쓰던 규칙 _ROUTE_FILE_TYPES 와 같음). B03 안내 문구는 「계획노선(shapefile 한 벌 또는 CSV)」 순으로 바꿔 shapefile 이 기본임을 보임.

  • 동작은 불변 — 파일 형식·경로 그대로. 예외는 위 업로드 판정 한 줄(문구와 어긋나 있던 것).

  • 자체검증 (2026-09-04, 검증 대기) — 방법: ruff format + npm run typecheck 통과 확인, 문구를 바꾼 자리에 남은 「업로드한 … CSV」 표현이 없는지 재검색. 결과: 남은 CSV 표현은 모두 내부 정본 파일(planned_route.csv)·CSV 판독기 자체를 가리키는 자리뿐임. 계획 대비 차이 — 업로드 판정 한 줄이 문구와 어긋나 있어 문구만이 아니라 판정도 함께 고침.

B05 진입 로딩 — 3D 후순위·회전 끊김 (2026-09-04 지시)

사용자 지시(2026-09-04) — 「3D 데이터는 보조 역할이라 초기화든 데이터 변경이든 후순위임. 그래서 [3D 업데이트] 버튼을 둔 것. 초기 로딩도 혼자 버벅이지 말고 조용히 뒤에서 뜨고 다 되면 팝업으로 알릴 것. 로딩 도넛이 툭툭 끊기니 회전은 진행률과 무관하게 계속 돌고 숫자만 갱신할 것. 완료 시점은 맨 마지막 3D 데이터 직전」.

착수 전 코드를 읽고 낸 현황임.

  • 도넛이 안 도는 게 맞음 — 진행률을 주면(set(비율)) 회전 클래스(is-indeterminate)가 꺼짐(ui_template_progress.ts). 즉 지금 보이는 움직임은 회전이 아니라 호가 5칸씩 뚝뚝 늘어나는 것임. 회전과 진행률이 같은 <svg> 의 transform 을 서로 뺏는 구조라 둘을 동시에 못 씀.

  • 끊김을 키우는 것은 무거운 단계 — 3D 지형·코리도가 메인 스레드를 잡는 동안 갱신 자체가 멈춤.

  • 로딩 5단계(B05_Profile_UI_Page.ts) — ① 워크플로우 ② 좌측 폼·노선 ③ 지표면 모델 ④ 종·횡단 자료 ⑤ 3D 지형. 완료(progress.remove())는 ⑤ 까지 끝난 뒤라 3D 를 기다리는 동안 화면이 잡혀 있음.

  • [3D 업데이트] 버튼은 이미 있음(2026-09-01) — 계획선 편집은 이 버튼으로 모아 반영 중. 같은 규칙을 초기화·진입에도 적용하면 됨.

  • 회전과 진행률 분리 — 서클 안에 회전 껍데기(__spin)를 한 겹 더 두고 CSS 회전을 거기에만 걸었음. 껍데기는 늘 돌고 안쪽 <svg> 는 12시 고정이라 호·숫자는 제자리에서 갱신됨. 쓰이지 않게 된 is-indeterminate 분기는 지움(공용 ui_template_progress).

  • 완료 시점을 3D 직전으로 — 단계 수를 5 → 4 로 줄이고 ④ 끝에서 로딩 표시를 걷음. 「확정 지표면 없음」 판정은 ③ 뒤로 앞당겨 빈 화면을 열지 않게 함.

  • 3D 는 뒤에서 조용히 — ⑤ 를 finally 뒤 배경 작업으로 돌리고 끝나면 토스트 「3D 지형 준비 완료」. 실패해도 화면은 그대로 쓰고 오류 토스트만 띄움.

  • 초기화·데이터 변경도 같은 규칙 — [초기화]는 끝에 B05 로 재진입하므로 위 진입 규칙이 그대로 걸림(추가 코드 없음). 계획선 편집은 이미 [3D 업데이트] 대기 표시로 모아 둔 상태.

  • 자체검증 — 공용 브라우저(5173, 용화_LAS) 실측. 진입은 캐시를 비우고 프로젝트 목록에서 [종단설계] 를 눌러 들어감.

    • ① 회전 — 껍데기의 CSS 애니메이션이 running 이고 시각이 계속 진행(0 → 183ms). 표본 6개의 변환행렬이 전부 다름(멈춘 구간 없음). 회전은 합성 스레드가 돌리므로 무거운 단계가 메인 스레드를 잡아도 끊기지 않음.
    • ② 숫자 — 25% → 50% → 75% 순으로 오름(문구도 단계마다 바뀜).
    • ③ 로딩이 걷힌 순간 종단 그래프 선 2개·좌측 패널 단추 61개가 이미 서 있고 3D 메쉬는 2개뿐 — 3D 없이 화면이 먼저 열림을 수치로 확인.
    • ④ 1.8초 뒤 3D 메쉬 489개와 함께 토스트 「3D 지형 준비 완료」.
    • ⑤ [초기화] → 확인 모달 → 토스트 「초기 계산 상태로 되돌렸습니다.」 뒤 재진입. 로딩 걷힘(그래프선 2·좌측단추 61) → 0.2초 뒤 3D 메쉬 489 + 준비 완료 토스트.
    • 계획 대비 차이 — 없음.

B05 초기화 후 계획선이 원지반과 어긋남 — 원인 확정 (2026-09-04)

사용자 보고(2026-09-04) — 「초기화 후에도 계획선이 측점 세로선에서 원지반선과 만나지 않음」. 공용 브라우저(5173, 2025 테스트)로 재현 성공, 원인 확정함.

  • 저장 데이터·서버는 정상 — 종단 정본의 측점 65개 전부 계획고 = 지반고(0.000m). 깨끗한 화면 실측도 측점 66개 최대 0.019m 로 붙어 있음.

  • 범인은 브라우저 세션에 남는 계획선 편집 초안(b05-profile-alignment-draft:<노선번호>). 초기화가 이 초안을 지우지 않아, 화면이 초기값 위에 옛 편집 델타를 다시 얹음.

  • 재현 기록 — 초안(측점 20~400m 에 +6m)을 넣고 새로고침하면 최대 6.0m 어긋남(측점 25개가 10cm 초과). [초기화] 직후에는 0.019m 로 멀쩡해 보이나 새로고침 한 번에 6.0m 로 되돌아감. 초안을 지우고 새로고침하면 0.019m 로 복귀 — 초안이 원인임이 확정됨.

  • 새는 구멍은 노선번호 없는 초안 키(...draft:none). 노선번호가 아직 없는 순간에 만들어진 초안이 어느 노선에나 되붙어, 초기화로 노선이 바뀌어도 살아남음.

  • 초기화가 계획선 초안을 함께 버림resetDesignAction 이 다른 세션 캐시를 비우는 자리에서 b05-profile-alignment-draft: 로 시작하는 키를 전부 지움.

  • 노선번호 없는 초안을 만들지 않음 — 노선번호가 없을 때는 초안을 저장하지 않음 (:none 키 폐지). B06 이 읽는 자리도 같은 규칙.

  • 자체검증(2026-09-04, 공용 브라우저 5174 · 프로젝트 용화_LAS, 사용자 지정) — 실측.

    • ① 초안 심기 — b05-profile-alignment-draft:137 에 20~400m 측점 +6m 를 넣고 새로고침하니 계획선이 지반선에서 최대 9.183m 뜸(깨끗한 상태 3.798m). 재현 성공.
    • ② [초기화] → 확인 모달 → 재계산 뒤 3.798m, 새로고침 후에도 3.798m 로 동일. 옛 편집 델타가 다시 얹히지 않음. 합격
    • ③ 초기화 직후 세션의 초안 키 0건, 새로고침 뒤에도 0건. 합격
    • ④ 정상 편집은 그대로 — 계획고 ▲ 를 누르니 계획선이 움직이고 초안 키가 다시 생김 (…draft:137). 검증 뒤 그 초안은 지워 시험 전 상태로 되돌림. 합격
    • 계획 대비 차이 — 판정 기준을 바꿈. 원안의 「측점 차이 0.02m 이하」는 초기값이 계획고=지반고인 평탄 시험노선 기준이었음. 용화_LAS 는 실제 자동설계라 절·성토가 있어 계획선이 지반선과 붙지 않는 것이 정상 — 그래서 「초기화 직후 값 = 새로고침 후 값 = 초기 자동설계값」 동일성으로 판정함.
    • 부수 영향 — 검증에 실제 [초기화]를 눌렀으므로 용화_LAS 의 사용자 수정분(경로·계획선· 횡단 설계)은 초기 자동계산 상태로 되돌아갔음.

B05 확정 시 구조물 측점 재생성 — 정리 (2026-09-04)

확정([저장]·[확정])이 종단 파일의 구조물·관 측점 10개를 다시 만들어 덮음. 2026-09-04 사용자 판단 — 포장 판정이 빠지는 것은 맞음(포장은 사용자 지정으로 바꿀 것), 측점 위치 소수 2자리도 유지(다른 설계자 관행과 같음). 남은 것은 아래 하나.

  • 포장 지정을 사용자 몫으로 — 확인 결과 이미 그렇게 되어 있음(2026-08-28 작업분). 코드를 고칠 것이 없었음.
    • 자동 판정은 켜지 않고 표기만 — pavement_suggested 는 B06 카드에 ⚠ 배지·툴팁으로만 나감.
    • 포장을 켜는 것은 ① 사용자 구간 지정(구조물 정본 G군·물넘이포장) ② 사용자가 카드에서 켠 값. 구간 밖에서는 저장된 사용자 값이 정본(paved_at).
    • 확정 시 구조물 측점을 다시 만드는 자리도 사용자 포장값을 그대로 이어받음 (B05_Profile_Router_Confirmpaved=bool(design.get("paved", False))).
    • 자체검증tmp/tests/test_b06_pavement_and_ford.py 가 이미 규칙을 못박고 있음 (구간 안 강제 True / 구간 밖 사용자값 유지 / 경사 제안만으로는 안 켜짐). 전체 185 통과.

B05 3D — 구조물 개별 선택 (2026-09-04 예정)

사용자 지시(2026-09-04) — 「B06 횡단도의 선택 로직을 공유하면 쉽게 될 것. 그러면 연계된 B05·B06 좌측 패널 활성화도 따라감」. 2026-09-04 확정 두 가지 — ① 고른 구조물 정보는 좌측 「구조물 배치」 패널로만 보임(3D 위 정보상자는 안 만듦) ② B06 은 선택만 세션에 남김 — 3D에서 골라도 화면이 넘어가지 않고, 나중에 B06 에 들어가면 그 측점 카드가 열림.

착수 전 코드를 읽고 낸 현황임.

  • 3D 구조물은 이미 부재마다 별개 물체 — 기슭막이(유입·유출·다단)·집수정·배관이 각각 자기 Mesh 로 얹힘(B05_Profile_UI_Corridor_Mesh.tscorridor-structure:종류:번호). 통짜로 뭉쳐 있지 않으므로 개별 선택에 기하 변경이 필요 없음.

  • 모자란 것은 신원표 — 솔리드 데이터(CorridorStructure)에 chainage_m·kind 는 있으나 부재키가 없음. 부재키는 B06 이 쓰는 것과 같은 이름(inlet·outlet·extra{i}·bextra{i}·집수정·배관)이고, 솔리드를 만드는 자리에서 이미 손에 쥐고 있음(B05_Profile_UI_Corridor_Structures.tswall.role·extra${i}).

  • 클릭 감지 범위 — 3D 포인터는 지형과 마커까지만 봄(B05_Profile_UI_Viewer_Marker_Input.ts). 코리도 그룹을 같은 방식으로 한 겹 더 보면 됨.

  • 좌측 패널은 받을 준비가 되어 있음 — 공용 「구조물 배치」(A00_Common/b_structures_sectionB05_Profile_UI_Structures_Panel.ts)에 selectPipeByChainage(누가거리)selectById(구조물id) 가 있고, 후자의 설명이 「종단도·3D에서 고른 구조물을 폼에 올린다」임.

  • B06 선택 규칙 = (측점, 부재키)B06_Section_UI_Page_Station_Controls.tsrevetSelection = { at: 측점.toFixed(2), key }. 이 한 쌍이 카드 강조·조정창·좌측 폼 로드를 모두 몰고 감. 3D 도 같은 한 쌍을 만들면 그 뒤가 전부 따라옴.

  • B05·B06 은 라우터가 따로 띄우는 화면(A00_Common/router.ts) — 두 화면이 동시에 떠 있지 않으므로 실시간 양방향이 아니라 세션에 남긴 선택으로 이음.

  • 부재키를 3D까지 들고 감CorridorStructurekey 필드 추가, 벽·다단·집수정·배관을 담는 자리에서 그대로 채움(값은 이미 그 자리에 있음).

  • 메쉬에 신원표 — 구조물 Mesh 에 userData = { chainageM, kind, key }. 이름 규칙은 그대로 둠(다른 코드가 이름으로 찾음).

  • 3D 클릭 잡기 — 신규 모듈 B05_Profile_UI_Viewer_Structure_Pick.ts(새 파일 — 뷰어 693줄·페이지 691줄이라 기존 파일에 넣지 않음). 코리도 그룹만 대상으로 하고 마커보다 뒤 순위 — 마커 끌기·이동 모드가 살아 있으면 구조물 선택은 건너뜀.

  • 3D 강조 — 고른 메쉬만 밝히고(emissive) 나머지는 원색, 빈 곳을 누르면 해제. 좌측 패널·종단 그래프에서 고른 경우에도 같은 함수로 3D 가 따라감.

  • 좌측 패널 활성화 — 배수관 세트(기슭막이·집수정·배관)는 selectPipeByChainage(누가거리), 그 밖의 구조물은 selectById. 배선 자리는 기존 선택 동기화(B05_Profile_UI_Selection.ts) — 3D 마커·종단·좌측·유역도가 이미 한 줄로 묶여 있으므로 구조물 선택을 같은 줄에 얹음.

  • 선택을 세션에 남김 — B06 이 쓰는 것과 같은 모양 { at, key } 를 sessionStorage 한 칸에 둠. B06 진입 시 그 값으로 카드 선택·스크롤·조정창 열기(기존 select() 창구 재사용). 조작 상태는 캐시 몫이라는 5장 데이터 3층 규칙과 같음.

  • 자체검증 — 공용 브라우저(5173) 실측으로 수치 판정. ① 3D에서 기슭막이·집수정·배관을 각각 눌렀을 때 좌측 폼이 그 시설로 열리는지 ② 강조가 한 번에 하나만 켜지는지 ③ 빈 곳 클릭으로 해제되는지 ④ 마커 끌기·회전이 안 깨지는지 ⑤ 그 뒤 B06 에 들어가면 같은 측점 카드가 선택·스크롤되고 조정창이 열리는지.

    • 방법 — 공용 브라우저(5173, 프로젝트 8cd2e635)에서 구조물 메쉬 표면 한 점을 화면 좌표로 환산해 실제 마우스로 클릭. 판정은 sessionStorage 넘김값 · 메쉬 자체발광(emissive) · 좌측 목록 선택 · B06 화면으로.
    • ① 기슭막이 클릭 → 넘김값 {"at":85.59,"key":"outlet"}, 좌측 목록 4+5.6 배수관 1 선택. 집수정 → key:"basin", 배관 → key:"pipe" (모두 같은 목록 항목).
    • ② 밝아진 메쉬는 고른 부재 것만 — 기슭막이 2장(관통 컷 위·아래 조각) → 집수정으로 바꾸면 집수정 2장만, 기슭막이는 꺼짐.
    • ③ 빈 곳 클릭 → 넘김값 없음 · 밝은 메쉬 0장 · 목록 선택 없음.
    • ④ 구조물 위에서 90px 끌기 → 카메라 좌표 합계 17.7 이동, 선택 0건. 마커(bp) 클릭 → 마커만 선택(확대 1.35배), 구조물 넘김값 없음.
    • ⑤ 3D에서 유출 기슭막이를 고른 뒤 [횡단설계] 진입 → 카드 4+5.6 (85.6m) 이 선택·스크롤되고 조정창 「기슭막이(유출)」 가 그 카드에 열림. 넘김값은 소비돼 비워짐.
    • 계획 대비 차이 4가지 — ① 저장 코리도 만료 추가(BUILD_VERSION 90→91). 옛 저장본엔 부재키가 없어 3D에서 골라도 B06으로 넘길 부재를 못 정함(실측: 키 전부 null). ② 뷰어 700줄 여유 확보 — 검증용 요약을 B05_Profile_UI_Viewer_Debug.ts 로 분리(동작 불변). 뷰어 687줄. ③ 검증 수단 추가__corridorScenecameraproject(모델좌표→화면좌표). 3D 물체를 실제 마우스로 누르려면 화면 자리를 재야 함. ④ 클릭은 캡처 단계로 — 캔버스 버블 단계 pointerdown 이 아예 안 옴(실측). 캡처로 달되 마커 입력보다 뒤에 등록.
    • 남은 것 — 없음. 세월교·BOX암거 부재키는 아래 후속으로 일원화함.

부재키 일원화 (2026-09-04 사용자 지시 — 완료)

「이름표는 당연히 일원화해야 함. 대부분 횡단도를 보고 작업한 결과물이며 계산로직상으로도 횡단도가 우선 지정됨」. 확정 두 가지 — ① 본체(세월교 월류부 상판·BOX 구체)를 누르면 좌측 폼·목록 강조와 B06 측점 카드까지만, 조정창은 안 띄움 ② 3D 강조는 부재 하나만.

  • 이름표 = 횡단도가 부르는 이름 — 세월교 inlet·outlet, BOX암거 left·right, 본체는 body. 이름이 겹쳐도 한 측점엔 시설이 하나뿐이라 (측점+이름)이면 유일함.
  • 부재까지 한 칸 더 — 조정창 하나가 그 측 부재 여럿을 다루므로 측이름:부재 꼴(inlet:wall·inlet:floor·inlet:wing·inlet:apron·left:apron·left:wing). 강조는 전체 키로 맞추고, B06 조정창은 앞칸만 봄.
  • B06 갈래 태우기 — 그 측점이 세월교면 세월교 조정창, BOX암거면 BOX 조정창, 아니면 기슭막이 조정창(신규 모듈 B06_Section_UI_Page_Structure_Pick.ts).
  • 저장 코리도 만료(BUILD_VERSION 91→92) — 91 저장본엔 배수관 세트 키만 있음. 재계산 비용 실측 = 저장본 5.1초 / 재계산 4.7초로 차이 없음(오차 범위).
  • 자체검증 — 공용 브라우저(5173) 실측.
    • 부재키 빈 칸 0건(전 구조물 72개). 세월교 측점 177.32 = body 1 · inlet:wall 2 · inlet:floor 1 · inlet:apron 2 · inlet:wing 2(유출측 동일).
    • 세월교 유입 측벽 클릭 → 넘김값 {"at":177.32,"key":"inlet:wall"}, 밝은 메쉬 그 벽 2장만(바닥·날개벽은 안 켜짐), 좌측 목록 8+17.3 세월교 1.
    • 이어서 [횡단설계] 진입 → 카드 station_000000177320 선택, 조정창 「세월교 유입 측벽」 열림.
    • 배수관 세트 되풀이 확인 — 유출 기슭막이 클릭 → {"at":85.59,"key":"outlet"} · 밝은 메쉬 2장 · 목록 4+5.6 배수관 1, 빈 곳 클릭 시 전부 해제.
    • 못 해 본 것 — BOX암거는 이 프로젝트에 없어 클릭 검증 못 함(부재키 부여 경로는 세월교와 같은 모듈).

선택 시 화면 전체 활성화 + 세션 상시 공유 (2026-09-04 사용자 보고 — 완료)

사용자 보고 두 가지 — ① 3D에서 구조물을 골라도 좌측 패널이 활성화되지 않음 ② 횡단도를 골라도 구조물 리스트가 하이라이트만 되고 보이는 자리로 이동하지 않음. 원칙 재확인 — 구조물 리스트·구조물 배치 폼·배수유역도·테이블·3D(횡단도)가 함께 활성화, B05·B06은 다른 페이지지만 한 페이지처럼(캐시·세션 공유).

측정으로 확인한 구멍 3 + 검토에서 나온 결함 1:

  • 좌측 패널 자동 펼치기 — 패널이 접혀 있으면 폼에 값이 실려도 안 보였음(실측: 폼 값은 실렸는데 패널 is-collapsed). 바깥(3D·종단·유역도·횡단도·복원)에서 고른 것이 폼에 실릴 때 패널을 펼침(onReveal 창구, B05·B06 공용 패널 한 곳).
  • 리스트 스크롤 이동 — 계곡 통과 시설 행에 scrollIntoView가 없었음(구조물 행만 있었음). 선택 행을 보이는 자리로 끌어옴(펼침 직후라 다음 프레임에).
  • 테이블 강조 — 확정으로 종단 정본에 병합된 구조물 측점이 구조물 구간 판정에서 빠졌고, 소수 3자리 문자열 비교라 끝자리가 갈리면(85.590↔85.594) 놓쳤음. 병합 측점 포함 + 허용오차(1cm) 비교로 교체. 실측 0건 → 6건(구배 3행×2구간).
  • 세션 상시 공유(양방향) — 넘김값을 소비형(1회)에서 유지형으로 바꿈. B06에서 고른 것(카드·목록·조정창 부재)도 같은 세션 칸에 적혀 어느 쪽으로 오가든 마지막 선택이 살아 있음. 진입 복원은 목록 로드가 늦는 경우까지 이중으로 세움.
  • 검토 결함 수정 — 카드 선택 시 조정창을 닫는 코드가 "해제"로 세션까지 지워, B06 목록 선택이 적히자마자 사라졌음(실측: 클릭 직후 session null). 부재 해제는 세션을 건드리지 않게 분리.
  • 자체검증 — 공용 브라우저(5173) 실측 왕복 2종.
    • B05 진입 복원: 패널 펼침 · 목록 「4+5.6 배수관 1」 선택+보임 · 유역 1 · 그래프 알약 1 · 테이블 6 · 3D 부재 2 — 6개 영역 전부.
    • B06 목록 「세월교 1」 클릭 → 세션 {"at":177.32} → B05 복귀: 같은 항목 선택+보임·유역·그래프·테이블 6·3D 19(측점 전체).
    • B05 3D 유출 기슭막이(447.32) 클릭 → 세션 {"at":447.32,"key":"outlet"} → B06: 패널 펼침·목록 「22+7.3 배수관 3」·카드 선택·조정창 「기슭막이(유출)」·세션 유지.
    • 줄 수 — B05 페이지 694 · B06 페이지 699 · 나머지 전부 700 미만(한계 근접 — 다음 작업 시 분리 여지 확인).

주의(700줄 리팩토링 진행 중) — 손댈 파일이 한계 근처임: 뷰어 693줄 · B05 페이지 691줄 · 코리도 메쉬 531줄 · 구조물 패널 1,024줄(분리 대기). 새 코드는 새 모듈로 빼고, 공유 파일을 손대기 전 git sync, 끝나면 push 하고 다른 창에 알릴 것(7장).

B01 프로젝트 수정 — 회사 로고 기본 연결 (2026-09-04 구현 완료 · 검증 대기)

사용자 지시(2026-09-04) — 「프로젝트 수정 모달의 회사 로고는 소속회사에 연결된 정보를 기본으로 연결하고, 필요한 경우 로고를 변경하게 할 것」.

착수 전 코드를 읽고 낸 현황임.

  • 도면은 이미 회사 로고로 떨어짐 — 표제란 값 조회가 COALESCE(p.logo_asset_id, c.logo_asset_id) 임(B07_DesignDetail_Router.py). 프로젝트가 로고를 안 골라도 도면에는 회사 대표 로고가 실림. 즉 이번 일은 저장 구조 변경이 아니라 화면 표시 문제임.

  • 모달이 프로젝트 값만 봄 — 「회사 로고 (도면 표제란)」 칸이 project.logo_asset_id 하나만 읽어(B01_Dashboard_UI_Modals.tscreateAssetField 호출, 칸 구현은 B01_Dashboard_UI_AssetPicker.ts) 비어 있으면 「(없음)」으로 보임 — 회사 로고가 붙는지 사용자가 알 수 없음.

  • 회사 로고 값을 가져올 창구는 이미 있음CompanyInfo.logo_asset_idfetchUserCompany()(B01_Dashboard_Api_Fetch.ts). 모달이 지금 부르는 구성원·자산 조회와 함께 부르면 됨.

  • 빈 칸을 회사 기본 로고로 보이기 — 프로젝트 값이 없으면 회사 로고의 미리보기와 이름을 「회사 기본 로고 · <자산명>」으로 표시. 저장값은 계속 비워 둠 — 회사 로고를 바꾸면 프로젝트가 따라가야 하므로(연결 유지) 값을 복사해 굳히지 않음.

  • 필요할 때만 변경 — [선택…]으로 다른 로고를 고르면 그때만 프로젝트 전용 값으로 저장(지금 동작 그대로).

  • [기본으로] 되돌리기 — 프로젝트 전용 로고를 지우고 회사 기본 연결로 되돌림(값 null).

  • 회사 로고가 없을 때 — 「(없음) — 회사 로고 미지정 (회사 정보 화면의 「로고 지정…」)」으로 안내.

  • 자체검증 (2026-09-04, 검증 대기) — 공용 브라우저(5173)에서 프로젝트 용화_LAS 로 실측.

    • 방법 — 자산 칸에 fallback 을 넣어 프로젝트 값이 null 일 때 회사 자산을 대신 보이게 함 (createAssetFieldAssetFieldOptions.fallback). 회사 정보는 fetchUserCompany() 로 함께 받고, 내 회사 프로젝트일 때만(company.id === project.company_id) 기본을 내밈.
    • 결과 ① 저장값을 null 로 만든 뒤 모달을 다시 열자 이름 회사 기본 로고 · 캐미팩토리 로고(견본), 그림 /api/dashboard/company/assets/1/file, [기본으로] 는 숨김(resetHidden=true).
    • 결과 ② [기본으로] → [확인] 저장 뒤 서버 재조회 logo_asset_id = null — 값 복사 없이 연결만 유지됨.
    • 결과 ③ 자산 고르기에서 로고를 다시 골라 저장하니 logo_asset_id = 1 로 되돌아옴(원래 값 복원 완료).
    • 결과 ④ 표제란 조회는 COALESCE(p.logo_asset_id, c.logo_asset_id) 이고 회사 값이 1 이라 프로젝트 null 상태에서도 도면에 실리는 자산 = 화면에 보인 자산(1)로 같음.
    • 계획 대비 차이 — 「회사 로고 미지정」 안내는 이 계정 회사에 로고가 있어 실화면 확인 불가(코드 경로만 마련).

B01 모달 — 바깥 클릭으로 닫기 + 변경 확인 (2026-09-04 구현 완료 · 검증 대기)

사용자 지시(2026-09-04) — 「B01 모달 팝업은 다른 공간을 클릭하면 닫히게. 단 내용이 추가되거나 변경된 게 있으면 별도의 확인 모달창(양식화되어 있음)을 보여 줄 것」.

착수 전 코드를 읽고 낸 현황임.

  • 모달 껍데기를 만드는 자리가 세 곳 — 공통 openModal(B01_Dashboard_UI_Modals.ts — 프로젝트 수정·삭제·사용자 수정·회사 등록 등 대부분이 여기를 지남), 자산 고르기(B01_Dashboard_UI_AssetPicker.ts), 임시보관함(B01_Dashboard_UI_TempModal.ts). 셋 다 같은 클래스(b01-dashboard__modal)를 씀.

  • 지금은 바깥을 눌러도 안 닫힘 — [취소]·[확인] 단추로만 닫힘.

  • 양식화된 확인창은 이미 있음 — 공용 showConfirmDialog(문구, 확인라벨)(ui_template/ui_template_elements.ts). 네이티브 confirm 대신 반드시 이것을 쓰라고 적혀 있으므로 새로 만들지 않음.

  • 바깥 클릭 닫기 — 오버레이 자신을 눌렀을 때만 닫고 패널 안 클릭은 무시. Esc 도 같은 경로로 묶음. 세 곳 모두 같은 규칙.

  • 변경 감지 — 모달을 열 때 입력값 스냅샷을 떠 두고, 닫기 시도 때 현재값과 비교. 대상은 입력칸·선택칸·파일칸과 로고 선택값.

  • 변경이 있으면 확인창showConfirmDialog 로 「변경한 내용이 저장되지 않습니다. 닫을까요?」를 띄우고 확인이면 닫음, 취소면 모달을 그대로 둠. 변경이 없으면 확인 없이 바로 닫음.

  • [취소] 단추도 같은 판정 — 세 곳 모두 [취소]가 바깥 클릭과 같은 tryClose 를 지남.

  • 자체검증 (2026-09-04, 검증 대기) — 공용 브라우저(5173) 실측.

    • 방법 — 규칙을 한 곳(B01_Dashboard_UI_Common.tsattachModalDismiss)에 두고 세 자리에서 부름. 입력칸 밖에서 바뀌는 값(고른 로고·고른 파일)은 extra 로 실어 견줌. 확인창이 모달 뒤에 깔리던 문제는 z-index 토큰 --z-confirm: 1050 을 새로 두어 해결(모달 1000 < 확인 1050 < 토스트 1100).
    • 결과 ① 안 고친 프로젝트 수정 모달에 바깥 클릭 → 확인창 없이 즉시 닫힘(modal=False, confirm=False).
    • 결과 ② 로고를 [기본으로] 바꾼 뒤 바깥 클릭 → 확인창 문구 「변경한 내용이 저장되지 않습니다. 닫을까요?」, [취소] 누르니 모달 유지·바꾼 값 유지(회사 기본 로고 · 캐미팩토리 로고(견본)).
    • 결과 ③ Esc 도 같은 확인창을 지나고 [닫기] 로 닫힘. 닫기만으로는 서버 값이 안 바뀜(재조회로 확인).
    • 결과 ④ 자산 고르기 — 안 고치면 바깥 클릭에 바로 닫히고(모달 2→1), 「신규 추가」 이름을 넣으면 확인창이 뜨며 [취소] 시 그대로 남음(모달 2 유지). 임시 보관함 — 안 고치면 바로 닫히고(1→0), 이름을 넣으면 확인창이 뜨고 [취소] 시 값 보관함 시험 이 남음.
    • 결과 ⑤ 패널 안 입력칸 클릭으로는 안 닫힘. 패널에서 시작한 드래그가 바깥에서 끝나도 안 닫힘(누른 자리로 판정).
    • 계획 대비 차이 — 확인창 z-index 를 함께 고쳐야 했음(계획에 없던 공용 토큰 1건 추가).

B05 3D — 절토 구간 측점 표시·전체 라벨 (2026-09-04 예정)

사용자 지적(2026-09-04) — ① 「3D 노선에 절토가 된 경우 측점 표시가 안 따라감」 ② 「측점 라벨이 구조물 측점 빼고 5측점 기준으로만 붙음. 전체 라벨이 있으면 좋겠음」.

착수 전 코드를 읽고 낸 현황임.

  • ① 원인은 한 줄 — 측점 막대의 표고를 Math.max(지반 표고, 계획고) 로 잡음(B05_Profile_UI_Page.ts). 성토(계획고 > 지반)면 계획고를 타지만 절토(계획고 < 지반)면 원지반 표고에 그대로 남음 — 3D 코리도는 절취해 노면이 내려가 있으므로 측점 막대만 공중에 뜸.

  • 고칠 방향 — 코리도(절취 지형)가 켜져 있으면 계획고를 그대로 씀. 코리도를 끈 상태에서는 원지반이 그대로라 지금처럼 max 를 유지해야 막대가 땅에 묻히지 않음. 즉 코리도 표시 여부로 갈라 잡음.

  • ② 라벨 규칙STATION_LABEL_STEP = 5 로 규칙 측점은 5칸(=100m)마다만 달림(B05_Profile_UI_Markers.ts). BP·EP·구조물 측점은 항상 달림. 5칸으로 묶어 둔 이유는 글자 겹침임(2026-08-04).

  • 겹침 대책이 필요함 — 20m 측점을 전부 달면 멀리서 볼 때 글자가 붙음. 카메라가 멀면 솎고 가까우면 전부 보이게 하는 거리 기준 솎기가 라벨 수를 늘리면서 읽힘을 지키는 가장 싼 방법임(스프라이트라 카메라 거리를 이미 알고 있음).

  • 절토 구간 측점 표고 — 코리도 표시 중이면 계획고를 그대로 씀(max 제거). 코리도를 끄면 designAt 이 값을 안 주므로 지금대로 원지반.

  • 전체 라벨 — 규칙 측점 전부에 라벨을 만듦(STATION_LABEL_STEP 규칙 제거).

  • 거리 기준 솎기LABEL_LOD 3단(카메라~시점 150m 미만 전부 · 400m 미만 2칸 · 그 밖 5칸). 구조물·BP·EP 는 stationNumber: null 로 두어 항상 표시. 판정은 뷰어 렌더 루프에서 카메라 거리로(단계가 안 바뀌면 즉시 반환).

  • 자체검증 — 공용 브라우저(5173, 용화_LAS) 실측.

    • 방법 — 측점 막대마다 위에서 아래로 레이를 쏴 코리도 표면·원지반 표고를 재고 막대와의 높이차를 비교(절토 = 코리도가 원지반보다 낮은 측점). 라벨은 스프라이트 개수·화면 글자 크기·겹침 쌍 수로 판정.
    • ① 절토 측점 3곳 모두 막대 코리도 표면 = 0.80m(띄움값 그대로). 예: 0측점 코리도 44.78 · 원지반 47.98(절토 3.2m) · 막대 45.58. 고치기 전이라면 원지반 위 48.78 로 3.2m 공중에 떠 있었을 값.
    • ② 성토 측점 10곳도 0.80m 로 전과 같음(성토는 계획고가 원지반보다 높아 max 와 결과가 같음).
    • ③ 라벨 66개(측점 66개 전부) 생성. 카메라를 붙이면 66개 전부 표시, 중간 거리 39개, 화면맞춤 23개(항상 13 + 5칸 10).
    • ④ 화면맞춤에서 겹침 1쌍(항상 표시끼리 — 같은 자리 BP·구조물). 규칙 측점끼리 겹침 0. 글자 크기는 화면맞춤 4px → 가까이 47px.
    • 계획 대비 차이 — 없음.

B04·B05 배수유역도 — 줌 한계 확대·측점 표기 (2026-09-04 구현 완료 · 검증 대기)

사용자 지적(2026-09-04) — ③ 「B04·B05 배수유역의 줌인이 너무 멀리서 멈춤. 한 화면에 측점 1~2개까지 확대되면 좋겠음」 ④ 「배수유역도에 측점 표기가 없어 종·횡단이나 3D와 견주어 보기 불편함. 다만 횡단배수 지점과 겹치지 않게 할 것」.

착수 전 코드를 읽고 낸 현황임.

  • 줌 상한이 낮음 — B04 지도는 8배(B04_PreProcess_UI_MapViewer.ts), B05 배수유역도는 16배(B05_Profile_UI_Drainage_Interact.ts)에서 멈춤. 도엽 한 장이 화면 폭에 들어오는 배율이 1배이므로, 도엽 폭이 1km 급이면 8배에서도 화면에 100m 이상이 들어옴 — 측점 5개 이상임.

  • 필요한 배율 — 규칙 측점 간격 20m 기준으로 한 화면에 12측점 = **화면 폭 2040m**. 도엽 실폭(meta.width_meters)을 알고 있으므로 상한을 고정 숫자가 아니라 「화면 폭이 20m가 될 때까지」로 계산하면 도엽 크기가 달라도 같은 체감이 됨.

  • 측점 표기가 없음 — 배수유역도는 계획선 위에 관 마커·유입 집중점·유역 번호 배지·선택 다이아몬드만 그림(B05_Profile_UI_Drainage_Render.ts). 측점 눈금·번호는 없음.

  • 겹침 주의 대상 — 횡단배수(관) 마커가 계획선 위 같은 자리에 있음. 유역 번호 배지도 맨 위에 얹힘. 측점 라벨을 같은 쪽에 그리면 관 마커를 가림.

  • 줌 상한 상향 — 고정값(8배·16배) 대신 computeMaxScale() 로 「화면 폭 20m」 배율까지 허용. 안전장치 ZOOM_SCALE_HARD_CAP = 2000.

  • 확대 시 화질 — 배율 4 를 넘으면 배경 그림의 흐림 보간을 끔(image-rendering: pixelated). 실제 크기는 축척 막대로 읽음.

  • 측점 눈금·번호 — 계획선 위 짧은 눈금 + 측점번호+잔여거리 표기. 그리는 코드는 한 곳(drawStationTicks, B04 MapOverlays)에 두고 B04·B05 가 함께 씀.

  • 겹침 회피 — 관 마커가 있는 측점은 라벨을 계획선 반대쪽으로 밈. 배율에 따라 5칸 → 2칸 → 전부. 노선이 되꺾이는 자리에서는 그것만으로 모자라 이미 그린 라벨과 겹치면 건너뛰는 규칙을 더함.

  • 자체검증 (2026-09-04, 검증 대기) — 공용 브라우저(5173) · 프로젝트 용화_LAS. 캔버스 그리기 호출을 한 프레임만 가로채 화면 좌표를 수치로 비교.

    • 결과 ① 최대 확대에서 화면 폭 B05 20.0m(배율 122.7), B04 20.0m(배율 208.3) — 종전 상한(16배·8배)으로는 각각 150m·460m 급이었음. B04 축척 막대가 「5 m」로 바뀜.
    • 결과 ② 그 배율에서 배경 그림은 image-rendering: pixelated 로 전환됨.
    • 결과 ③ B05 한 프레임에 측점 라벨 8개·관 마커 11개, 라벨↔마커 최소 거리 16px, 라벨끼리 최소 36px — 겹침 없음(라벨 높이 16px).
    • 결과 ④ B04 도 같은 라벨이 뜸(11개, 라벨끼리 최소 18px). 겹침 규칙을 넣기 전에는 되꺾이는 구간에서 최소 4px 까지 붙었음 — 규칙 추가 후 해소.
    • 계획 대비 차이 — 겹침 회피에 「이미 그린 라벨과 겹치면 건너뛰기」를 더함(계획에 없던 규칙, 되꺾임 구간 때문).

B03~B08 좌측 패널 제목 줄 — 프로젝트 이름 우측 표기 (2026-09-04 구현 완료 · 검증 대기)

사용자 지적(2026-09-04) — 「B03~B08 좌측 패널 상단 페이지 제목의 같은 행 우측 맞춤으로 프로젝트 이름을 넣어 달라고 했는데 반영 안 된 것 같음」.

  • 확인 결과 실제로 안 들어가 있음 — 좌측 제목 패널은 공용 createPanel("title", …) 하나가 만들고 제목 문자열 하나만 받음(ui_template/ui_template_overlay.ts). 페이지들은 createWorkflowLayout({ title }) 로 그 문자열만 넘김(ui_template/ui_template_workflow_layout.ts) — 프로젝트 이름이 들어갈 자리 자체가 없음.

  • 이름을 어디서 가져올지부터 정해야 함 — 화면이 들고 있는 것은 프로젝트 id 뿐임(localStorage 의 현재 프로젝트 키, A00_Common/b_page_scaffold.ts). 워크플로 상태 응답(WorkflowState)에도 이름이 없음. 두 갈래 — ① 워크플로 상태 응답에 이름 한 칸 추가(백엔드 조회에 컬럼 하나) ② 대시보드에서 프로젝트를 고를 때 이름도 localStorage 에 저장. ①이 안전함 — 새로고침·주소 직접 입력으로 들어와도 이름이 따라옴.

  • 이름 창구 — 워크플로 상태 응답(get_workflow_state)에 project_name 을 실음. 프론트는 fetchProjectWorkflowState 로 받음(응답 껍데기 {status, workflow_state} 를 벗기도록 함께 고침).

  • 제목 줄 오른쪽 표기 — 제목은 왼쪽, 프로젝트 이름은 같은 행 오른쪽 끝. 길면 말줄임, 전체는 툴팁.

  • 한 곳만 고쳐 여섯 화면 반영 — 공용 제목 패널(ui_template_overlay.tscreatePanel)에 이름표를 붙임. B03 은 레이아웃을 직접 조립해 createWorkflowLayout 을 안 지나므로, 이름표를 오버레이 쪽에 두어 두 조립 경로가 모두 얻게 함(페이지 코드는 손대지 않음).

  • 이름이 없을 때 — 프로젝트 미선택·조회 실패면 빈 칸(너비 0).

  • 자체검증 (2026-09-04, 검증 대기) — 공용 브라우저(5173) · 프로젝트 용화_LAS 로 실측.

    • 결과 ① B03~B08 여섯 화면 모두 이름 용화_LAS 표시(툴팁도 같은 값).
    • 결과 ② 여섯 화면 모두 제목과 같은 행(세로 중심 차 4px 미만), 패널 오른쪽 끝에서 16px(=패널 좌우 여백)로 붙음. 제목과 겹침 없음.
    • 결과 ③ 긴 이름을 넣어 재니 처음에는 제목이 59px→36px 로 밀리며 잘렸음 → 제목 패널의 제목만 flex: 0 0 auto, 이름은 max-width: 60% 로 고쳐 다시 재니 제목 59px 그대로, 이름만 말줄임(nameClipped=true), 겹침 없음.
    • 결과 ④ 새로고침 뒤에도 이름 유지. 프로젝트 id 를 지우면 칸 너비 0(제목만 보임).
    • 계획 대비 차이 — ⓐ 이름표 자리를 워크플로 레이아웃이 아니라 오버레이로 옮김(B03 경로 때문) ⓑ fetchProjectWorkflowState 가 껍데기를 안 벗기고 있어 함께 고침 ⓒ 백엔드 .py 변경을 uvicorn StatReload 가 잡지 못해 8000 백엔드를 한 번 재시작함(서브 창 8001 은 그대로).

B02·B03 계획노선 범위 — 시·종점 누가거리 입력과 절단 여유 3m (2026-09-04 구현 완료 · 검증 대기)

사용자 지시(2026-09-04) — 「계획노선 자료는 공사지 전체 데이터일 수 있어 사용자가 범위를 정할 필요가 있음. B02 프로젝트 생성 과정에서 노선의 시작 누가거리·종료 누가거리를 받고, 그에 맞춰 B03 의 내부 CSV 로 계획 평면 노선을 정한 뒤 서피스 밖 데이터를 잘라낼 것. 이때 절단 기준이 30m 로 되어 있는데 3m 로 변경 필요」.

착수 전 코드를 읽고 낸 현황임.

  • 절단 여유 값은 한 곳뿐SURFACE_ROUTE_EDGE_TRIM_M = 30.0(config/config_system_terrain.py), 쓰는 곳은 trim_route_to_surface(common_util/common_util_route_geometry.py) 하나임. 기본값만 바꾸면 전 경로에 반영됨(환경변수로도 덮임).

  • 30m 은 2026-09-01 사용자 확정값이었음 — 이유가 「서피스 가장자리는 점 밀도가 떨어져 그 구간 지반고가 못 미덥다」였음. 3m 로 낮추면 가장자리 값을 더 믿는 셈이므로 끝단 지반고가 튀지 않는지 확인이 함께 필요함(이번 지시로 값은 3m 로 바꿈).

  • B02 에 누가거리 칸이 없음 — 지금 받는 값은 공사명·지역·임도 종류·연도·연장·메모·시행청·연도기번·사업량·설계일자·담당자임(B02_ProjRegister_UI_Page.ts). 프로젝트 저장 구조에도 없음 — 화면·스키마·DB 세 층 모두 칸 추가가 필요함.

  • 자르는 순서 — 사용자 범위(시·종점 누가거리)로 먼저 자른 뒤, 남은 노선에 서피스 트림(3m 여유)을 적용해야 함. 순서가 바뀌면 사용자가 정한 시점이 서피스 트림에 밀려 달라짐.

  • 절단 여유 3mSURFACE_ROUTE_EDGE_TRIM_M 기본값 30 → 3.

  • B02 입력 두 칸 — 「노선 시작 누가거리 (m)」·「노선 종료 누가거리 (m)」. 비우면 전 구간.

  • 값 저장projects.route_start_m·route_end_m 추가(마이그레이션 db_management/015_route_range.sql, 공유 DB 에 적용 완료). B01 프로젝트 수정 모달에서도 고침.

  • B03 적용load_design_route(project_root, surface, route_range)범위 절단 → 서피스 트림 순서 보장. 자동 체인이 프로젝트 값을 읽어 넘김.

  • 잘못된 범위 안내 — 시작 ≥ 종료는 화면(B02·B01)과 서버(B02·B01 라우터) 양쪽에서 막음.

  • 자체검증 (2026-09-04, 검증 대기) — 프로젝트 용화_LAS 실측 + 단위 시험(tmp/tests).

    • 결과 ① 실제 노선(전 구간 2136.2m)에 범위 100~400m 를 걸면 300.0m 만 남고, 남은 시점 좌표가 원 노선 100m 지점과 0.5m 안에서 같음(test_route_range_real.py).
    • 결과 ② 절단 여유 30m → 3m 로 낮추자 연장 1070.4m → 1097.4m(+27.0m). 양 끝 20m 구간의 지반고 변화율 최대 0.203, 노선 안쪽 최대 0.494 — 끝단이 더 튀지 않음(test_edge_trim_3m_yonghwa.py).
    • 결과 ③ 범위를 비우면(None, None) 전 구간 그대로.
    • 결과 ④ B01 수정 모달에서 900~120 을 넣고 저장하면 서버가 막아 값이 안 바뀜(모달 유지). B02 등록에서도 같은 값으로 「종료 누가거리는 시작보다 커야 합니다.」가 뜨고 프로젝트가 생기지 않음.
    • 결과 ⑤ B01 모달에 120·900 을 저장하면 서버 값이 그대로 돌아오고, 비우면 다시 null(원상 복구까지 확인).
    • 계획 대비 차이 — 이미 자동설계를 마친 프로젝트는 계획노선 정본 CSV 를 지름길로 읽으므로, 범위를 나중에 바꿔도 초기값 스냅샷을 지우고 다시 돌리기 전에는 반영되지 않음(신규 프로젝트는 정상). 스냅샷 폐기 연동은 별도 판단 필요.

B05 3D — 원근 카메라로 되돌리기 (2026-09-04 예정)

사용자 지시(2026-09-04) — 「3D 원근 관련 기능을 바꾼 적이 있는데 이전 방식이 좋았음. 되돌리되 바꾼 뒤 문제가 될 요소를 미리 확인할 것」.

  • 바꾼 자리를 찾음 — 커밋 f6296fa7(2026-08-25) 「구조물 3D 투영 표기 · 직교 카메라 · 조정창 템플릿 일원화」. 그 전에는 원근 카메라(시야각 45°)였고, 이때 B05_Profile_UI_Viewer_Camera.ts 를 새로 만들어 직교(원근 없음) 로 바꿈. 당시 이유는 「원근 왜곡 없이 탑뷰 판독」이었음.
  • 그 이유가 지금은 거의 사라짐 — 직교가 필요했던 대상은 탑뷰에 겹쳐 그리던 구조물 투영 윤곽선(노랑·하늘·주황)인데, 그 커브 묶음은 2026-09-02 사용자 지시로 숨김 처리되어 지금 화면에 없음(__corridorPlanCurves(true) 로만 켬).
  • 되돌릴 코드는 작음 — 뷰어에서 카메라를 만드는 자리와 화면맞춤 한 줄(setHalfHeight)뿐임(B05_Profile_UI_Viewer.ts 4곳). 카메라 위치·근평면·먼평면 계산은 그대로 씀.
  • B04 는 계속 원근임 — 지표면 뷰어들은 지금도 원근 카메라라, 되돌리면 B04·B05 조작감이 같아지는 이득이 있음. 커서 피벗 줌 유틸은 두 방식 모두 지원하며(B04가 원근 경로를 매일 씀) 갈아 끼울 것이 없음.

되돌린 뒤 문제가 될 요소(미리 점검한 결과)

  • 탑뷰 왜곡이 돌아옴 — 화면 중앙에서 먼 측점일수록 구조물 옆면이 보여 위에서 내려다본 크기 비교가 어긋남. 정밀 대조가 필요할 때를 대비해 직교/원근 전환 단추를 하나 두는 안을 함께 검토(기본은 원근).

  • 줌 느낌이 달라짐 — 직교는 배율만 키우지만 원근은 카메라가 실제로 다가감. 아주 가까이 가면 근평면에 지형이 잘릴 수 있음(근평면은 화면맞춤 거리의 1/1000). 확대 한계를 실측으로 확인할 것.

  • 측점 띠·라벨 크기 — 스프라이트·띠 크기가 지금 직교 기준으로 잡혀 있어(라벨 높이 3.2 단위, 띠 0.18×0.5) 원근에서는 가까울수록 커지고 멀수록 작아짐. 「B05 3D 절토 구간 측점 표시·전체 라벨」 항목의 거리 기준 라벨 솎기와는 오히려 궁합이 맞음 — 두 항목을 같이 손보는 것이 이득.

  • 화면맞춤 크기감 — 지금은 직교 반높이를 거리 × 0.42 로 두어 원근 45° 를 흉내 내는 중이라, 되돌리면 자연히 원래 크기감으로 맞음.

  • 문제 없음을 확인한 것 — 구조물·마커 클릭(둘 다 카메라 종류와 무관), 나침반, 저장 코리도 캐시(기하와 무관해 무효화 불필요), 탑뷰 기울임(극점 뒤집힘 방지)은 그대로 유지.

  • 원근 카메라 복귀 — 뷰어 카메라를 시야각 45° 원근으로 되돌리고 직교 전용 화면맞춤 처리를 걷어냄. B05_Profile_UI_Viewer_Camera.ts 삭제(직교 전용 모듈), 뷰어 4자리 복원. 뷰어 689줄.

  • 직교/원근 전환 단추 — 2026-09-04 사용자 확정 「넣음」. [ISO][TOP][FRONT][SIDE] 옆에 단추 하나, 글자는 갈 쪽을 가리킴(직교로원근으로). 기본은 원근.

    • 카메라 두 벌을 B05_Profile_UI_Viewer_Camera.ts 가 쥐고 갈아 끼움. 갈아 끼우면 객체가 바뀌므로 마커 입력·구조물 클릭·커서 피벗 유틸이 카메라를 값이 아니라 함수로 받도록 바꿈(공용 B04_PreProcess_UI_Camera.ts 는 값도 그대로 받게 두어 B04 호출부 무변경).
    • 전환해도 화면이 튀지 않게 위치·시선·근평면·먼평면을 옮기고, 보이는 크기를 맞춤(원근→직교는 시점거리로 반높이를, 직교→원근은 배율로 거리를 되돌림).
    • 자체검증(용화_LAS, 5173) — [직교로] 클릭 → Ortho, 카메라 위치·근평면·먼평면 그대로, 화면 크기 1,217×795px → 1,096×730px(원근 왜곡분 10%). 단추 글자 원근으로 로 바뀜. 직교 상태에서 휠 확대 = 배율 1 → 1.882 로 동작. [원근으로] 클릭 → 되돌아오고 값이 처음과 완전히 일치. B04 지표면 화면에서 휠·드래그 시 페이지 오류 0건.
  • 근평면 확인 — 실측 결과 근평면 상한 0.4m 를 새로 걺. 휠 확대는 커서 아래 지점 0.5m 앞에서 멈추는데(커서 피벗 유틸) 근평면을 맞춤거리의 1/1000 로만 두면 긴 노선에서 그 0.5m 를 넘어 잘림. 용화_LAS(맞춤거리 1,208m)는 상한 없이는 근평면 1.21m > 0.5m 로 잘렸을 값.

  • 측점 띠·라벨 크기 재조정손대지 않음. 실측 결과 직교 때와 화면 글자 크기가 같음(화면맞춤 3.9px — 직교 반높이 거리×0.42 로 계산한 값과 일치). 읽힘은 크기가 아니라 거리 기준 솎기(위 라벨 항목)로 해결함.

  • 자체검증 — 공용 브라우저(5173, 프로젝트 5cff3920 용화_LAS) 실측. ④ 는 라벨 항목과 함께 하므로 남김.

    • 방법 — 좌측 [ISO]·[TOP]·[FRONT]·[SIDE] 단추를 실제로 눌러 카메라 상태와 모델 경계의 화면 픽셀 크기를 잼. 확대 한계는 캔버스 위에서 실제 휠을 100칸 굴려 커서 아래 지점까지의 거리와 근평면을 비교. 구조물은 노출된 캔버스 지점을 찾아 실제 마우스 클릭.
    • ① 네 방향 모두 Perspective · 시야각 45° 로 뜸(직교 0건). 화면맞춤 크기감 — 직교는 반높이를 거리×0.42 로 원근 45°(tan 22.5° = 0.41421)를 흉내 내던 값이라 차이 1.4%, 되돌린 뒤가 원래 크기감임. 탑뷰 모델 885×583m → 화면 1,217×795px(캔버스 1,341×1,240).
    • ② 확대 한계 — 휠 100칸에서 커서 아래 지점까지 0.516m 에서 멈춤, 근평면 0.4m 이라 잘림 없음. 축소는 far(맞춤거리×10)까지 그대로.
    • ③ 구조물 클릭 — 유출 기슭막이 클릭 → 넘김값 {"at":85.594514,"key":"outlet"} · 밝은 메쉬 2장(그 부재만) · 좌측 목록 4+5.6 배수관 1 선택. 빈 곳 클릭 → 넘김값 null · 밝은 메쉬 0장.
    • ⑤ B04 와 조작감 — B04 지표면 뷰어도 원근(시야각 50°)이고 커서 피벗 줌 유틸을 공유하므로 같은 계열이 됨(전에는 B05만 직교였음).
    • 계획 대비 차이 1가지 — 근평면 상한 0.4m 추가. 계획은 「필요하면 조정」이었고 실측에서 긴 노선이 잘리는 것이 확인돼 반영함.

B07 횡단면도 — 축척 뒤죽박죽 확인 (2026-09-04 완료, 검증 대기)

사용자 지적(2026-09-04) — 「B07 횡단면도의 축척이 뒤죽박죽으로 보임」.

  • 축척 값 자체는 한 곳 고정DRAWING_SCALE_CROSS = 100(1/100), 도면 좌표 환산도 그 한 값만 씀(B07_DesignDetail_Engine_Cad.pyCROSS_MM). 단면마다 다른 축척을 쓰는 코드는 없음.

  • 대신 단면마다 그리는 범위가 다름 — 가로는 「설계선이 원지반과 갈라졌다 다시 만나는 구간 + 여유 1.5m」, 세로는 그 구간의 표고차로 잡음(_section_window). 절·성토가 큰 측점은 크게, 작은 측점은 작게 나옴.

  • 칸 크기도 제각각 — 장 배치가 열폭 = 그 열 최대폭, 행높이 = 그 행 최대높이임(2026-08-30 사용자 확정). 그래서 같은 축척이어도 테두리·간격이 들쭉날쭉해 축척이 다른 것처럼 보일 수 있음.

  • 먼저 가릴 것 — 서로 다른 두 단면에서 같은 실거리(예: 노폭 3m)가 종이에서 같은 mm 인지 재 볼 것. 같으면 「칸 크기」 문제이고, 다르면 진짜 축척 문제임(장 배치에서 블록을 줄이는 자리가 있는지 추적).

  • 원인 가리기 — 같은 실거리의 종이 치수를 두세 단면에서 재어 축척 문제인지 칸 크기 문제인지 확정.

    • 실측(용화_LAS, 측점 12개): 실거리 3 m 가 모든 단면에서 정확히 30.0 mm — mm/m 이 전부 10.0000. 축척 문제 아님.
    • 같은 장(1장, 단면 6개) 칸 실측: 폭 116218 mm(차 102), 높이 29178 mm(차 148). 전체 65개 측점으로는 폭 116438, 높이 77427. 칸 크기 문제 확정.
  • 칸 크기 문제면 — 한 장 안의 단면 칸을 같은 폭·높이로 통일(가장 넓은 단면 기준). 빈 곳은 여백으로 두어 눈에 규칙이 서게 함.

    • 옛 배치(열폭 = 그 열 최대, 행높이 = 그 행 최대)를 장별 완전 통일로 교체 — 한 장 안 모든 칸이 같은 폭·높이(_grid_for), 테두리는 build_cross_drawing(cell_frame=...) 로 칸에 맞춰 그림.
    • 장 경계는 전체 최소 장수가 되도록 동적계획으로 고름(_sheet_breaks) — 앞에서부터 채우면 바로 뒤의 큰 단면이 칸을 키워 6칸짜리 장에 1개만 실리는 일이 있었음.
  • 축척 문제면 — 블록을 줄이는 자리를 없애고 1/100 을 그대로 지킴. 한 장에 안 들어가면 장을 나눔.

    • 축척은 지식DB 「설계제원_총괄」 측량·도면 기준의 1/100 고정(단일값, 범위 없음). 블록을 줄이는 자리는 원래도 없었음 — 확인만 함.
  • 표제란 축척 표기 일치 — 실제로 그린 축척과 표제란 값이 같은지 확인.

    • 표제란 scale_fields(("", DRAWING_SCALE_CROSS)) = 1/100, 실측 mm/m = 10.0 — 일치.
  • 자체검증 — 도면 실측. ① 두 단면의 같은 실거리 종이 치수 일치 ② 한 장 안 칸 크기 균일 ③ 표제란 축척 일치 ④ 측점 누락 없음.

    • 방법: tmp/tests/test_b07_cross_scale.py · test_b07_cross_uniform.py · test_b07_variant_compare.py (용화_LAS) + 실서버 실측 — 로그인된 공용 브라우저(5174)에서 design-drawings API 를 불러 장별 칸 크기를 잼.
    • 결과 ① 3 m = 30.0 mm 전 단면 동일 ② 장 21개 전부 한 장 안 칸 폭·높이 단일값(예 1장 193×207.37 mm ×6칸, 4장 283×276.92 mm ×2칸) ③ mm/m = 10 단일 ④ 측점 65개 = 장에 담긴 측점 65개, 누락 0 ⑤ 칸 밖으로 나간 그림 0.000 mm.
    • 계획 대비 차이: 장수가 16 → 21~22 장으로 늘어남(칸 통일의 대가, 칸 사용률 평균 82%, 단면 1개만 실리는 장 4개). 2026-09-04 사용자 확정 — 축척은 건드리지 않고 세트별 장수 변동·여백 발생을 허용.

B06 표준 횡단면 설정 — 하나의 상세값 컨테이너로 통합 (2026-09-04 예정)

사용자 지시(2026-09-04) — 「좌측 패널의 표준 횡단면 설정 3가지 기준이 대부분 중복임. 「표준횡단면 상세값」 한 컨테이너로 묶을 것. 노폭·노견·측구는 공통, 암 구간은 반영할 절토 경사와 L형 측구만, 포장 구간은 절·성토 경사가 토사와 같고 횡단 경사만 다름. 공통 항목은 지우고 구분선을 써서, 횡단도에서 옵션을 골랐을 때만 해당 값이 반영되게 할 것」.

  • 지금 구조 — 토사·암·포장 3그룹이 같은 필드 묶음을 각각 가짐(노폭 / 노견 좌·우 / 측구 상단·하단·깊이 / L형 측구 폭·깊이 / 절토 경사 / 성토 경사 / 횡단 경사 최소·최대). 필드 정의는 한 벌인데 그룹마다 반복해 그림(B06_Section_UI_Standard_Panel.ts).

  • 바꿀 구조(사용자 확정) — 공통 = 노폭·노견·측구, 구분선 뒤 = 절토 경사 · L형 측구, 구분선 뒤 포장 = 횡단 경사. 포장의 절·성토 경사는 토사 값을 그대로 씀.

  • 저장 구조는 건드리지 않는 것이 쌈 — 서버와 주고받는 값은 지금 3그룹 형태임(standard_cross_section). 화면만 한 컨테이너로 합치고 저장할 때 3그룹으로 펼쳐 보내면 백엔드·기존 프로젝트가 그대로 동작함.

  • 판단이 필요한 한 가지 — 기존 프로젝트가 그룹마다 다른 공통값(예: 암 노폭만 다름)을 갖고 있을 수 있음. 합칠 때 무엇을 공통값으로 삼을지 규칙이 필요함(토사 값을 기준으로 삼는 안이 무난 — 착수 시 사용자 확인).

  • 한 컨테이너로 묶기 — 「표준횡단면 상세값」 하나에 공통 → 구분선 「암 구간 — 다른 값만」 → 구분선 「포장 구간 — 다른 값만」 순으로 배치. 옛 토사/암/포장 3개 접이 그룹은 없앰.

  • 중복 필드 제거 — 칸이 31개에서 15개로 줄었음. 공통 10칸(노폭·노견 좌우·측구 3·절토·성토 경사· 횡단 경사 min/max) + 암 3칸(절토 경사·L형 측구 폭/깊이) + 포장 2칸(횡단 경사 min/max).

  • 선택에 따른 반영 — 저장 구조가 3그룹 그대로라 카드에서 고른 옵션이 값을 고르는 경로는 바뀐 것이 없음.

  • 저장 호환 — 화면만 합치고, 공통값은 고칠 때 세 그룹에 펼쳐 넣음(spread). 나가고 들어오는 값은 예전과 같은 standard_cross_section 3그룹.

  • 기존 값 합치기 규칙 — 사용자 확정(2026-09-04): 토사 값 기준. 패널을 열 때·불러올 때·리셋할 때 unifyCommon 이 공통 항목을 토사 값으로 한 벌 맞춤(암 절토 경사·포장 횡단 경사는 제외).

  • 자체검증(2026-09-04, 공용 브라우저 5174 · 프로젝트 용화_LAS) — 세션 저장분을 직접 읽어 판정.

    • ① 공통 노폭 3 → 3.4 로 고치니 토사·암·포장 셋 다 3.4. 합격
    • ② 암 절토경사 0.4 → 0.55 는 암만 바뀌고 토사·포장은 1 그대로. L형 측구도 암 그룹에만 있음. 합격
    • ③ 포장 횡단경사 최소 1.5 → 1.8 은 포장만, 토사·암은 3 그대로. 합격
    • ④ 새로고침 뒤에도 화면·세션 값 그대로(3.4 / 0.55 / 1.8). 합격
    • ⑤ 옛 프로젝트 흉내로 그룹마다 다른 공통값을 심음(암 노폭 9, 포장 측구 상단 7, 암 성토경사 5) → 새로고침하니 전부 토사 값으로 합쳐짐(3.4 / 0.9 / 1.2). 구간 고유값(암 절토 0.55, 포장 횡단 1.8)은 유지. 합격
    • 계획 대비 차이 — 없음. 검증에 쓴 값은 원래 값(노폭 3 · 암 절토 0.4 · 포장 횡단 1.5)으로 되돌려 놓음.

B07 표준 횡단면도 — 변수 모식도·치수·부분확대·암반선 (2026-09-04 완료, 검증 대기)

사용자 지시(2026-09-04) — 「표준 횡단면도 좌상단에 기본값으로 B06 좌측 패널의 변수 위치 안내와 비슷한 그림을 넣고, 변수 이름 자리에 도면처럼 치수를 적을 것. 측구는 작으니 부분 확대도로. 발파·암반이면 암반선과 각도를 넣어 절토측이 2단(토사 각도 + 암반 각도)으로 표현될 것」.

  • 자리는 이미 있음 — 「표준 횡단면도」는 지금 도각만 있는 빈 도면임(blank_cross_standard, 2026-09-01 사용자 지시로 빈 채 열어 둠).

  • 모식도 원본이 있음 — B06 좌측 패널의 변수 위치 안내 모식도(B06_Section_UI_Standard_Diagram.ts). 같은 배치를 도면 축척·선굵기로 옮기면 됨.

  • 치수 값 출처 — 위 「B06 표준 횡단면 설정」의 값. 두 항목을 잇대어 하면 값 창구가 한 곳으로 정리됨.

  • 본 그림 — 좌상단에 표준 횡단면 모식도, 각 변수 자리에 치수선·치수값(도면 표기).

    • B06 모식도와 같은 배치(좌=절토·측구, 우=성토, 가운데=계획고)를 실치수로 그림. 축척 1/50(DRAWING_SCALE_CROSS_STANDARD). 치수선은 눈금+치수값 한 벌로 그리는 헬퍼로 통일.
  • 측구 부분 확대도 — 측구를 따로 확대해 그리고 그 확대 축척을 함께 적음.

    • 1/10(DRAWING_SCALE_DITCH_DETAIL), 상단폭·저폭·깊이 3개 치수 + 「측구 상세도 (S = 1/10)」 표기.
  • 암반선·2단 절토 — 발파·암반 구간은 암반 경계선을 긋고 위는 토사 각도, 아래는 암반 각도로 2단 표기(각도 값 함께).

    • 절토측에 덧그림. 아래 1.5 m 는 암반 1:0.4, 그 위는 토사 1:1. 암반선은 수평 파선 + 「암반선」 표기.
  • 어떤 구간을 그릴지 정리 — 기본은 토사, 암·포장은 달라지는 값만 덧그림(또는 별도 칸).

    • 본 그림 = 토사 기준. 암은 2단 절토로 덧그리고, L형 측구·포장 횡단경사는 주기(※) 로 적음. 사용자가 「묻지 말고 진행」이라 하여 이 안으로 확정.
  • 자체검증 — 도면 실측. ① 치수값이 표준 설정과 일치 ② 부분 확대도 축척 표기 ③ 암반선 2단 각도 표기 ④ 도각·표제란 정상.

    • 방법: tmp/tests/test_b07_standard_cross.py + 도면을 PNG 로 렌더해 눈으로 확인.
    • 결과 ① 본 그림 치수 500·3000·500·900·4000STANDARD_CROSS_SECTION 값과 일치 ② 확대도 900·300·300 + 「S = 1/10」 표기 ③ 「암반선」·「암반 1:0.4」·「토사 1:1」 표기, 2단 절토선이 꺾임점 1개(선분 2개) ④ 콘텐츠 358.2 × 172.6 mm ≤ A1 작도영역 739.2 × 499.2 mm, 표제란 축척 1/50 ⑤ 도면 목록에 cross_standard 가 실리고 빈 도각 목록에는 「표준도」만 남음.
    • 계획 대비 차이: 절·성토 높이는 실제 지형이 없으므로 대표값 3 m 로 그림(표준도 관례). 값 창구를 한 곳으로 모으는 「B06 표준 횡단면 설정 통합」 항목은 창 3 담당이 아니라 그대로 둠.
    • 실서버·화면 확인: 도면을 실제로 열어 캡처 — 도면층 7개(표준 단면·암반선 2단 절토·치수·측구 상세도·주기·표제·도각)가 모두 서고 표제란이 채워짐.

B07 계획평면도 3종 — 수치등고선 배경(유역도 자료 공유) (2026-09-04 완료, 검증 대기)

사용자 지시(2026-09-04) — 「계획평면도(지형·노선배치도·배치도) 세 장은 유역도와 같이 수치등고선을 배경으로 깔 것. 캐시 자료를 유역도와 공유할 수 있으면 좋겠음. 이걸 배경으로 다음 내용을 추가 설명 예정」.

  • 유역도가 쓰는 배경을 그대로 쓰면 됨 — 유역도는 도엽 수치지형도의 등고선·세류선(도엽_등고선.geojson·도엽_하천중심선.geojson)을 배경으로 깖. 읽기·좌표 환산·도곽 크기 절취는 B07_DesignDetail_Router_Support_Basin.py 한 곳에 있음 — 그 함수를 계획평면도도 부르면 자료·캐시가 저절로 공유됨.

  • 셋 다 지금은 빈 도면blank_plan_terrain · blank_plan_route · blank_plan_layout.

  • 정할 것은 축척 — 유역도는 1/6000 고정임. 계획평면도는 노선 전장이 들어가야 하므로 축척을 따로 정해야 함(도곽 크기에서 역산).

  • 배경 공용화 — 유역도의 배경 준비 함수를 계획평면도에서도 부르도록 창구 하나로 정리(자료 읽기 한 번, 여러 도면이 공유).

    • map_background() 하나로 모음(도엽 읽기·좌표 환산·도곽 절취). 유역도·계획평면도가 같은 것을 부름. 환산 결과는 _metric_lines_cached(파일 mtime 키)로 캐시.
  • 축척 결정 — 노선 전장·도곽 크기로 계획평면도 축척을 정함(장 나눔 규칙 포함).

    • 지식DB 「설계제원_총괄」 측량·도면 기준 1/1,200 고정(DRAWING_SCALE_PLAN). 횡단면도와 같은 원칙 — 줄이지 않고 안 들어가면 장을 나눔(plan_chunks, 종단 측점 기준·경계 측점 1개 중복). 용화_LAS 노선 전장 1,070 m·bbox 630×214 m → 종이 525×178 mm 로 1장.
  • 세 장의 주제 초안 — 지형 = 등고선·세류선만, 노선배치도 = 계획노선·측점, 배치도 = 구조물 배치. 세부는 사용자 추가 설명을 받아 보강.

    • 세 장 모두 같은 배경·같은 도곽 배치(지형도도 노선을 범위에만 넣고 그리지는 않음). 구조물은 pipe_points.json 정본에서 읽어 마름모+이름(세월교·BOX암거·D800 등).
  • 자체검증 — 세 장 모두 등고선 배경이 도곽 안에서 잘려 나오는지, 축척 표기와 실제가 맞는지, 유역도와 같은 자료를 두 번 읽지 않는지(응답 시간으로 확인).

    • 방법: tmp/tests/test_b07_plan_drawings.py (용화_LAS) — 실제 도면 생성 후 레이어별 개수·bbox·캐시 통계 실측.
    • 결과 ① 콘텐츠 734.3 × 489.2 mm ≤ A1 작도영역 739.2 × 499.2 mm, 세 장 동일 ② 노선 실거리 630.1 × 214.2 m → 종이 525.12 × 178.46 mm, 실측 0.83333 mm/m = 1/1,200 정확히 일치(표제란 표기와 같음) ③ 등고선 180줄·세류선 10줄이 세 장 모두 동일 ④ 주제 구분 확인 — 지형에 노선 0, 노선배치도에 측점 130개(65측점×눈금+이름)·구조물 0, 배치도에 구조물 22개(11개×기호+이름)·측점 0 ⑤ 자료 공유 실측: 유역도 배경 준비 8.5초(캐시 미스 2) → 계획평면도 1.3초(캐시 적중 2, 미스 증가 없음) — 두 번 읽지 않음 ⑥ 도면 목록에 plan_terrain·plan_route·plan_layout 3종이 실리고 빈 도각 목록에서 빠짐.
    • 계획 대비 차이: 측점 눈금을 노선 정점이 아니라 종단 측점 좌표로 찍도록 고침(정점 누가거리가 간격의 배수가 아니라 눈금이 2개만 찍혔음).
    • 실서버 확인(백엔드 재시작 뒤): 로그인된 공용 브라우저(5174)에서 세 장 모두 200 응답 — 지형 276개(등고선 180·세류선 10), 노선배치도 407개(+노선 1·측점 130), 배치도 299개(+구조물 22). 좌측 도면 목록에 네 개(라이다 포함) 버튼이 눌리는 상태로 뜸.

B07 계획평면도(라이다) — 3D 탑뷰 그림 배치 (2026-09-04 1차 배치 완료, 사용자 확인 대기)

사용자 지시(2026-09-04) — 「라이다 계획평면도는 3D 자료를 탑뷰에서 본 그림이 필요함. 가능한 범위에서 일단 배치해 주면 보고 개선하겠음」.

  • 도면 틀이 그림을 받아 줌 — 도면 템플릿에 이미지 요소가 있어 PNG·JPG 를 그대로 실을 수 있음(SVG 만 벡터로 바꾸고 래스터는 이미지로 둠).

  • 가장 싼 길 — 이미 만들어 둔 지표면 격자(DTM)로 음영기복 그림을 서버에서 만들어 배경으로 까는 것. 점구름을 그대로 그리면 수천만 점이라 도면 만들기가 느려짐.

  • 자리는 빈 도면blank_plan_lidar.

  • 탑뷰 그림 생성 — 지표면 격자로 음영기복 이미지를 만들어 도곽 범위에 맞춰 자름.

    • 확정 DTM 격자(dtm_{필터}[_smooth].npz)를 도곽으로 잘라 음영기복 PNG 생성(북서 315°·고도 45°, 한 변 최대 1,600 px). 어느 지표면을 쓸지는 1단계 확정값을 따름 — DrainageContextsurface_params 를 실어 전달.
  • 도면에 배치 — 계획평면도와 같은 축척·도곽으로 그림을 얹고 노선을 그 위에 그림.

    • Image 엔티티(네 모서리 + data URL)로 실음. 축척·도곽·장 나눔은 계획평면도와 같음(1/1,200).
    • 곁들여 고친 것: entities_bbox() 가 꼭짓점 배열(points)을 세지 않아 그림이 도곽 계산에서 통째로 빠졌음 — 세도록 고침.
  • 1차 배치 후 사용자 확인 — 보고 개선 방향을 받음(사용자 지시). ← 대기 중

  • 자체검증 — 그림이 도곽 안에 맞게 들어가는지, 좌표가 노선과 어긋나지 않는지(노선 양 끝 좌표로 대조), 도면 생성 시간이 크게 늘지 않는지.

    • 방법: tmp/tests/test_b07_lidar_plan.py (용화_LAS) + 생성된 PNG 를 직접 열어 눈으로 확인.
    • 결과 ① 콘텐츠 726.1 × 487.2 mm ≤ A1 작도영역 739.2 × 499.2 mm ② 그림 0693 × 0475.2 mm 안에 노선 80.4605.5 × 151.9327.6 mm 이 완전히 들어감(좌표 정합) ③ 음영기복 준비 0.4초, 그림 자료 214 KB — 점구름 4,900만 점을 그리는 것과 비교 불가하게 가벼움 ④ 능선·계곡이 눈으로 구분됨(첫 판 120255 는 흐려 90250 으로 대비를 올림).
    • 계획 대비 차이: 없음. 사용자 확인 후 개선 예정.
    • 실서버 확인: 로그인된 공용 브라우저에서 200 응답, 엔티티 88개(음영기복 그림 1·노선 1·도각 84·표제 2).

B07 용지도 — 등고선 배경 + 지적·행정구역 (2026-09-04 완료, 검증 대기)

사용자 지시(2026-09-04) — 「용지도는 계획평면도와 같이 수치등고선을 배경으로 하고 연속지적도·시군구·읍면동을 얹을 것. 색상은 변경하고, 배수유역도의 표 자리에 범례를 넣을 것. 연속지적도에 주소(지번) 정보가 있는지 확인하고, 없으면 일단 그림만」.

  • 자료는 이미 프로젝트마다 내려받아 있음 — 연속지적도·행정구역 시군구·행정구역 읍면동을 GeoJSON 으로 저장함(B04_PreProcess_Engine_GisVector.py 의 VWorld 내려받기).

  • 배경은 계획평면도와 같은 것 — 위 항목의 배경 공용 창구를 그대로 씀.

  • 주소 정보 있음(2026-09-04 실제 파일로 확인) — 저장된 연속지적도 GeoJSON 의 필지마다 속성 30개가 들어 있음. 쓸 만한 것은 지번(jibun, 예 「440전」)·지목(jimok면적(parea소유 구분(owner_nm개별공시지가(jiga_ilp)와 시도·시군구·읍면동·리 이름임(실측: 한 프로젝트 필지 952개, 경상북도 봉화군 춘양면 서벽리). 즉 필지에 지번을 적을 수 있고, 용지 조서용 면적·지목·소유 구분까지 이미 확보돼 있음.

  • 자리는 빈 도면blank_landuse.

  • 지번 표기 — 필지에 지번을 적음(겹치면 솎고, 작은 필지는 지시선으로 뺌). 지목·면적·소유 구분은 이번 판 표기 대상에서 뺌(용지 조서용 값이라 도면에는 안 넣음).

    • 작은 필지는 솎음(종이 6×3 mm 미만이면 지번 생략). 지시선으로 빼는 것은 이번 판 미구현 — 실측 대상 프로젝트에 해당 필지가 없어 확인할 수 없었음.
    • 도곽을 통째로 감싸는 필지를 따로 처리함 — 노선이 임야 대필지 안에 들어앉으면 경계선이 도곽 안에 하나도 없어 지번이 사라졌음(용화_LAS 실측: 노선 전체가 「산77-15임 일월면 용화리」 한 필지 안). 그 경우 도곽 중심에 지번만 적음.
  • 도면 구성 — 등고선 배경 위에 연속지적도(필지 경계)·시군구·읍면동 경계를 얹음.

    • 축척·도곽·장 나눔은 계획평면도와 같음(1/1,200), 배경도 같은 창구. 지적·행정 경계는 도곽 범위로 절취 — 자르지 않으면 산지 대필지 하나가 도면을 10 km 로 벌렸음(실측 콘텐츠 8,368 mm).
  • 색상 정리 — 지금 화면용 색과 다르게 도면용 색을 따로 정함(경계 굵기 포함).

    • 등고선 #9aa3ad(화면 #6b7684 보다 옅게) · 필지 #8c6b4f · 읍면동 #2f7d4f(파선 2px) · 시군구 #a63d3d(일점쇄선 3px) · 노선 #ffe066(3px).
  • 범례 — 유역도의 표가 있던 자리에 범례를 넣음.

    • 오른쪽 칸 방위표 아래. 5줄(계획노선·필지 경계·읍면동·리 경계·시군구 경계·등고선) + 제목.
  • 자체검증 — 도곽 안 배치·색 구분·범례 표기·좌표 정합(노선과 지적 경계가 어긋나지 않는지).

    • 방법: tmp/tests/test_b07_landuse.py (용화_LAS) — 실제 도면 생성 후 레이어별 개수·bbox·지번 대조.
    • 결과 ① 콘텐츠 734.3 × 489.2 mm ≤ A1 작도영역 739.2 × 499.2 mm ② 등고선 180줄 배경 + 노선 1줄 + 범례 11개 + 지번 1개 ③ 지번 「산77-15임」이 실제 지적 속성값과 일치 ④ 도면용 등고선 색이 화면용과 다름 ⑤ 도면 목록에 landuse 가 실리고 빈 도각 목록에서 빠짐.
    • 계획 대비 차이: 이 프로젝트에서는 필지·행정 경계선이 도곽 안에 하나도 없음 — 노선이 임야 대필지 한 곳에 통째로 들어가고 시군구·읍면동 경계는 도곽 밖임(실측: 지적 고리 198개 중 도곽에 걸치는 것 3개, 모두 3~7 km 짜리 산지 필지). 자료대로의 정상 결과이며, 경계가 지나는 노선에서 확인이 더 필요함.
    • 실서버 확인: 로그인된 공용 브라우저에서 200 응답, 엔티티 279개(등고선 180·범례 11·지번 1·노선 1).

표준도는 보류(2026-09-04 사용자) — 빈 도면(blank_standard) 그대로 둠. 2026-09-04 기준 빈 도각으로 남은 도면은 이것 하나뿐임.

B05·B06 종단 그래프 — 줌 버튼 단순화 (2026-09-04 예정)

사용자 지시(2026-09-04) — 「종단 그래프의 줌인·아웃이 마음에 안 듦. 버튼이 너무 많고 제어가 어려움. 버튼은 줌인·줌아웃만 두고, 그래프의 자유도는 맡김. 대신 하단 테이블과 그림이 연계되어 있으니 조심할 것. 유토곡선도 보이는 창의 내용에 따라 Y 값이 바뀌게 할 것」. 이어진 확정(2026-09-04) — 「유토곡선과 종단 그래프의 기본값이자 최대값은 지금 상태로 지정. 더 빽빽해지면 의미가 없음. 초기화 버튼은 유지해 기본값으로 돌아가게 할 것」.

  • 지금은 버튼 7개 — 가로 ·, 세로 ⇕+·⇕−, 창 이동 ·, 전체보기 (B05_Profile_UI_Profile_Zoom.ts, 2026-09-04). 가로·세로·창 중심을 사람이 각각 맞춰야 해 손이 많이 감.
  • 연계 구조 — 그래프·측점 테이블·계획고 편집 버튼층·구조물 알약 레인 넷이 같은 가로 좌표계를 씀. 그래서 가로 확대는 SVG 를 늘리는 방식이 아니라 캔버스 폭 자체를 키우는 방식이어야 넷이 함께 늘어남(현재 방식이 그러함 — 유지).
  • 유토곡선은 이미 종단과 가로 스크롤이 묶여 있음 — 두 그림이 같은 구간을 봄. 다만 Y 는 전 구간 최대 토량으로 고정이라, 확대해도 곡선이 납작하게 눌림.
  • 종단 그래프의 Y 도 사실상 같은 문제 — 표시 표고창을 사람이 ·▲▼ 로 맞추는 중임.

제안(사용자 요청 「가능한 방법」)버튼 2개는 가로 배율만 맡고, 세로는 프로그램이 자동으로 맞춤.

  • 줌인·줌아웃 = 가로 배율만 — 지금의 폭 배수 방식 그대로(한 칸 1.25배, 상한 8배).
  • 지금 상태가 기본값이자 축소 한계(2026-09-04 사용자 확정) — 폭맞춤 상태(배율 1)보다 더 축소하지 못하게 막음. 더 줄이면 측점이 겹쳐 읽을 수 없어 의미가 없음. 즉 줌아웃은 배율 1 에서 멈추고 그때 버튼을 흐리게 함.
  • 초기화 버튼은 남김 — 기본값(배율 1·자동 Y)으로 한 번에 되돌림. 버튼은 줌인·줌아웃·초기화 셋.
  • 세로는 보이는 구간에 자동 맞춤 — 가로 스크롤 위치와 화면 폭으로 지금 보이는 누가거리 구간을 알 수 있음. 그 구간의 지반선·계획선 최저~최고에 위아래 10% 여유를 두어 Y 창을 잡음. 확대할수록 그 구간의 고저차가 화면 높이를 꽉 채우므로 ⇕+·⇕−·· 네 버튼이 필요 없어짐.
  • 유토곡선도 같은 규칙 — 같은 구간의 누계 토량 최저~최고로 Y 를 잡음(지금은 전 구간 최대치 고정). 두 그림이 같은 스크롤을 쓰므로 창 계산은 한 벌이면 됨.
  • 보조 조작(선택)Ctrl+휠로 확대·축소, 그래프를 잡아끌어 좌우 이동. 버튼 2개는 그대로 두고 손에 익은 조작만 더하는 것이라 원하면 나중에 붙여도 됨.

조심할 것(미리 점검한 결과)

  • 가로 방식은 바꾸지 않음 — 캔버스 폭을 키우는 지금 방식을 유지해야 테이블·편집 버튼·구조물 레인이 그래프와 같이 늘어남. SVG 변형으로 바꾸면 넷이 어긋남.

  • 세로는 그래프 영역만 바뀜 — 테이블에는 영향 없음. 다만 스크롤할 때마다 축이 출렁이면 어지러움 → 스크롤이 멈춘 뒤 맞추고(짧은 지연), 눈금은 지금처럼 1·2·5 계열로 딱 떨어지게 스냅.

  • 편집 중에는 Y 고정 — 계획고를 끌어 올리는 동안 축까지 따라 움직이면 조작 감각이 깨짐. 손을 떼면 다시 맞춤.

  • B06 종단은 카드 공통 Y 스케일을 씀 — 측점 카드끼리 높이를 견주려고 같은 축을 쓰는 중임. 자동 맞춤으로 바꾸면 그 비교가 깨질 수 있음 → B06 은 자동 맞춤을 껐다 켤 수 있게 할지, B05 만 자동으로 둘지 사용자 확인.

  • 버튼 세 개로 줄이기 — 줌인·줌아웃·초기화만 남기고 세로 배율·창 이동 버튼 제거.

  • 축소 한계 = 기본값 — 배율 1 아래로 안 내려가게 막고, 한계에 닿으면 버튼을 흐리게 표시.

  • 세로 자동 맞춤 — 보이는 구간의 지반·계획선 범위 + 여유 10%, 스크롤이 멈춘 뒤(0.16초) 갱신, 눈금 스냅 유지. 창 계산은 공통 함수 한 벌(windowElevationRange)을 B05·B06 이 함께 씀.

  • 편집 중 축 고정 — 계획고 편집 버튼을 누르고 있는 동안 Y 창을 붙잡고 손을 떼면 다시 맞춤.

  • 유토곡선 Y 자동 — 같은 구간 기준으로 누계 토량 범위를 잡음(전 구간 ±200㎥ 고정 해제).

  • 정렬 확인 — 가로 배율을 바꿔도 그래프·테이블·편집 버튼·구조물 레인의 측점 위치가 어긋나지 않음.

  • B06 적용 범위 확인 — 사용자 답(2026-09-04): 「공통으로 템플릿화」. B05·B06 종단이 같은 규칙·같은 함수로 자동 맞춤. 확인 결과 카드 공통 Y 스케일 걱정은 근거가 없었음calculateYScale 이 먹이던 곳은 B06 종단 하나뿐이고 횡단 카드는 애초에 그 값을 안 씀. 그래서 그 함수는 지금 아무도 안 부름 (죽은 코드 정리 항목에 넘김 — 이번 차례 아님).

  • 자체검증(2026-09-04, 공용 브라우저 5174 · 프로젝트 용화_LAS, 사용자 지정) — 수치 판정.

    • ① 버튼 + · · ⤢ 셋만 남음. 배율 1 에서 disabled(흐림) — 확대 뒤 풀리고 초기화하면 다시 죽음. 합격
    • ② 보이는 구간의 지반·계획선이 그래프 높이의 83.1~83.3% 를 채움(여유 10%×2 를 뺀 이론값 83.3%). 배율 1·3배·스크롤 이동 어디서나 같은 값 — 눌리지 않음. 합격
    • ③ 스크롤을 옮기면 Y 눈금이 그 구간 값으로 바뀜(860880m → 835842m → 830~834m). 합격
    • ④ 같은 측점의 그래프 세로선과 편집 버튼 중심 x 차이 0.5px(버튼 폭 21px 의 절반 자리 보정값), 배율 2배에서도 0.5~0.52px 로 유지. 어긋남 없음. 합격
    • ⑤ 유토곡선 Y 가 창을 따라감 — 전 구간(8.8 ~ 185.1㎥) → 확대(4.3 ~ 89.3) → 스크롤 이동 (3,610 ~ −3,814). 전 구간 고정이던 이전과 달라짐. 합격
    • ⑥ 계획고 ▲ 를 3초 누르는 동안 계획선은 움직였는데(첫 4점 y 16.08/17.48/18.87/20.27 → 16.08/17.02/17.95/18.88) 눈금은 그대로(870m,880m). 손을 뗀 뒤 다시 맞춤. 합격
    • 가 배율 1 로 되돌림(캔버스 폭 7145px → 4615px, 다시 흐려짐). 합격
    • B06(횡단설계 페이지) 종단도 같은 결과 — 채움 83.3%, 스크롤 시 눈금 840850m → 830834m, 유토곡선 Y 도 창을 따라감. 합격
    • 계획 대비 차이 — (1) 보조 조작(Ctrl+휠·잡아끌기)은 「원하면 나중에」 항목이라 넣지 않음. (2) 유토곡선 Y 에서 0선 강제 포함을 뺌 — 창 안 값만으로 잡아야 확대 효과가 나옴. (3) 검증 중 만든 계획선 초안은 지우고 새로고침해 시험 전 상태로 되돌림(초안 0건 확인).

B03 파일 카드 미리보기 확대 — 한 행 전폭·모든 항목 표시 (2026-09-04 구현 완료 · 검증 대기)

사용자 지시(2026-09-04) — 「파일들의 정보를 구분하려고 완료 시 그림을 넣으려 함. 해당 요소의 한 행을 전부 쓰고 높이는 적당히 고정. 지금 없는 항목들도 최소한 뭐라도 보여줄 것 — 자료를 보고 쉽게 표현할 수 있는 것을 그냥 넣을 것. 포인트 클라우드는 대충이라도, 스냅샷을 찍는 셈. 나머지도 같음」. (지시에는 B02 로 적혔으나 B02 는 프로젝트 생성 폼뿐이고 파일 카드는 B03임 — B03 기준으로 잡음.)

  • 지금 상태 — 카드 미리보기는 2026-09-04 에 넣은 작은 SVG(100×60) 하나임(B03_FileInput_UI_Preview.ts). 지형 자료는 범위 사각형만, 계획노선은 솎은 선임. 부속 파일(shx·dbf·cpg·prj·tfw)은 그림이 아예 없음.

  • 라이다는 공짜에 가깝게 점 그림을 뽑을 수 있음 — 분석기가 분류 통계를 낼 때 이미 전 점을 청크로 훑고 있음(analyze_las_metadatachunk_iterator). 그 지나가는 길에 일정 간격으로 3~5천 점의 XY 만 주워 두면 파일을 다시 읽지 않고 탑뷰 점 그림이 나옴. 분류가 없어 훑지 않는 파일만 한 번 더 읽는데, 이때는 앞 몇 청크만 보고 끝냄.

  • GeoTIFF 는 조건부rasterio 로 이미 열고 있으므로 저해상 축소 읽기(128×128 안팎)로 흑백 썸네일을 만들 수 있음. 다만 오버뷰가 없는 큰 파일은 수 초가 걸릴 수 있어, 오버뷰가 있을 때만 만들고 없으면 지금처럼 범위 사각형만 둠(사용자 제약 「오래 걸리면 안 됨」).

  • 부속 파일은 그림 대신 값 — 자료 성격상 그릴 도형이 없음. 좌표계 이름(prj·route_prj), 속성 개수·레코드 수(dbf), 인코딩(cpg), 픽셀 크기·회전 여부(tfw), 도형 개수(shx) 처럼 한눈에 구분되는 값 한두 개를 큰 글씨로 보여 줌.

  • 자리·크기 — 미리보기가 카드 한 행 전폭, 높이 120px 고정.

  • 라이다 점 그림 — 분류 통계를 훑는 그 길에 XY 를 성기게 주움(상한 5천 점, 1m 눈금 정수, 파일 재열람 없음). 분류가 없는 파일은 앞 3청크만 봄.

  • GeoTIFF 썸네일 — 오버뷰가 있을 때만 128×128 흑백 PNG(2~98 백분위로 대비), 없으면 범위 사각형 유지.

  • 부속 파일 값 표시.shx 도형 수, .dbf 레코드·속성 수, .cpg 인코딩, .prj 좌표계 이름+EPSG, .tfw 픽셀 크기·회전 여부. 값 읽기용 가벼운 분석기(dbf·shx·cpg)를 새로 둠(머리글만 읽음).

  • 완료 상태에서만 — 업로드·분석이 끝난 카드에만 보이고, 값이 없으면 「보여 줄 값이 없음」 한 줄.

  • 자체검증 (2026-09-04, 검증 대기) — 공용 브라우저(5173) · 프로젝트 용화_LAS 실측 + 단위 시험.

    • 결과 ① 카드 9장 모두 미리보기 폭 308px(카드 343px 안쪽 여백 뺀 전폭)·높이 120px 고정.
    • 결과 ② 라이다 카드에 점 5,000개가 그려지고, 표본 400점이 100% 자기 범위 사각형 안에 들어옴(툴팁 「점 5,000개 (솎은 탑뷰)」).
    • 결과 ③ 4,900만 점 LAS 분석: 분류 통계만 2.96s → 점 수집 포함 3.56s(+0.61s, 한 번 훑기 그대로). GeoTIFF 썸네일 0.1s(13.6KB), 부속 파일 각 0.0~0.4s.
    • 결과 ④ 부속 파일 카드가 각각 「도형 1개」·「레코드 1개 / 속성 2개」·「인코딩 949」·「Korean 1985 / Modified East Belt (EPSG:5176)」·「픽셀 0.2×0.2 m / 회전 없음」을 보임 — 빈칸 없음.
    • 계획 대비 차이 — 기존 업로드분은 옛 메타데이터라 미리보기 재료가 없어, 검증용으로 용화_LAS 입력 파일의 메타데이터를 다시 분석해 새 키만 병합했음(재업로드하면 같은 값). 다른 프로젝트는 다시 올릴 때 채워짐.