⚠ **뿌리** — `tmp/` 는 창 사이에 안 건너감(실측 확인: 상대 창이 놓은 `tmp/_sync_probe.txt` 가 시간을 두고 두 번 봐도 안 보임). 그래서 **정본(등록부 스키마)만 건너가고 그것을 읽는 시험은 안 건너가** 오늘 두 번, 같은 시험이 **연 창은 통과·받은 창은 실패**가 됐음. - `tmp/tests/*` 를 `resources/tester/` 로 **복사**(127 파일). 내용은 **한 줄도 안 고침** - `tmp/tests` 는 **남겨 둠** — 되돌릴 자리(사용자 지시) - 실행: `./venv/Scripts/python.exe -m pytest resources/tester/ -q` 옮기기 전과 **같은 수**: 617 통과 / 22 건너뜀 / 실패 0 ⇒ 이제 시험·예외·까닭이 **정본과 함께** 움직임. 오늘 세운 「예외는 정본 스키마에」와 짝임. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
79 lines
2.6 KiB
Python
79 lines
2.6 KiB
Python
"""근거리 제어점 직결 — 조밀 기준선이 격자 탐색에 안 틀어지는지 검증."""
|
|
|
|
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]
|