diff --git a/E04_Stab3D/E04_Stab3D_Router.py b/E04_Stab3D/E04_Stab3D_Router.py index a52acc53d..2416a95e8 100644 --- a/E04_Stab3D/E04_Stab3D_Router.py +++ b/E04_Stab3D/E04_Stab3D_Router.py @@ -184,7 +184,6 @@ def _overview(project_root: Path, root: Path) -> dict[str, Any]: for item in saved: current = run.fingerprint(finger_source, ground, item.pop("settings")) item["stale"] = item.pop("fingerprint") != current - points = source.db_snapshot(root).get("route_points") or [] return { "sections": run.auto_sections(stations), "stations": [ @@ -196,9 +195,10 @@ def _overview(project_root: Path, root: Path) -> dict[str, Any]: } for s in stations ], + # 중심선 = 측점 중심(B06 누가 그대로 · route_points 는 접선 꺾은선이라 누가가 다름) "line": [ - [float(p["model_x"]), float(p["model_y"]), float(p["chainage_m"])] - for p in sorted(points, key=lambda p: p["sequence_num"]) + [float(s["center_x"]), float(s["center_y"]), float(s["chainage_m"])] + for s in sorted(stations, key=lambda s: float(s["chainage_m"])) ], "saved": saved, "defaults": SearchSettings().model_dump(), diff --git a/E04_Stab3D/E04_Stab3D_Run.py b/E04_Stab3D/E04_Stab3D_Run.py index 299ca5ca5..599886ce9 100644 --- a/E04_Stab3D/E04_Stab3D_Run.py +++ b/E04_Stab3D/E04_Stab3D_Run.py @@ -33,7 +33,7 @@ from E03_StabSection.E03_StabSection_Types import DEFAULT_ROAD_SURCHARGE_KPA from E04_Stab3D import E04_Stab3D_Engine_Grid as grid_engine from E04_Stab3D import E04_Stab3D_Engine_Search as search_engine -ENGINE_VERSION = "e04-2" # 엔진 판 — 바뀌면 지문이 달라져 다시 셈 +ENGINE_VERSION = "e04-3" # 엔진 판 — 바뀌면 지문이 달라져 다시 셈 STAGE_DIR = "E04_Stab3D" GROUND_FILE = Path("E02_StabGround") / "ground.json" SECTION_LENGTH_M = 100.0 # 자동 구간 길이 @@ -127,14 +127,19 @@ def _engine_station(root: Path, station: dict[str, Any]) -> dict[str, Any]: def _node_mask( - root: Path, grid: dict[str, Any], start_m: float, end_m: float, half_width_m: float + stations: list[dict[str, Any]], + grid: dict[str, Any], + start_m: float, + end_m: float, + half_width_m: float, ) -> np.ndarray: """탐색 노드 자리 = 중심선에서 half_width 안 · 가장 가까운 중심선 점의 누가가 구간 안 - · 가장 가까운 점이 노선 양 끝점인 셀(노선 시점 앞 · 종점 뒤)은 뺌.""" - points = sorted( - source.db_snapshot(root).get("route_points") or [], key=lambda p: p["sequence_num"] + · 가장 가까운 점이 중심선 양 끝점인 셀(시점 앞 · 종점 뒤)은 뺌. + + 중심선 = 측점 중심을 이은 선(B06 누가 그대로 · route_points 는 접선 꺾은선이라 누가가 다름).""" + line = np.array( + [[float(s["center_x"]), float(s["center_y"]), float(s["chainage_m"])] for s in stations] ) - line = np.array([[p["model_x"], p["model_y"], p["chainage_m"]] for p in points], float) # 0.5 m 로 촘촘히 — 꺾인 점 사이 셀도 바른 누가 dense = [line[:1]] for a, b in zip(line[:-1], line[1:]): @@ -199,7 +204,7 @@ def run_engine( strata = grid_engine.strata_from_grid( grid, (ground or {}).get("materials"), water_depth_m=0.0 if wet else None ) - mask = _node_mask(root, grid, settings["start_m"], settings["end_m"], half) + mask = _node_mask(stations, grid, settings["start_m"], settings["end_m"], half) ratios = (1.0,) if settings["shape"] == "sphere" else (1.0, float(settings["ellipsoid_ratio"])) params = search_engine.SearchParams( node_mask=mask, diff --git a/resources/tester/test_533_3_e04_engine.py b/resources/tester/test_533_3_e04_engine.py index a3549dc85..011197fd3 100644 --- a/resources/tester/test_533_3_e04_engine.py +++ b/resources/tester/test_533_3_e04_engine.py @@ -83,16 +83,6 @@ def root(tmp_path, monkeypatch): z = _ground(yy) np.savez(models / "dtm_classification.npz", x=xs, y=ys, z=z, valid_mask=np.ones_like(z, bool)) monkeypatch.setattr(run.source, "cross_section", lambda r, ch: _cross(float(ch))) - monkeypatch.setattr( - run.source, - "db_snapshot", - lambda r: { - "route_points": [ - {"model_x": ch, "model_y": 0.0, "chainage_m": ch, "sequence_num": i} - for i, ch in enumerate(CHAINAGES) - ] - }, - ) return tmp_path @@ -185,10 +175,10 @@ def test_node_mask_section_and_route_ends(root): x = np.arange(-30.0, 131.0, 1.0) y = np.arange(-20.0, 21.0, 1.0) grid = {"x": x, "y": y} - mask = run._node_mask(root, grid, 0.0, 100.0, 12.0) + mask = run._node_mask(STATIONS, grid, 0.0, 100.0, 12.0) xx, yy = np.meshgrid(x, y) assert not mask[xx < -0.5].any() and not mask[xx > 100.5].any() assert not mask[np.abs(yy) > 12.0].any() assert mask[(np.abs(yy) <= 12.0) & (xx >= 1) & (xx <= 99)].all() - part = run._node_mask(root, grid, 20.0, 60.0, 12.0) + part = run._node_mask(STATIONS, grid, 20.0, 60.0, 12.0) assert not part[(xx < 19.5) | (xx > 60.5)].any() and part[(yy == 0) & (xx == 40)].all() diff --git a/resources/tester/test_533_3_e04_router.py b/resources/tester/test_533_3_e04_router.py index aac24b02b..0e7793b5d 100644 --- a/resources/tester/test_533_3_e04_router.py +++ b/resources/tester/test_533_3_e04_router.py @@ -57,21 +57,6 @@ def project(tmp_path, monkeypatch): z = 500.0 + 0.4 * (yy - 200.0) + 0.002 * (xx - 200.0) ** 2 # 노선 옆 비탈 np.savez(models / "dtm_classification.npz", x=xs, y=ys, z=z, valid_mask=np.ones_like(z, bool)) monkeypatch.setattr(run.source, "stations", lambda root: STATIONS) - monkeypatch.setattr( - run.source, - "db_snapshot", - lambda root: { - "route_points": [ - { - "model_x": s["center_x"], - "model_y": 200.0, - "chainage_m": s["chainage_m"], - "sequence_num": i, - } - for i, s in enumerate(STATIONS) - ] - }, - ) async def fake_root(project_id): return tmp_path