feat(B05): 노선 추천 종단 반영 켜기·끄기 + 갈래 설명 한 쪽씩 넘기기

- 64-1: 추천 창 「종단 반영」 체크(기본 켬) — 요청 with_profile 로 서버가 가름 · 끄면 원지반만(63-4 전 점수) · 묶음 캐시에 남은 종단은 걷어 냄 · 값은 편집 창 안에서만(저장 안 함)
- 64-2: 설명 칸을 갈래 한 쪽씩 ◀ ▶ + 「n / 8」 · 고른 갈래 쪽부터 · 토공 최소 · 공사비 어림 최소 쪽에 종단 반영 설명 추가
- 시험: test_64_1_profile_toggle.py · ui_checks 64-1 · 64-2

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016PSXsvyDxjNmufteN5bqmt
This commit is contained in:
2026-10-06 23:14:14 +09:00
co-authored by Claude Sonnet 5.5
parent d42efb162b
commit 89433a352d
13 changed files with 309 additions and 34 deletions
@@ -36,7 +36,7 @@ from B05_Profile.B05_Profile_Engine_RouteInitial_Metrics import (
COST_EARTH_M3,
COST_LENGTH_M,
)
from B05_Profile.B05_Profile_Engine_RouteInitial_Profile import profile_earth
from B05_Profile.B05_Profile_Engine_RouteInitial_Profile import plain_metrics, profile_earth
from B05_Profile.B05_Profile_Engine_RouteInitial_Search import (
CROSSING_BAND,
OBJECTIVES,
@@ -213,12 +213,15 @@ def build_pool(
return pool
def similar(pool: Pool, mode: str, outline: Any) -> list[dict[str, Any]]:
def similar(pool: Pool, mode: str, outline: Any, with_profile: bool = True) -> list[dict[str, Any]]:
"""이 노선과 `SIMILAR_M` 안인 다른 갈래 — 갈래 이름 · 가장 먼 거리(m).
화면이 「이 지형은 제약 안에서 갈 길이 한 띠뿐 · ○○ 과 거의 같은 노선」을 알리는 데 쓴다."""
here = LineString(outline.vertices)
others = {"follow": pool.follow, **{name: pick(name, pool.candidates) for name in GOALS}}
others = {
"follow": pool.follow,
**{name: pick(name, pool.candidates, with_profile) for name in GOALS},
}
found = []
for name, (other, _) in others.items():
if name == mode or other is None:
@@ -284,7 +287,9 @@ GOALS: dict[str, Callable[[dict[str, Any]], tuple[float, ...]]] = {
}
def pick(mode: str, candidates: list[Route]) -> Route:
"""갈래 목표 비교값이 가장 좋은 후보. 같으면 앞 후보."""
def pick(mode: str, candidates: list[Route], with_profile: bool = True) -> Route:
"""갈래 목표 비교값이 가장 좋은 후보. 같으면 앞 후보. `with_profile` 끔 = 원지반 가늠 점수."""
goal = GOALS[mode]
return min(candidates, key=lambda item: goal(item[1]))
return min(
candidates, key=lambda item: goal(item[1] if with_profile else plain_metrics(item[1]))
)