feat(B04): 도로 유입 흐름 강도 표시 + 유입 집중점 마커, 사이드 패널 컨테이너 정리
흐름 강도 계산은 이미 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>
This commit is contained in:
@@ -615,8 +615,22 @@ export const ui_locales = {
|
||||
B04_Surface_Title: ["전처리", "Preprocess"],
|
||||
B04_Surface_Field_InputId: ["입력 파일 ID", "Input File ID"],
|
||||
B04_Surface_Field_InputId_Placeholder: ["예: 1", "e.g. 1"],
|
||||
B04_Surface_Group_Filters: ["지면 필터 선택", "Ground Filters"],
|
||||
B04_Surface_Group_Methods: ["지표면 표현 선택", "Surface Methods"],
|
||||
/* 지면 필터·서피스·스무딩은 함께 모델 하나를 결정하는 값이라 한 컨테이너에 둔다
|
||||
(2026-08-01 사용자 지시). 그래서 예전 그룹 제목 대신 항목 라벨로 쓴다. */
|
||||
B04_Surface_Group_Analysis: ["지표면 분석", "Surface Analysis"],
|
||||
B04_Surface_Group_Filters: ["지면 필터", "Ground filter"],
|
||||
B04_Surface_Group_Methods: ["서피스", "Surface"],
|
||||
B04_Surface_Group_Display: ["모델 표시 옵션", "Model display options"],
|
||||
B04_Surface_Group_ViewControls: ["뷰어 시점 제어", "Viewer camera"],
|
||||
B04_Surface_Field_Smoothing: ["스무딩", "Smoothing"],
|
||||
B04_Surface_Smoothing_On: ["적용", "On"],
|
||||
B04_Surface_Smoothing_Off: ["미적용", "Off"],
|
||||
B04_Surface_Smoothing_Unsupported: [
|
||||
"이 지표면 표현은 스무딩을 지원하지 않습니다.",
|
||||
"This surface method does not support smoothing.",
|
||||
],
|
||||
B04_Surface_Opt_PointSize: ["점 크기", "Point size"],
|
||||
B04_Surface_Opt_Density: ["밀도", "Density"],
|
||||
B04_Surface_Field_Force: ["기존 결과 무시하고 재계산", "Force recompute"],
|
||||
B04_Surface_Btn_Analyze: ["지표면 분석 실행", "Run Surface Analysis"],
|
||||
B04_Surface_Btn_Refresh: ["목록 새로고침", "Refresh"],
|
||||
@@ -689,6 +703,22 @@ export const ui_locales = {
|
||||
B04_Surface_Watershed_Origin_Cached: ["저장분", "Cached"],
|
||||
/* {seconds}=재산정에 걸린 시간(초) */
|
||||
B04_Surface_Watershed_Origin_Recomputed: ["재산정 {seconds}초", "Recomputed in {seconds}s"],
|
||||
/* 도로 유입 흐름 강도 */
|
||||
B04_Surface_Flow_Strength: ["흐름 강도", "Flow strength"],
|
||||
B04_Surface_Flow_Strength_Tip: [
|
||||
"도로 1m 구간마다 그 자리로 모이는 상류 면적을 색으로 칠하고, 물이 특히 많이 모이는 자리를 마커로 찍습니다. 마커를 누르면 그 지점으로 들어오는 셀들의 외곽선을 보여 줍니다.",
|
||||
"Colors each 1m stretch of road by the upstream area draining into it, and marks the spots that collect the most. Click a marker to outline the cells that drain into it.",
|
||||
],
|
||||
B04_Surface_Flow_Inflow_Loading: ["유입 셀을 불러오는 중…", "Loading the contributing cells…"],
|
||||
/* {index}=마커 번호, {chainage}=누가거리, {area}=유입면적, {cells}=셀 수, {path}=최장 유하장 */
|
||||
B04_Surface_Flow_Inflow_Summary: [
|
||||
"유입 집중점 {index} · 측점 {chainage}m — 유입면적 {area} · 셀 {cells}개 · 최장 유하장 {path}m",
|
||||
"Hotspot {index} · Station {chainage}m — Area {area} · {cells} cells · Longest path {path}m",
|
||||
],
|
||||
B04_Surface_Flow_Inflow_Failed: [
|
||||
"유입 셀을 불러오지 못했습니다.",
|
||||
"Failed to load the contributing cells.",
|
||||
],
|
||||
B04_Surface_Map_PlannedRouteEmpty: [
|
||||
"B03에서 계획노선 파일을 올리면 표시됩니다.",
|
||||
"Shown after the planned route file is uploaded in B03.",
|
||||
|
||||
@@ -234,6 +234,16 @@
|
||||
--map-flow-away-arrow: rgba(30, 64, 175, 0.95);
|
||||
--map-flow-unknown-fill: rgba(120, 113, 108, 0.18); /* 표고가 없어 판정 못한 셀 */
|
||||
|
||||
/* 도로 유입 흐름 강도 색띠 — 적음(파랑) → 많음(빨강). 로그 스케일로 보간한다.
|
||||
보간을 하려면 hex여야 한다(rgba/색이름 금지). */
|
||||
--map-flow-ramp-0: #2563eb;
|
||||
--map-flow-ramp-1: #06b6d4;
|
||||
--map-flow-ramp-2: #22c55e;
|
||||
--map-flow-ramp-3: #eab308;
|
||||
--map-flow-ramp-4: #f97316;
|
||||
--map-flow-ramp-5: #dc2626;
|
||||
--map-inflow-outline: #dc2626; /* 선택한 지점으로 들어오는 셀들의 외곽선 */
|
||||
|
||||
/* 유역 채움 파스텔 8종 — 유역 번호 순으로 돌려쓴다(사용자 지시: 파스텔톤).
|
||||
알파 0.45는 비선택 유역을 0.18로 낮출 때 문자열로 치환하므로 형식을 바꾸지 말 것. */
|
||||
--map-basin-1: rgba(167, 216, 199, 0.45);
|
||||
|
||||
Reference in New Issue
Block a user