- 덧그림 범위를 서버가 화면과 같은 TS 로 셈 — Node 진입점 B07_DesignDetail_Cross_Extent_Node(최소 DOM 위에서 오프스크린 SVG 그리기 그대로) · 번들 build:b07-extent - 화면 그리기·수확 부분을 B07_DesignDetail_Cross_Overlay 로 떼어 화면과 Node 가 한 벌로 씀 - 장 배치·블록 테두리가 측점별 덧그림 범위를 덮음(목록·장 열기·확정·수정 네 길 모두 같은 계획) - 글자는 CAD 그리기대로 세로 가운데 · 폭은 글꼴 어림(한글 1.0 · 나머지 0.6 배) - 번들 낡음 판정에 B07 맨 위 TS 포함 - 검증_sub4: 66개 박스 ↔ 그림(덧그림·글자 실폭 포함) 모두 1.0 mm · 잘림 0 · 겹침 0 · 20장 → 21장 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013rJwJMVL4EE31y77TB11AP
92 lines
3.8 KiB
Python
92 lines
3.8 KiB
Python
"""B07 횡단면도 — 화면이 덧그리는 설계선·구조물까지 박스 안 1 mm (68-3).
|
|
|
|
서버가 화면과 같은 TS 를 Node 로 돌려 덧그림 범위를 재고(`_Cross_Extent_Node`),
|
|
장 배치 · 블록 테두리가 그 범위를 덮는다.
|
|
"""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from B07_DesignDetail.B07_DesignDetail_Engine_Cad import (
|
|
CROSS_MM,
|
|
FRAME_LAYER_ID,
|
|
build_cross_drawing,
|
|
)
|
|
from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Sheet import section_block_size
|
|
from B07_DesignDetail.B07_DesignDetail_Engine_Template import entities_bbox
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
FIXTURE = Path(__file__).parent / "fixtures" / "b07_cross_overlay_sections.json"
|
|
NODE_MODULES = ROOT / "config" / "node_modules"
|
|
|
|
_SOURCE = {
|
|
"chainage_m": 0.0,
|
|
"samples": [
|
|
{"valid": True, "offset_m": float(x), "elevation_m": 100.0 + 0.2 * x}
|
|
for x in range(-10, 11)
|
|
],
|
|
}
|
|
_DESIGN_LINE = [
|
|
{"offset_m": -10.0, "elevation_m": 98.0},
|
|
{"offset_m": -2.0, "elevation_m": 99.6},
|
|
{"offset_m": 2.0, "elevation_m": 99.6},
|
|
{"offset_m": 10.0, "elevation_m": 102.0},
|
|
]
|
|
# 오른쪽으로 8 m 더 뻗고 위로 3 m 솟는 덧그림(관 · 날개벽 따위)
|
|
_OVERLAY = (-3.0, 18.0, 97.0, 105.0)
|
|
|
|
|
|
def _frame(drawing: dict) -> list[float]:
|
|
return drawing["cross_placements"][0]["frame"]
|
|
|
|
|
|
def test_frame_covers_overlay_by_one_mm() -> None:
|
|
drawing = build_cross_drawing(
|
|
_SOURCE, "cross_s00000m", _DESIGN_LINE, None, None, "", overlay=_OVERLAY
|
|
)
|
|
placement = drawing["cross_placements"][0]
|
|
left, bottom, right, top = _frame(drawing)
|
|
to_x = lambda offset: offset * CROSS_MM + placement["ox"] # noqa: E731
|
|
to_y = lambda elev: (elev - placement["dy"]) * CROSS_MM + placement["oy"] # noqa: E731
|
|
assert right - to_x(_OVERLAY[1]) == pytest.approx(1.0)
|
|
assert top - to_y(_OVERLAY[3]) == pytest.approx(1.0)
|
|
# 왼쪽 · 아래는 서버 선(원지반 끝 · 설계선)이 더 바깥 — 그쪽에 1 mm
|
|
lines = [e for e in drawing["entities"] if e.get("layerId") != FRAME_LAYER_ID]
|
|
min_x, _min_y, _max_x, _max_y = entities_bbox(lines)
|
|
assert min_x - left == pytest.approx(1.0)
|
|
# 장 배치용 크기도 같은 규칙
|
|
width, height = section_block_size(_SOURCE, _DESIGN_LINE, with_table=False, overlay=_OVERLAY)
|
|
assert width == pytest.approx(right - left)
|
|
assert height == pytest.approx(top - bottom)
|
|
|
|
|
|
def test_no_overlay_keeps_68_1_frame() -> None:
|
|
plain = build_cross_drawing(_SOURCE, "cross_s00000m", _DESIGN_LINE, None, None, "")
|
|
inside = build_cross_drawing(
|
|
_SOURCE, "cross_s00000m", _DESIGN_LINE, None, None, "", overlay=(1.0, 3.0, 99.7, 99.8)
|
|
)
|
|
assert _frame(plain) == pytest.approx(_frame(inside))
|
|
|
|
|
|
@pytest.mark.skipif(not NODE_MODULES.is_dir(), reason="프론트엔드 의존성 미설치")
|
|
def test_node_bundle_measures_screen_overlay() -> None:
|
|
"""화면 코드를 Node 로 — 배수관 측점(85.052)은 서버 범위(+4.0 m)보다 13.8 m 까지 뻗는다."""
|
|
from B07_DesignDetail.B07_DesignDetail_Router_Support_Overlay import (
|
|
_NPM_SCRIPT,
|
|
BUNDLE,
|
|
_extents_from,
|
|
)
|
|
from common_util.common_util_node_bundle import run_bundle_json
|
|
|
|
detail = json.loads(FIXTURE.read_text(encoding="utf-8"))
|
|
extents = _extents_from(run_bundle_json(BUNDLE, _NPM_SCRIPT, {"detail": detail}))
|
|
assert set(extents) == {0, 85.05} # 측점 키는 0.01 m 로 끊는다(cross_station)
|
|
x_min, x_max, y_min, y_max = extents[85.05]
|
|
assert x_max == pytest.approx(13.8216, abs=1e-3)
|
|
assert x_min == pytest.approx(-10.4371, abs=1e-3)
|
|
assert y_max - y_min == pytest.approx(16.9505, abs=1e-3)
|
|
# 0 m: 노폭 글자(2 mm, 세로 가운데 정렬)가 맨 위 — 글자 반높이 0.1 m 까지
|
|
assert extents[0][3] == pytest.approx(879.8831, abs=1e-3)
|