Files
Aislo/resources/tester/test_174_b07_cross_cell_stack.py
T
eomsangdonandClaude Opus 5.5 303342a56e feat(b07): 횡단 장 측점마다 도면층 · 옛 확정 장 원지반 잠금 풂(212-1 · 212-2)
- 까닭: 새로 만든 장은 서버 · CAD 걸름 모두 원지반이 잡힘 — 안 잡힌 것은 180-1 앞에 원지반 층 잠금째 저장된 확정 장 또는 반영 전 서버 · 페이지 메모리의 옛 도면
- 확정 장을 열 때 원지반 층 잠금 풂 · 측점 층 없는 확정 장은 stale_layers 안내([수정] 때 새 꼴)
- 장의 측점마다 층 하나(b08-station-{측점} · 「횡단 No.3」) = 원지반 · 계획선 · 구조물 · 암 그림(자식 선까지) · 종류는 색 · 선 꼴 · 표 · 글은 수량표 층 · 종류 층 지움
- 개체 id · groupId 그대로 · placement 에 layer_id · design_ids — 화면 덧그림도 측점 층 · 서버 설계선은 id 로 걷음
- DXF 층 이름 = 측점 층 id
- 새 시험 test_212 · 174 · 180 · 180_2 원지반 찾기를 색으로

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TNMXVCZXMpHpVvqmFkeChL
2026-10-10 15:29:22 +09:00

124 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""174-1 B07 횡단 장 — 칸 아래 가운데 표 먼저 · 그 위 글 · 그림.
못박는 것
- 표 아래선 = 칸 아래 + 여백 · 같은 행 칸끼리 표 윗선 · 아랫선 한 높이(그림 · 글 크기와 무관).
- 표 가운데 x = 칸 가운데 = 도로 중심(offset 0) — 좌우 비대칭 단면도.
- [상세] 글은 표 바로 위 · 그림 아래 끝 = 글(없으면 표) 위 8 mm.
- 그림이 칸 위 · 옆을 넘으면 overflow_cells(축척 그대로) · 들어가면 없음.
- 배치 판 5(옛 판 확정 장 = 옛 배치 안내).
"""
import pytest
from B07_DesignDetail.B07_DesignDetail_Engine_Cad import GROUND_COLOR
from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Sheet import (
CELL_TABLE_PAD_MM,
build_cross_sheet,
plan_cross_sheets,
)
from B07_DesignDetail.B07_DesignDetail_Engine_Cad_Table import (
cross_note_height,
cross_note_lines,
cross_table_height,
)
from B07_DesignDetail.B07_DesignDetail_Engine_Template import (
entities_bbox,
usable_area,
use_project_templates,
)
from B07_DesignDetail.B07_DesignDetail_Router_Support import CROSS_SHEET_LAYOUT
NOTE = {"structure_note": "L형 측구\n집수정 보강"}
def _source(chainage: float, slope: float, lo: int, hi: int) -> dict:
return {
"chainage_m": chainage,
"samples": [
{"valid": True, "offset_m": float(x), "elevation_m": 100.0 + slope * x}
for x in range(lo, hi + 1)
],
}
def _sheet(sources: list[dict], designs: list[dict | None], grid: list[int]) -> tuple:
use_project_templates(None)
sheet = plan_cross_sheets([s["chainage_m"] for s in sources], {"default": grid})[0]
sections = [
{
"chainage": s["chainage_m"],
"source": s,
"design": design,
"quantity_table": {"ground": 1.0, "planned": 0.5},
"title": "",
}
for s, design in zip(sources, designs, strict=True)
]
return sheet, build_cross_sheet(sheet, sections)
def _tables(drawing: dict) -> list[tuple[float, float, float]]:
"""표마다 (가운데 x, 아랫선 y, 윗선 y) — 배치 순서."""
out = []
for entity in drawing["entities"]:
if entity["type"] != "Table":
continue
shape = entity["shapeData"]
left, top = shape["origin"]["x"], shape["origin"]["y"]
out.append((left + sum(shape["columnWidths"]) / 2, top - sum(shape["rowHeights"]), top))
return out
def test_같은_행_표_한_높이_그림_중심_칸_가운데() -> None:
# 2 × 2 — 좌하단 · 좌상단 · 우하단 · 우상단 · 높이 · 좌우 범위 · 글 유무가 다 다름
sources = [
_source(0.0, 0.05, -6, 6),
_source(20.0, 0.3, -3, 9),
_source(40.0, 0.05, -8, 4),
_source(60.0, 0.6, -5, 5),
]
designs = [None, NOTE, NOTE, None]
sheet, drawing = _sheet(sources, designs, [2, 2])
_w, h = usable_area()
cell_h = h / 2
tables = _tables(drawing)
assert len(tables) == 4
for (cx, bottom, top), slot in zip(tables, sheet["slots"], strict=True):
assert cx == pytest.approx(slot[0]) # 표 가운데 x = 칸 가운데
assert bottom == pytest.approx(slot[1] - cell_h / 2 + CELL_TABLE_PAD_MM)
assert top - bottom == pytest.approx(cross_table_height())
# 같은 행(아래 행 = 0 · 2번 · 위 행 = 1 · 3번) 표 윗선 · 아랫선 한 높이
for a, b in ((0, 2), (1, 3)):
assert tables[a][1:] == pytest.approx(tables[b][1:])
# 같은 열 표 가운데 x 한 줄
assert tables[0][0] == pytest.approx(tables[1][0])
# 도로 중심(offset 0) = 칸 가운데 · 그림(원지반) 아래 끝 = 글(없으면 표) 위 8 mm
grounds = [
entities_bbox([e])
for e in drawing["entities"]
if e.get("type") == "PolyLine" and e.get("lineColor") == GROUND_COLOR
]
for placement, slot, table, design, ground in zip(
drawing["cross_placements"], sheet["slots"], tables, designs, grounds, strict=True
):
assert placement["ox"] == pytest.approx(slot[0])
note_h = cross_note_height(cross_note_lines(design))
assert ground[1] == pytest.approx(table[2] + note_h + 8.0)
assert drawing["overflow_cells"] == []
def test_넘침_위_옆() -> None:
w, h = usable_area()
# 4 × 4 칸(192.5 × 130 mm) — 0: 높이 넘침(경사 1 · 높이 120 mm + 표) · 1: 오른쪽만 긴
# 단면(-2 ~ 16 m · 폭 180 < 칸 폭이지만 도로 중심 고정이라 오른쪽 넘침) · 2: 들어감
sources = [_source(0.0, 1.0, -6, 6), _source(20.0, 0.05, -2, 16), _source(40.0, 0.05, -5, 5)]
_sheet_, drawing = _sheet(sources, [None, None, None], [4, 4])
cw, ch = w / 4, h / 4
cells = [[-w / 2, -h / 2 + ch * j, -w / 2 + cw, -h / 2 + ch * (j + 1)] for j in range(2)]
assert drawing["overflow_cells"] == [pytest.approx(c) for c in cells]
def test_배치_판_5() -> None:
assert CROSS_SHEET_LAYOUT == 5