Files
Aislo/resources/tester/test_75_profile_strip.py
T
eomsangdonandClaude Opus 5.5 3c97d7c32d feat(B05): 계획노선 편집 창 종단 띠 — 노드를 놓을 때마다 지금 노선 종단 · [확인] = 띠에 보인 종단(75-1)
- 지도 아래 한 줄 띠: 원지반선 · 계획선 · 측점 눈금 · 켬/끔 단추(추천 창 「종단 반영」과 한 벌)
- 켬 = 서버 새 통로 /route/profile-preview 가 [확인]과 같은 폴리라인(같은 R · CSV 자릿수)으로 균형 종단 셈 · 끔 = /route/elevations 지반선만
- 갱신은 놓을 때 · 되돌리기 · 추천 적용 · 켬/끔 때만 · 최신 응답만 채택 · 기다리는 동안 옛 그림 흐림
- [확인]은 띠 응답을 기다린 뒤 띠에 보인 계획선(균형 종단 · 지반고)을 그대로 적용 — 추천을 손으로 고쳐도 켬이면 균형 종단

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYJJRCfHfdCGNhmXTjQKV7
2026-10-07 19:45:23 +09:00

76 lines
2.8 KiB
Python

"""편집 창 종단 띠 — [확인]과 같은 노선 점으로 균형 종단을 셈한다(PLAN 75-1).
./venv/Scripts/python.exe -m pytest resources/tester/test_75_profile_strip.py -q
"""
import asyncio
from pathlib import Path
from uuid import uuid4
from B05_Profile import B05_Profile_Router_Replan as replan
from B05_Profile import B05_Profile_Router_RouteInitial as initial
from common_util.common_util_route_geometry import read_planned_route_csv
NODES = [(0.0, 0.0), (120.0, 35.0), (180.0, 140.0), (310.0, 150.5)]
RADIUS_M = 25.0
def _strip_points(monkeypatch, tmp_path: Path, criteria=None) -> tuple[list, object]:
seen: dict = {}
async def paths(_pid):
return tmp_path, "x"
async def plan_criteria(_pid):
return RADIUS_M, 0.0, 0.0
async def profile_of(_pid, _root, points, crit):
seen["points"], seen["criteria"] = points, crit
return {"stations_m": [0.0, 20.0], "plan_m": [1.0, 2.0]}
monkeypatch.setattr(replan, "_project_paths", paths)
monkeypatch.setattr(replan, "_plan_criteria", plan_criteria)
monkeypatch.setattr(initial, "balanced_profile_of", profile_of)
request = initial.ProfilePreviewRequest(
vertices=[
replan.RouteVertexInput(x=x, y=y, curve=i != 2, radius_m=40.0 if i == 1 else None)
for i, (x, y) in enumerate(NODES)
],
criteria=criteria,
)
answer = asyncio.run(initial.profile_preview(uuid4(), request))
assert answer["profile"]["plan_m"] == [1.0, 2.0]
return seen["points"], seen["criteria"]
def test_띠_노선점은_확인이_읽는_CSV와_같다(monkeypatch, tmp_path: Path) -> None:
points, _ = _strip_points(monkeypatch, tmp_path)
working = tmp_path / "planned_route.csv"
replan._write_planned_polyline(
working,
NODES,
RADIUS_M,
simplify=False,
curve_flags=[True, True, False, True],
radii=[None, 40.0, None, None],
)
stored = read_planned_route_csv(working)
assert stored is not None
assert [(p["x"], p["y"]) for p in points] == [(v.x, v.y) for v in stored.vertices]
assert len(points) > len(NODES) # 원호가 펴져 있다
def test_띠는_지금_추천_제약을_싣는다(monkeypatch, tmp_path: Path) -> None:
criteria = replan.RouteInitialCriteria(max_grade_pct=12.0)
_, got = _strip_points(monkeypatch, tmp_path, criteria)
assert got.max_grade_pct == 12.0
def test_확인_목표는_같은_셈의_측점_계획고(monkeypatch, tmp_path: Path) -> None:
async def profile_of(*_args):
return {"stations_m": [0.0, 20.0, 31.5], "plan_m": [5.0, 6.0, 6.5], "cut_m3": 1.0}
monkeypatch.setattr(initial, "balanced_profile_of", profile_of)
target = asyncio.run(initial.balanced_target(uuid4(), tmp_path, [], None))
assert target == ([0.0, 20.0, 31.5], [5.0, 6.0, 6.5])