"""노선 [확인] 체인 이월 · 균형 종단 반영(PLAN 74-3 · 74-4). ./venv/Scripts/python.exe -m pytest resources/tester/test_74_route_confirm_initial.py -q """ import json from pathlib import Path from B05_Profile.B05_Profile_Router_Replan import RouteReplanRequest from B05_Profile.B05_Profile_Router_RouteInitial import _set_base_pvi from B06_Section.B06_Section_Router_Design import CARRY_INPUT_KEYS ROOT = Path(__file__).resolve().parents[2] def test_이월은_사용자_입력만() -> None: for result_key in ( "design_elevation_m", "cut_area_m2", "fill_area_m2", "design_line", "road_edges", "slope_unclosed", "section_mode", "ditch_side", ): assert result_key not in CARRY_INPUT_KEYS assert {"ground_type", "paved", "ditch_choice", "cut_slope_ratio_user"} <= set(CARRY_INPUT_KEYS) def test_체인이_옛_설계를_통째로_옮기지_않는다() -> None: source = (ROOT / "B03_FileInput" / "B03_FileInput_Service_Chain.py").read_text(encoding="utf-8") assert 'record["design"])' not in source # 옛 (누가거리, design 통째) 이월 assert "compute_default_designs, project_root, long_path, chainages, standard, inputs" in ( " ".join(source.split()) ) def test_변화점_계획고를_균형_종단으로(tmp_path: Path) -> None: path = tmp_path / "longitudinal.json" base = [{"chainage_m": s, "elevation_m": 100.0} for s in (0.0, 20.0, 30.0, 40.0)] alignment = {"base_pvi": base, "policy": {}} path.write_text(json.dumps({"profile_alignment": alignment}), encoding="utf-8") assert _set_base_pvi(path, [0.0, 20.0, 40.0], [10.0, 12.0, 14.0]) == 4 got = [ p["elevation_m"] for p in json.loads(path.read_text("utf-8"))["profile_alignment"]["base_pvi"] ] assert got == [10.0, 12.0, 13.0, 14.0] # 구조물 측점(30 m)은 직선 보간 def test_확인_요청_기본은_끔() -> None: assert RouteReplanRequest().balanced_profile is False assert RouteReplanRequest(balanced_profile=True).balanced_profile is True def test_종단곡선이_있어도_측점마다_목표를_지난다() -> None: import numpy as np from B05_Profile.B05_Profile_Engine_Grade_Alignment import ( AlignmentPolicy, build_curves, evaluate, ) from B05_Profile.B05_Profile_Engine_Grade_Profile import pass_through base_s = np.array([0.0, 20.0, 40.0, 60.0, 80.0]) target = np.array([100.0, 102.4, 102.0, 104.6, 103.0]) # 대수차가 커 곡선이 들어감 policy = AlignmentPolicy.from_dict({}) curves, _ = build_curves(base_s, target, policy) assert curves # 맞춤이 없으면 측점에서 뜸 base_z = pass_through(base_s, target, policy) got = evaluate(base_s, base_z, build_curves(base_s, base_z, policy)[0], base_s) assert np.max(np.abs(got - target)) < 1e-3