- B05_Profile_Engine._route_geojson x · y 3 → 4자리(z 3자리 그대로) · 짝 머리 표시 - draftLine 그린 선 x · y 4자리 · 곡선 start · apex · end 4자리 · R 3자리(= RouteCurve.as_dict) · 파이썬 round 짝(toFixed) - 교점 끌기 재현 브라우저 ↔ 서버 차 0.81 → 0.00 ㎥ · 옹벽 + 추가 측점 0.88 → 0.00 ㎥(test_475_1_route_digits) - 472-1 헬퍼 — 옮김 인자 · 페이지 배선(stationsAt · storedPvi) · 단면 모양 = 따라간 구조물(헛 차 덤 고침) · golden 값 그대로 - 옛 시험 두 곳(346_1) — 안 깎은 선 단언 → 서버 저장 자리 단언 - 관 지문 허용오차 주석 · calculations R1 줄 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
93 lines
3.4 KiB
Python
93 lines
3.4 KiB
Python
"""475-1 — 노선 선 소수 자리 한 벌(요구 275 ① · 브라우저 ↔ 서버 저장 차).
|
||
|
||
짝 = 서버 노선 geojson `_route_geojson` x · y 4자리 = 계획노선 csv `write_route_csv` =
|
||
브라우저 route 단계 `draftLine`(`B05_Profile_Pipeline_RouteGround.ts`). 같은 선이면 측점 · 지반 ·
|
||
계획선 · 면적 짝이 모두 같아 누가토량 차가 사라짐(옛 3자리 = 교점 끌기 0.8 ㎥).
|
||
|
||
고정 자료 = `fixtures/golden_472` · 브라우저 길 = `helper_472_1_browser.mjs` 옮김 인자 · 서버 길 =
|
||
`helper_475_1_moved.server_moved`(노선 저장 체인 DB 없이).
|
||
|
||
./venv/Scripts/python.exe -m pytest resources/tester/test_475_1_route_digits.py -q
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import copy
|
||
|
||
import helper_472_1_paths as paths
|
||
import helper_475_1_moved as moved
|
||
import pytest
|
||
|
||
from B05_Profile.B05_Profile_Router_Replan import _vertices_of
|
||
from common_util.common_util_route_geometry import write_route_csv
|
||
|
||
WALL = {
|
||
"structure_id": "wall600",
|
||
"type_id": "retaining_wall",
|
||
"placement": "interval",
|
||
"chainage_m": 600.0,
|
||
"start_m": 595.0,
|
||
"end_m": 605.0,
|
||
"options": {
|
||
"wall_form": "콘크리트",
|
||
"length_m": 10,
|
||
"height_m": 2,
|
||
"before_m": 5,
|
||
"after_m": 5,
|
||
"side": "자동(성토 쪽)",
|
||
},
|
||
"memo": "",
|
||
"placement_source": "manual",
|
||
"status": "draft",
|
||
"revision": 0,
|
||
"geometry": None,
|
||
"summary_item": None,
|
||
"group_items": None,
|
||
"x": 208785.614,
|
||
"y": 367845.1028,
|
||
}
|
||
# 교점 9(360 m 언저리) 동 +5 m · 같은 끌기 + 옹벽 595–605 + 추가 측점 510
|
||
CASES = {
|
||
"drag": {"node": 9, "dx": 5, "dy": 0},
|
||
"drag_wall_plus": {"node": 9, "dx": 5, "dy": 0, "plus": [510], "structures": [WALL]},
|
||
}
|
||
|
||
|
||
def test_geojson_자리_csv_와_같음(tmp_path) -> None:
|
||
from B05_Profile.B05_Profile_Engine import _route_geojson
|
||
|
||
line = [[208785.61234567, 367845.10285, 512.34567], [208790.00005001, 367850.99994999, 1.0]]
|
||
write_route_csv(tmp_path / "r.csv", [{"x": x, "y": y} for x, y, _ in line])
|
||
csv_xy = [list(p) for p in _vertices_of(tmp_path / "r.csv")]
|
||
geo = _route_geojson(line)["geometry"]["coordinates"]
|
||
assert [[x, y] for x, y, _ in geo] == csv_xy
|
||
assert geo[0][0] == 208785.6123 and geo[0][2] == 512.346
|
||
|
||
|
||
@pytest.fixture(scope="module", params=list(CASES))
|
||
def pair(request, tmp_path_factory) -> tuple[dict, dict]:
|
||
if not (paths.ROOT / "config" / "node_modules" / "vite").is_dir():
|
||
pytest.skip("프론트엔드 의존성 미설치")
|
||
move = copy.deepcopy(CASES[request.param])
|
||
work = tmp_path_factory.mktemp(request.param)
|
||
browser = paths.browser(work, move)
|
||
# 추가 측점 = 브라우저가 새 노선으로 따라간 자리(페이지 [저장]이 보내는 값)
|
||
if move.get("plus"):
|
||
move["plus"] = [s["chainage_m"] for s in browser["stations"] if "plus-" in (s["key"] or "")]
|
||
server = moved.server_moved(
|
||
paths.stage_project(work / "project"), {**move, "draft": browser["draft"]}
|
||
)
|
||
return browser, server
|
||
|
||
|
||
def test_그린_선_서버_선_같음(pair) -> None:
|
||
browser, server = pair
|
||
assert browser["route_line"] == server["route_line"]
|
||
|
||
|
||
def test_누가토량_차_002_안(pair) -> None:
|
||
browser, server = pair
|
||
b, s = browser["final_cumulative_m3"], server["final_cumulative_m3"]
|
||
assert browser["station_count"] == server["station_count"]
|
||
assert abs(b - s) <= 0.02, f"브라우저 {b} · 서버 {s}"
|