"""근거리 제어점 직결 — 조밀 기준선이 격자 탐색에 안 틀어지는지 검증.""" import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[2])) import numpy as np import pytest import B05_Profile.B05_Profile_Engine_Solver as S @pytest.fixture() def fake_project(tmp_path: Path) -> Path: """1m 해상도 완만한 합성 DTM을 가진 가짜 프로젝트 루트.""" models = tmp_path / "B04_PreProcess" / "models" models.mkdir(parents=True) n = 61 x = np.arange(n, dtype=np.float64) y = np.arange(n, dtype=np.float64) xx, yy = np.meshgrid(x, y) z = 100.0 + 0.02 * xx + 0.01 * yy # 경사 2% — 제약에 안 걸린다 np.savez_compressed( models / "dtm_test_smooth.npz", x=x, y=y, z=z, valid_mask=np.ones_like(z, dtype=bool), ) return tmp_path def _solve(project_root: Path, pts: list[dict]) -> list[list[float]]: points_data = { "bp": pts[0], "ep": pts[-1], "cp": [dict(p, order=i + 1) for i, p in enumerate(pts[1:-1])], } result = S.solve_optimal_route(project_root, "test", True, points_data, {}, "dtm") return result["polyline"] def test_dense_baseline_preserved(fake_project: Path) -> None: """3m 간격 조밀 제어점(문턱 4m 이하) — 평면이 원좌표 그대로, 끼어든 점 없음.""" rng = np.random.default_rng(7) ts = np.arange(5.0, 50.0, 2.0) pts = [ {"x": float(t + rng.uniform(-0.3, 0.3)), "y": float(t * 0.7 + rng.uniform(-0.3, 0.3))} for t in ts ] poly = _solve(fake_project, pts) assert len(poly) == len(pts) for got, want in zip(poly, pts): assert got[0] == pytest.approx(want["x"], abs=1e-9) assert got[1] == pytest.approx(want["y"], abs=1e-9) def test_same_cell_pair_not_merged(fake_project: Path) -> None: """같은 칸에 스냅되는 초근접 정점 쌍도 안 합쳐지고 둘 다 남는다.""" pts = [ {"x": 10.0, "y": 10.0}, {"x": 10.6, "y": 10.3}, # 10.0과 같은 2m 칸 {"x": 13.0, "y": 11.8}, {"x": 16.0, "y": 13.2}, ] poly = _solve(fake_project, pts) assert len(poly) == len(pts) assert [p[:2] for p in poly] == [[p["x"], p["y"]] for p in pts] def test_sparse_pair_still_searched(fake_project: Path) -> None: """문턱(2×셀=4m)을 넘는 먼 구간은 종전대로 격자 탐색 — 중간점이 생긴다.""" pts = [{"x": 5.0, "y": 5.0}, {"x": 45.0, "y": 40.0}] poly = _solve(fake_project, pts) assert len(poly) > 2 # 탐색이 격자 중간점을 채웠다 assert poly[0][:2] == [5.0, 5.0] assert poly[-1][:2] == [45.0, 40.0]