한 줄을 결과와 같이 쓰다 보니 분석을 돌릴 때마다 직전 결과가 지워졌다. 진행 문구는
우상단, 결과는 좌상단에 남겨 둘 다 동시에 읽을 수 있게 했다(2026-08-01 사용자 지시).
- WatershedOverlay에 busyElement(진행 전용)를 추가하고 sayBusy()로 갱신한다.
결과·오류는 종전대로 statusElement(좌상단)에 쓴다.
- 분석이 끝나면 진행 문구를 거둔다.
- 지도에 .b04-map__status-topright 자리를 신설했다. 객체 개수는 우하단
(.b04-map__status-corner), 유역 결과·흐름 강도 요약은 좌상단 그대로다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
흐름 강도 계산은 이미 trace_flow()가 원본 1m 격자에서 하고 있었고 03_road_routing.npz에
저장까지 되어 있었다. 이번 작업은 그 원본값을 밖으로 꺼내 화면에 그리는 것이다.
- 강도 곡선 출력 간격을 5m -> 1m로 바꿔 계산 원본을 그대로 내보낸다(구간 합, 평균 아님).
구간 기준을 round -> floor로 바로잡았다. 도로 셀 누가거리가 전부 0.5 배수라
numpy의 짝수 반올림이 짝수 칸에 3배를 몰아 2m 주기 빗살을 만들고 있었다
(도로가 격자축과 나란한 구간은 홀수 칸이 전부 0이라 색이 점선으로 나왔다).
- find_inflow_hotspots(): 도로를 시점·기본 관(세류 교차)·종점으로 잘라 구역을 만들고
구역마다 floor(길이 / 관 최대간격) + 3개를 뽑는다. 강도 최대점부터 고르되 고른 지점
양 편측으로 관 최소간격만큼을 후보에서 빼 한쪽 쏠림을 막는다. 관 쪽 경계에서도 같은
거리만큼 물러난다 - 그러지 않으면 그 관이 이미 받는 물 전부가 관 옆 칸에서 다시
최대값으로 잡혀, 정작 관이 없어 보충이 필요한 자리가 뽑히지 못한다.
- GET /api/projects/{id}/drainage/road-inflow 신설(B04_wf1_Surface_Router_Inflow.py).
저장된 road_slot으로 그 1m 구간에 귀속된 셀 마스크를 만들어 외곽선만 돌려준다.
새 그래프 탐색 없음. npz는 mtime 키로 프로세스 캐시에 둔다.
- 응답에 schema_version을 넣어 형식이 바뀌면 옛 저장분을 무시하고 다시 계산하게 했다.
- 프론트: B04_wf1_Surface_UI_FlowStrength.ts 신설. 계획선 위에 1m 구간 로그 레인보우와
유입 집중점 마커(크기=강도, 번호)를 얹고, 마커를 고르면 기여 셀 외곽선을 겹쳐 그린다.
마커 안쪽만 선택 대상이며 팬은 가운데 버튼 전용이라는 규칙은 그대로 둔다.
좌표 변환은 MapRender에 모았다(normalizedToScreen / lonLatToScreen / metricToScreen).
- 사이드 패널: 지면 필터·서피스·스무딩을 "지표면 분석" 한 컨테이너로 모으고 스무딩을
드롭다운(적용/미적용)으로 바꿨다. 포인트·모델 표시 옵션은 "모델 표시 옵션" 하나로
합치고 맨 아래에 점 크기·밀도를 [값][게이지] 형태로 놓았다.
- DRAINAGE_ROAD_WIDTH_M 주석에 설계 도로폭이 아니라 D8 대각 통과를 막는 해석용 굽기
폭임을 명시했다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- ui_template_theme.css에 2D 지도 벡터 팔레트(--map-*) 33종을 유일한 정의처로 등록하고,
캔버스에서 CSS 변수를 읽는 공통 유틸 ui_template_palette.ts(themeColor)를 신설.
값은 한 번만 읽어 캐시하고 data-theme 변경 시 비운다(다크 전환 대응).
- B04 지도·유역 오버레이·흐름 화살표와 B05 배수유역도·유역선 편집·배관 마커의
하드코딩 색상을 전부 토큰 조회로 교체. 계획선 색·굵기, 후광색은 공용 함수로 일원화.
- B05 배수유역 패널의 사용자 문구를 전부 ui_locales로 이관(제목, 레이어 토글 5종,
도구 버튼 5종, 툴팁, 상태 문구 8종, 유역 제원 표기). B04 유역 분석 오버레이의
버튼·갈래 토글·진행/실패 안내도 함께 전환. 관리자 진단용 결과 판독문은 원문 유지.
- A02 프로그램 소개의 6단계 제목과 A01 히어로 문구의 단계 나열을 진행단계 이름
(전처리/종단설계/횡단설계/상세설계/수량산출/설계도서)과 일치시킴.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 사용자 지정 기본값을 한곳(BACKGROUND_DEFAULT_ON / GIS_DEFAULT_ON /
CONTOUR_LABEL_DEFAULT_ON)에 모아 정의한다.
- 켜짐: 백지도, 위성, 시군구, 읍면동, 세류(전체)
- 꺼짐: 하이브리드, 연속지적도, 등고선, 도엽등고선, 표고점, 성절토, 옹벽석축, 등고라벨
- 유수방향 레이어는 화면에서 제외(목록에서 삭제)
- 명칭: 세류(하천중심선) -> 세류(전체), 배수유역 재산정 -> 유역 분석
- 유역 갈래 기본값(1차 꺼짐 / 2차 켜짐 / 유역방향 꺼짐 / 평균흐름 켜짐)은 기존과 동일
- B05 배수유역도 초기 보기는 도로 기준 줌인으로 되돌림(B04 하단 지도는 배경 전체 보기 유지)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
저장분을 자동 표시하도록 바꾼 뒤로 진입 시 shown=true가 되어, 재산정 버튼을 누르면
분석 요청 없이 오버레이만 숨겨졌다(사용자 눈에는 무응답). 버튼은 언제나 재산정을
실행하도록 하고, 보이기/숨기기는 갈래별 버튼(1차/2차/유역방향/평균흐름)이 맡는다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
증상 두 가지
1. 재산정 버튼을 눌러도 프론트에 아무 안내가 없었다.
오버레이가 지도 자체 상태(.b04-map__status)에 문구를 썼는데,
loadLayers 가 같은 칸에 3곳에서 덮어써 즉시 지워졌다.
2. 페이지 접근 시 배수유역이 안 보였다.
응답 캐시 파일(00_watershed_response.json)이 아직 없어 자동 조회가
빈 손으로 끝나는데, 그 사실을 화면에 알리지 않아 이유를 알 수 없었다.
조치
- 배수유역 전용 상태 줄(.b04-map__watershed-status)을 컨트롤 영역에 따로 둔다.
지도 로딩 문구와 서로 덮어쓰지 않는다.
- 컨트롤에 배수유역 그룹을 만들어 재산정 버튼 + 갈래 토글 4종 + 상태 줄을 묶었다.
- 진행 상태를 버튼 라벨에도 반영: 배수유역 재산정 -> 분석 중… / 불러오는 중…
- 결과 문구에 출처와 소요를 붙인다: [저장분] ... / [재산정 28.4초] ...
- 저장분이 없으면 오류가 아니라 안내로 표시:
"저장된 배수유역 분석이 없습니다. [배수유역 재산정]을 누르세요."
- 실패하면 버튼 활성 상태를 되돌려 껐다 켠 것처럼 보이지 않게 했다.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1. 재산정하지 않는 한 저장분을 그대로 쓴다
GET /drainage/primary-region 이 기본으로 영구저장소의 응답 캐시를
그대로 돌려준다(0.0004s). refresh=true 일 때만 다시 계산한다.
저장 배열에서 응답을 재조립하지 않고 **응답 자체**를 남긴다 —
재조립하면 원본과 어긋날 여지가 생긴다.
버튼 이름 배수유역 -> 배수유역 재산정. 지도를 열면 저장분이 자동으로 뜬다.
2. B05용 평균 흐름 화살표 (build_flow_arrows)
셀 화살표는 1m 라 도면 배율에서 경향이 안 보인다. 겹치지 않는 10m 블록으로
나눠 방향을 원형 평균하고, 40m 간격으로 솎아낸다.
- 세류선 셀과 도로 셀은 뺀다. 그 자리는 확정된 물길/노면을 따르는 값이라
사면 경향을 왜곡한다.
- 산술평균이 아니라 원형 평균(0도와 359도의 평균은 180도가 아니다).
평균 벡터 길이가 방향 일치도이므로 0.7 미만이면 그 블록은 버린다.
- 블록 유효 셀이 절반 미만이면 건너뛴다(가장자리 조각 방지).
실데이터 377개, 간격 40m 균일, 블록당 평균 98셀, 적 278 / 청 99.
config: ARROW_BLOCK_M / ARROW_SPACING_M / ARROW_MIN_COVERAGE / ARROW_MIN_AGREEMENT
3. 갈래별 하이드/쇼 버튼 4종
1차 유역 / 2차 유역 / 유역 방향 / 평균 흐름.
평균 화살표는 B04 에도 올려 형태를 확인할 수 있게 했다.
4. B05 는 페이지 진입 즉시 유역도를 올린다
B04 결과를 읽기만 해 0.1초면 끝나므로 버튼을 기다릴 이유가 없다.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
화살표가 안 보이던 문제
1m 격자를 도엽 전체 배율로 보면 셀이 1~2px 다. 줌 상한이 8배라 셀이
화살표 최소 크기(7px)에 절대 못 미쳐 채움색만 보였다.
-> 셀마다 그리지 않고 화면상 약 22px 간격이 되도록 건너뛰며 표본만 그린다.
화살표 크기는 그 간격에 맞춰 커진다. 흐름장을 읽는 표준 방식이다.
-> 채움색 위에서도 읽히도록 흰 테두리를 한 겹 깔고 그 위에 그린다.
갈래별 토글 버튼 추가 (1차 유역 / 2차 유역 / 유역 방향)
GIS 버튼 줄에 배수유역 전체 토글 옆으로 붙는다. 전체 토글이 꺼져 있으면
갈래 설정과 무관하게 아무것도 그리지 않는다.
그리는 순서는 유역방향(격자/화살표) -> 1차 유역 -> 2차 유역/관.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
분석은 돌고 상태 문구도 나오는데 지도에는 아무것도 안 보였다.
원인: 프레임 함수 이름이 draw() 가 아니라 drawVectorLayer() 라
오버레이 draw 호출을 끼워 넣는 치환이 조용히 실패했다. 호출 자체가
소스에 없었다.
- drawVectorLayer() 안, GIS 레이어와 등고 라벨 뒤에 오버레이 draw 삽입.
격자/화살표가 등고선을 덮어야 읽히므로 맨 위에 얹는다.
- drawPrimaryRegion 이 drawGridCells 를 한 번 더 부르던 중복 제거
(draw 체인이 이미 먼저 호출한다).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
분석이 30초 걸리는데 B05는 일반 사용자 화면이다. 관리자 확인용 B04에서
한 번 돌려 저장하고, B05는 그 결과를 읽어 관 보충과 세부유역만 처리한다
(2026-07-31 사용자 지시).
노선 원천 변경
- B05 확정 경로 -> B03 업로드 계획 노선 파일(CSV). 분석이 노선 설계보다
먼저 끝나 있어야 하기 때문. 샘플 planned_route_sample_epsg5187.csv 로 검증.
- common_util_route_geometry.py 신설 — RouteVertex/StructureCandidate/누가거리
보간/세류 교차점/계획 노선 CSV 리더. B04와 B05가 같은 표현을 쓰도록 공용화.
열 이름은 대소문자·한글 표기를 함께 받는다(B03이 여러 형식 수용 예정).
B04 (관리자 확인용, 신규)
- Engine_Watershed_{Grid,Stream,Descent,Flow,Expand,Export} — B05에서 git mv
- Engine_Watershed_Analyze.py — 1~8단계 오케스트레이션
- Router_Watershed.py — GET /drainage/primary-region
- UI_Watershed.ts — 2D 지도 GIS 레이어 그룹에 "배수유역" 토글 추가.
격자/화살표/세류망/1차영역/2차유역/기본관을 겹쳐 그린다.
- 저장 위치 B05_wf2_Route/drainage -> B04_wf1_Surface/drainage
- 03_road_routing 단계 추가: B05가 세부유역을 나눌 최소 배열(셀->도로셀 귀속,
유하장, 강도, 도로셀 제원, 셀 표고) + 계획도로선/기본배관/2차유역 기하
B05 (일반 사용자용, 축소)
- Engine_Drainage_Basin.py — B04 산출물 로더 + 관 보충(9) + 측구 라우팅/세부유역(10,11)
- Engine_Drainage.py 는 관경 산정만 남기고 322 -> 27줄
- Router_Drainage.py 509 -> 142줄. POST /drainage/basins 만 남김
- 화살표·격자·강도 띠 렌더 제거. 계획도로선/기본배관/2차유역만 받는다
삭제
- _legacy_watershed/ 4파일 (능선 행진 방식 원본 보관본)
- Engine_Watershed_Basin.py (B04 Analyze + B05 Drainage_Basin 으로 분할)
- GET /drainage/candidates 와 propose_structure_stations (구방식 후보 제안)
E2E 검증 (실데이터)
B04 분석 28.2s -> 저장(geojson 11KB + npz 2.6MB)
B05 로드 + 세부 설계 0.11s <-- 30초가 0.1초로
면적 457,404m2 로 B04 2차 유역과 정확히 일치
관 편집 재산정 0.12s, 관 3개 -> 세부유역 3개, 면적 보존
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>