- follow_structures ↔ followStructures(intervalM): site 꼴 = 새 노선 일반 측점(격자 · 끝) 중 가장 가까운 곳 · 그 밖 정수 m 그대로 - 파이썬 snap_existing_station ↔ TS snapExistingStation · general_stations ↔ gridStations 짝 - 브라우저 노선 초안 따라감(Pipeline_Grade) = 측점 간격 넘김 · 서버 노선 저장 따라감 = 서버 간격 - test_322_2: B05 목록 고정 수 23 대신 both 목록 수와 같음(M02 켬끔 판마다 다름) - 시험 test_380_3_site_follow(거울 · 가운데면 앞 측점 · 좌표 없음 그대로) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VmC34fsxxbweEG3RUjs3Mn
102 lines
3.7 KiB
Python
102 lines
3.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""380-3 노선이 바뀌어 좌표로 따라간 사토장 · 토취장(site) = 새 노선 일반 측점 중 가장 가까운 곳.
|
|
|
|
요구 241-8 「기존에 있던 측점들을 기준으로」 — 따라간 뒤에도 기존 측점에 섬(CAD 글 ±0.51 m).
|
|
그 밖 꼴은 종전대로 정수 m. 짝 = 파이썬 `follow_structures` · `snap_existing_station` ·
|
|
`general_stations` ↔ TS `followStructures(…, intervalM)` · `snapExistingStation` · `gridStations`
|
|
(`helper_380_3_site_follow.cjs`).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
ROOT = HERE.parents[1]
|
|
if str(ROOT) not in sys.path:
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
from common_util.common_util_route_follow import follow_structures # noqa: E402
|
|
from common_util.common_util_structure_station import ( # noqa: E402
|
|
general_stations,
|
|
snap_existing_station,
|
|
)
|
|
from config.config_system_design import SECTION_STATION_INTERVAL_M # noqa: E402
|
|
|
|
# 새 노선 = 길이 130.0 m(50 + 50 + 30) — 일반 측점 0 · 20 · … · 120 · 130
|
|
LINE = [(0.0, 0.0), (50.0, 0.0), (50.0, 50.0), (80.0, 50.0)]
|
|
ITEMS = [
|
|
{"placement": "site", "chainage_m": 33.0, "x": 33.0, "y": 1.0}, # 투영 33 → 40
|
|
{"placement": "site", "chainage_m": 75.0, "x": 51.0, "y": 25.0}, # 투영 75 → 80(가까운 쪽)
|
|
{"placement": "site", "chainage_m": 10.0, "x": 10.0, "y": -2.0}, # 가운데 10 → 앞 측점 0
|
|
{"placement": "site", "chainage_m": 127.0, "x": 78.0, "y": 50.0}, # 투영 128 → 끝 130
|
|
{"placement": "point", "chainage_m": 33.0, "x": 33.0, "y": 1.0}, # site 아님 = 정수 m 33
|
|
{"placement": "site", "chainage_m": 40.0}, # 좌표 없음 — 그대로
|
|
]
|
|
WANT = [40.0, 80.0, 0.0, 130.0, 33.0, 40.0]
|
|
GRIDS = [(130.0, 20.0), (120.0, 20.0), (0.0, 20.0), (5.5, 2.0)]
|
|
SNAPS = [(25.0, [0.0, 20.0, 40.0]), (30.0, [0.0, 20.0, 40.0]), (7.0, [0.0, 10.0])]
|
|
|
|
pytestmark = pytest.mark.skipif(
|
|
not (ROOT / "config" / "node_modules" / "typescript").is_dir(),
|
|
reason="프론트엔드 의존성 미설치",
|
|
)
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def ts(tmp_path_factory) -> dict:
|
|
source = tmp_path_factory.mktemp("s3803") / "in.json"
|
|
source.write_text(
|
|
json.dumps(
|
|
{
|
|
"grids": GRIDS,
|
|
"snaps": SNAPS,
|
|
"items": ITEMS,
|
|
"line": [{"x": x, "y": y} for x, y in LINE],
|
|
"interval": SECTION_STATION_INTERVAL_M,
|
|
}
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
proc = subprocess.run( # noqa: S603 — 고정 실행 파일
|
|
["node", str(HERE / "helper_380_3_site_follow.cjs"), str(source)],
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
cwd=str(ROOT),
|
|
check=False,
|
|
)
|
|
assert proc.returncode == 0, proc.stderr
|
|
return json.loads(proc.stdout)
|
|
|
|
|
|
def _python_follow() -> list[float]:
|
|
items = [
|
|
SimpleNamespace(**{"x": None, "y": None, "start_m": None, "end_m": None, **item})
|
|
for item in ITEMS
|
|
]
|
|
follow_structures(items, LINE)
|
|
return [item.chainage_m for item in items]
|
|
|
|
|
|
def test_따라간_site_는_새_노선_일반_측점() -> None:
|
|
assert SECTION_STATION_INTERVAL_M == 20.0
|
|
assert _python_follow() == WANT
|
|
|
|
|
|
def test_거울_파이썬_TS(ts) -> None:
|
|
assert ts["follow"] == _python_follow()
|
|
assert ts["grid"] == [general_stations(total, interval) for total, interval in GRIDS]
|
|
assert ts["snap"] == [snap_existing_station(value, stations) for value, stations in SNAPS]
|
|
assert ts["snap"] == [20.0, 20.0, 10.0] # 가운데면 앞 측점
|
|
|
|
|
|
def test_간격_안_주면_종전_정수_m(ts) -> None:
|
|
assert ts["plain"] == [33.0, 75.0, 10.0, 128.0, 33.0, 40.0]
|