diff --git a/docs/raw/조사/2026-10-18_419_요구254_추천엔진.md b/docs/raw/조사/2026-10-18_419_요구254_추천엔진.md new file mode 100644 index 000000000..9033b4cfe --- /dev/null +++ b/docs/raw/조사/2026-10-18_419_요구254_추천엔진.md @@ -0,0 +1,69 @@ +# 요구 254 — 노선 추천 엔진 · 추천 창 상세 설계 + +분석 = 브레인 + 클로드 에이전트 둘(Opus 5.5 · 읽기 전용 · 시제품은 scratchpad). 앞 분석 = `2026-10-18_412_요구253_분석.md` 1 · 2 · 4장. + +## 1. 사용자 확정(254) + +- 곡선 수 줄이기는 노선 추천 안의 기능 — 사용자 옵션 아님. +- 종단 포함 계산 · 추천 창 「측점 맞춤」 단추 → 「종단 반영」 단추 · 측점 맞춤은 필수. +- 오른쪽 [재계산] = 영구저장소의 그 결과를 지우고 다시 만듦(덮어쓰기 아님). +- 토공 = 측점별 횡단 기준(종단 기준 아님). +- 「노선 추천」 칸 [초기화] 지움 · 아래 [초기화] 기준 = 사용자가 추천으로 [적용]한 노선(바꾸면 그것) → PLAN 418. + +## 2. 지금 사실(코드) + +- 측점 맞춤: 엔진은 이미 늘 맞춤(`B05_Profile_Engine_RouteInitial_Pool.py:113-120, 161` · `B05_Profile_Engine_RouteInitial.py:323-336`) · 창 「측점 맞춤」 = 맞추기 전 선 보기 전환만(`B05_Profile_UI_RouteEdit_Recommend.ts:151-154, 310-316` · 서버로 가는 것 없음). +- 종단 반영: 창에 단추 없음 · 갈래로 정함(follow 끔 · 나머지 켬 · `B05_Profile_UI_RouteEdit_Initial_Model.ts:31`) · 켬 = 균형 종단(`B05_Profile_Engine_RouteInitial_Profile.py`) — 20 m 마다 **공식 횡단 엔진**(`B06_Section_Engine_Design.py:179` `compute_cross_design` · [저장] 정본과 같은 파이썬) 단면적 → 동적 계획 종단 · 평균단면법 토량 · 후보마다 빠른 판 · 고른 것만 정밀. +- 띠 가늠(노폭 4 m · 비탈 뺌 · 종단 기준)이 남은 곳: 결과 표 절 · 성 값(`Initial_Model.ts:321-322` ← `Metrics.py:224-240`) · 종단 끔 점수 · 합치기 판정(`Merge.py:246-254`) · 탐색 · 국소 잼 · 공사비 어림 — 이 지형에서 실제 횡단 토량보다 5~10배 작음(검증_sub4 · 같은 선 띠 3,941 ㎥ 대 균형 종단 횡단 21,577 ㎥) · 순위가 뒤집히기도 함. +- 공식 엔진 비용: 한 번 2~5 ms · 노선 전체(60 측점) 0.4 s · 균형 종단 빠른 판 2.8 s · 정밀 5.6 s · 추천 지형(2 m)과 공식 지형(1 m) 차 +5.8 %. +- 균형 종단이 프로젝트에 저장된 표준단면 패널값 대신 설정 기본값을 씀(`Profile.py:175-182` · 공식은 `B06_Section_Server_Calc_Prebuild.py:269`). +- [적용] 뒤 종단 = 추천과 같은 균형 종단(1 m 지형) · 종단 끔이면 계획고 = 지반고. +- [재계산] = 바뀐 것 있을 때만 켜짐 · 같은 입력이면 저장본을 돌려줌(`Recommend.ts:401` · `Router_RouteInitial.py:128-131`) · 저장본은 덮어쓰지 않고 판(`ALGO_VERSION`)이 다르면 안 읽음 · 옛 판 파일이 남음. + +## 3. 곡선 수와 토공이 이어지는 까닭(사용자 물음 1) + +- 이 산지에서 곡선이 많은 까닭 = 노선이 등고선을 따라 굽이굽이 돌기 때문. +- 곡선을 합쳐 줄이면 노선이 곧아져 비탈을 가로지름 → 깎기 · 쌓기가 커짐(시제품: 곡선 33 → 20 이면 절성토 +10 %). +- 그래서 「얼마나 합칠지」를 엔진 안에서 토공 증가 한도로 멈춰야 함 — **사용자 옵션 아님 · 엔진 안 상수**. + +## 4. 설계(브레인 정함 · 바꿀 수 있음) + +엔진(추천만 · 손 편집 · 공용 선 짜기 짝 안 바뀜): +- 원지반 기울기 = 참고만: + - 후보 거름 · `_trace` 판 고르기 · 큰 R · 합치기 · 측점 맞춤의 원지반 기울기 막기를 걷음. + - 위반 수 = R · 계류 · 측점만. + - 탐색 링크 상한은 남김(비탈 곧장 오르는 길 막이). + - 시종점이 상한을 넘으면 화면에 알림. +- 토공 = 측점별 공식 횡단: + - 후보 줄 세움 = 모든 후보를 「상한 누른 계획선」 횡단으로(후보당 0.4 s) → 위 3개만 균형 종단 빠른 판 → 고른 하나 정밀. + - 합치기 판정 = 바뀐 측점(3~6개)만 횡단 차이로 셈. + - 국소 잼(수십만 번)은 띠 가늠 그대로 — 엔진 안 빠른 거름일 뿐. + - 결과 표 절 · 성 = 횡단 값. + - 표준단면 = 프로젝트 저장 패널값. +- 종단 반영 끔 = 계획고 = 지반고로 횡단 토공([적용] 뒤 값과 같음). +- 곡선 합치기 멈춤 = 노선 전체 횡단 토공 증가 ≤ +10 %(엔진 상수 · 사용자 옵션 아님). +- 삼각(R 없는 교점) 없음 = 내각 155° 이상도 곡선 둠(09-07 사용자 「곡선은 늘 둠」) · 못 두면 교점 지움(곧게) · MC = 일반측점 필수(측점 밖 0 목표). +- 맞추기 전 선(`raw` · `unsnapped`) 걷음. +- 판: `ALGO_VERSION` 8 · 엔진 소스 지문을 열쇠에 더함(손으로 올리기 빠뜨려도 새로 셈) · 옛 판 · 옛 지문 저장본은 미리 셈 때 지움. +- 시간 예산 = 첫 갈래 지금 + 20 s 안. + +추천 창(B05 노선 추천 모달): +- 「측점 맞춤」 단추 지움 → 그 자리에 「종단 반영」 단추(기본 켬 · 다섯 갈래 모두) · 누르면 바로 다시 보임(저장본 있으면 그것). +- [적용] 때 균형 종단 = 이 단추 값 · `initial_choice.json` 에 `with_profile` 저장 · 다시 열면 되살림. +- 미리 셈 = 종단 켬 기본 다섯 갈래. +- [재계산] = 늘 켜짐(입력 오류 · 셈 중 빼고): + - 지금 입력의 저장본(다섯 갈래 같은 후보 묶음)을 지우고 메모리 후보 묶음도 버린 뒤 새로 셈. + - 지우기는 묶음 잠금 안에서(미리 셈과 겹침 막이). + - 진행 줄은 지금 것. + - [적용]한 노선 · 초기값 층은 안 건드림. +- 도움말 글 = 측점 맞춤 필수 · 종단 반영 · 재계산 뜻으로. + +## 5. 나눔 + +| 절 | 일 | 창 | 파일 경계 | +|---|---|---|---| +| 419 | 원지반 기울기 참고만 · 삼각 없음 · 측점 필수 · raw 걷음 · 합치기 판정 = 횡단 차이(420 함수 부름) · 후보 줄 세움 | sub4 | Pool · Merge · Station · Radius · Search · Engine(RouteInitial.py) | +| 420 | 횡단 토공 함수(새 `B05_Profile_Engine_RouteInitial_CrossEarth.py`) · 균형 종단 표준단면 = 저장 패널값 · 결과 절 · 성 = 횡단 · 판 8 + 소스 지문 · 옛 저장본 정리 · [재계산] 서버(요청 `recompute` · 잠금 안 지움 · `_POOLS` 버림) · `initial_choice` with_profile · 미리 셈 종단 켬 | sub2 | Profile · Metrics · Store · Router_RouteInitial · Schema · Replan(initial_choice) | +| 421 | 추천 창 단추(측점 맞춤 → 종단 반영) · [재계산] 늘 켜짐 + recompute · [적용] with_profile · 도움말 · unsnapped 화면 걷음 | sub1(418 뒤 이어) | Recommend.ts · Initial.ts · Initial_Model.ts · Recommend_Help.ts · Api_RouteInitial.ts | + +- 420 함수 이름 · 모양을 먼저 정함: `cross_earthwork(line, chainages, design_z | None, terrain, standard) -> {cut, fill, per_station}` · `cross_earthwork_delta(before, after, changed_chainages, …)` — 419 는 이 이름으로 부르고, 420 이 올리기 전엔 지금 띠 가늠으로 둠.