- 지도 아래 한 줄 띠: 원지반선 · 계획선 · 측점 눈금 · 켬/끔 단추(추천 창 「종단 반영」과 한 벌) - 켬 = 서버 새 통로 /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
76 lines
2.8 KiB
Python
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])
|