feat(B05): 계획노선 초기 폴리라인을 자동설계 체인에서 세움
PLAN 0-10. 그동안은 화면이 route/plan 을 처음 부를 때 만들어져, 화면을 안 열면 값이 없었음 — 초기값은 서버가 낸다는 0-4 원칙과 어긋났음. - 파일입력 자동설계 체인이 예상노선 정본을 남긴 직후(2.6단계) 초기 폴리라인도 세움. 실패는 비치명적 — 없으면 화면이 처음 열릴 때 만들어짐. - _ensure_planned_initial 이 **낡음도 본다** — 예상노선 파일이 더 나중에 쓰였으면 다시 만듦. 파일을 다시 올리면 예상노선이 새로 깔리는데 초기본이 옛 노선인 채로 남으면 노선 초기화가 옛 자리로 돌아갔음. 자체검증 — 예상노선 파일 시각을 최신으로 만든 뒤 route/plan 을 부르니 초기 폴리라인이 다시 만들어짐(노드 28 · 곡선 13 그대로). 시험 409 통과·17 건너뜀. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -205,6 +205,12 @@ async def run_auto_design_chain(
|
||||
if not expected_path.is_file():
|
||||
write_route_csv(expected_path, points)
|
||||
|
||||
# 2.6) 계획노선 **초기 폴리라인**도 여기서 세운다(2026-09-06 PLAN 0-10).
|
||||
# 예상노선은 점 묶음이라 그대로는 설계선이 못 된다 — 지식DB 의 R 기준으로
|
||||
# 곡선을 끼운 폴리라인이 불변 초기 데이터다. 화면이 처음 열릴 때 만들면
|
||||
# 「화면을 안 열면 값이 없다」가 되므로 초기값은 서버가 낸다(0-4 원칙).
|
||||
await _ensure_initial_polyline(project_id, project_root, points)
|
||||
|
||||
# 3) B05 경로 계산
|
||||
request = RouteSolveRequest(
|
||||
filter_key=str(defaults["source_filter"]),
|
||||
@@ -327,6 +333,30 @@ async def run_auto_design_chain(
|
||||
clear_designing(project_root)
|
||||
|
||||
|
||||
async def _ensure_initial_polyline(
|
||||
project_id: UUID, project_root: Path, points: list[dict[str, float]]
|
||||
) -> None:
|
||||
"""계획노선 초기 폴리라인을 세운다 — 이미 있으면 그대로 둔다. 실패는 비치명적."""
|
||||
import asyncio
|
||||
|
||||
from B05_Profile.B05_Profile_Router_Replan import _ensure_planned_initial, _min_plan_radius_m
|
||||
|
||||
try:
|
||||
radius_m = await _min_plan_radius_m(project_id)
|
||||
summary = await asyncio.to_thread(_ensure_planned_initial, project_root, radius_m)
|
||||
if summary:
|
||||
logger.info(
|
||||
"초기 계획노선 폴리라인: project_id=%s 노드 %d · 곡선 %d · 위반 %d (R %.1fm)",
|
||||
project_id,
|
||||
summary["nodes"],
|
||||
summary["curves"],
|
||||
summary["violations"],
|
||||
radius_m,
|
||||
)
|
||||
except Exception: # noqa: BLE001 — 없으면 화면이 처음 열릴 때 만든다
|
||||
logger.exception("초기 계획노선 폴리라인 생성 실패(계속 진행): %s", project_id)
|
||||
|
||||
|
||||
async def run_redesign_chain(
|
||||
project_id: UUID,
|
||||
surface_model_id: int,
|
||||
|
||||
@@ -175,11 +175,18 @@ def _write_planned_polyline(path: Path, points: list[tuple[float, float]], radiu
|
||||
|
||||
|
||||
def _ensure_planned_initial(project_root: Path, radius_m: float) -> dict | None:
|
||||
"""계획노선 **초기 폴리라인**이 없으면 예상노선을 폴리라인화해 세운다."""
|
||||
"""계획노선 **초기 폴리라인**이 없거나 낡았으면 예상노선을 폴리라인화해 세운다.
|
||||
|
||||
「낡았다」 = 예상노선 파일이 더 나중에 쓰였다. 파일을 다시 올리면 예상노선이 새로
|
||||
깔리는데 초기본이 옛 노선인 채로 남으면 노선 초기화가 옛 자리로 돌아간다.
|
||||
"""
|
||||
target = planned_route_initial_path(project_root)
|
||||
source = expected_route_csv_path(project_root)
|
||||
if target.is_file():
|
||||
return None
|
||||
points = [(x, y) for x, y in _vertices_of(expected_route_csv_path(project_root))]
|
||||
if not source.is_file() or source.stat().st_mtime <= target.stat().st_mtime:
|
||||
return None
|
||||
logger.info("예상노선이 새로 깔려 초기 폴리라인을 다시 만듭니다: %s", target)
|
||||
points = [(x, y) for x, y in _vertices_of(source)]
|
||||
if len(points) < 2:
|
||||
return None
|
||||
summary = _write_planned_polyline(target, points, radius_m)
|
||||
|
||||
Reference in New Issue
Block a user