- 집수정 □형 Ø800 — 관측 줄에 원문 치수(소광리 「집수정구조도(800)」 설계조건 칸·산출식)를 싣고 그 치수로 표 수량이 원문 식대로 다시 나오는지 시험 원문 값으로: 콘크리트 2.84 → 2.83752 · 합판거푸집 21.28 → 21.2843 · 철근 D13 4.78 → 4.776 · 면목 12.67 → 12.6728(터파기·되메우기·잔토 그대로) 그림: 긴 벽 정면(바닥기초·관·방수로·터파기) + 평면 · 관·방수로 자리는 원문 입체도 모식이라 적음 - 물넘이포장 — 슬래브 T(규격) · 와이어메쉬 2/3T(소광리 「포장」 그림) · 터파기 · 새 사유 「원문 둘이 다름: 소광리 포장 와이어매쉬 1.0·비닐 2㎡ ↔ 이 표(울진 1공구) 1.16·비닐 없음」을 표·그림이 같이 씀 - 날개벽 5종 — 원문 탭에 구조도 그림이 없고 날개 모양이 손으로 적은 수뿐이라 까닭 · 돌집수정 ㄷ·ㄴ형 — 집계표 관측값이라 치수 원문 없음 까닭 - 사유 문구(브레인 판정): 개거 150×200 「원문 둘이 다름(산출식 0.3×0.1 ↔ 그림 홈 150×200 + 밑 보 400×200)」 · 바닥막이 「옹벽은 버림·잡석까지 팜 — 바닥막이는 정본이 돌 두께만이라 다름」 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
112 lines
4.9 KiB
Python
112 lines
4.9 KiB
Python
"""구조물도 그림 — 기슭막이·골막이·떼흙막이·바닥막이·개거 (2026-09-14 · 표 = 그림).
|
||
|
||
표를 세운 그 전개(`build_table`)로 장을 만들고 그림 글자가 **표 근거와 같은 수**를 보이는지 대조.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import re
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
ROOT = Path(__file__).resolve().parents[2]
|
||
if str(ROOT) not in sys.path:
|
||
sys.path.insert(0, str(ROOT))
|
||
|
||
from B08_Quantity.B08_Quantity_Engine_StructureFigure import attach_figures # noqa: E402
|
||
from B08_Quantity.B08_Quantity_Engine_StructureSheet import build_standard_sheets # noqa: E402
|
||
from B08_Quantity.B08_Quantity_Engine_UnitQuantity import build_table # noqa: E402
|
||
from B08_Quantity.B08_Quantity_Engine_UnitQuantity_Revetment import ( # noqa: E402
|
||
BED_SILL_TRENCH_NOTE,
|
||
SOIL_GUARD_SOD,
|
||
)
|
||
|
||
|
||
def _sheet(type_id: str, rubble=None, **options) -> dict:
|
||
structure = {
|
||
"structure_id": type_id,
|
||
"type_id": type_id,
|
||
"start_m": 0.0,
|
||
"end_m": float(options.get("length_m") or 0.0),
|
||
"options": options,
|
||
}
|
||
table = build_table([structure], None, rubble_base_thickness_m=rubble)
|
||
payload = build_standard_sheets(table)
|
||
attach_figures(payload, rubble)
|
||
return payload["sheets"][0]
|
||
|
||
|
||
def _texts(sheet: dict) -> list[str]:
|
||
return [shape["text"] for shape in sheet["figure"] or [] if shape["kind"] == "text"]
|
||
|
||
|
||
def _basis(sheet: dict, name: str) -> str:
|
||
return next(row["basis"] for row in sheet["rows"] if row["name"] == name)
|
||
|
||
|
||
def test_기슭막이_돌쌓기형은_돌쌓기_그림이고_기울기_두께가_표와_같다() -> None:
|
||
sheet = _sheet("revetment", form="돌쌓기(메)", height_m=2.0, back_len_cm=35, length_m=10)
|
||
texts = _texts(sheet)
|
||
assert sheet["figure_reason"] is None
|
||
slope = re.search(r"1:([\d.]+)", _basis(sheet, "돌쌓기")).group(1) # 메쌓기 표준경사
|
||
assert f"1 : {slope}" in texts
|
||
top = re.search(r"상부 ([\d.]+)", _basis(sheet, "입적")).group(1)
|
||
assert f"상부 {top} m" in texts
|
||
concrete = _sheet("revetment", form="콘크리트", height_m=2.0, length_m=10)
|
||
assert concrete["figure"] is None and "콘크리트 기슭막이" in concrete["figure_reason"]
|
||
|
||
|
||
def test_골막이_그림_치수는_표_두께식과_같다() -> None:
|
||
sheet = _sheet(
|
||
"erosion_check", form="돌", height_m=1.5, top_length_m=4, bottom_length_m=2, back_len_cm=45
|
||
)
|
||
texts = _texts(sheet)
|
||
thickness = re.search(r"평균두께 ([\d.]+)m", _basis(sheet, "입적")).group(1)
|
||
label = next(t for t in texts if t.startswith("상부"))
|
||
assert f"평균 {float(thickness):.2f}" in label
|
||
trench = next(t for t in texts if t.startswith("바닥파기"))
|
||
width = re.search(r"× ([\d.]+) \)", _basis(sheet, "터파기").replace(")", " )")).group(1)
|
||
assert f"폭 {float(width):.2f}" in trench
|
||
band = [s for s in sheet["figure"] if s["kind"] == "path" and s["dash"]][0]
|
||
assert min(y for _x, y in band["points"]) < 0 # 바닥파기 띠가 밑변 바깥(아래)에 섬
|
||
|
||
|
||
def test_떼흙막이_붙박이_치수로_표_두_줄이_다시_나온다() -> None:
|
||
d = SOIL_GUARD_SOD["dims"]
|
||
sod = (
|
||
d["top_m"] * d["sod_m"]
|
||
+ d["bottom_m"] * d["sod_m"]
|
||
+ (d["top_m"] + d["bottom_m"]) / 2 * d["height_m"]
|
||
+ d["slant_m"] * d["sod_m"] * 2
|
||
)
|
||
trench = (d["slant_m"] * d["trench_width_m"] * d["trench_depth_m"] * 2) + (
|
||
d["bottom_m"] * d["trench_width_m"] * d["trench_depth_m"]
|
||
)
|
||
rows = {row[0]: row[2] for row in SOIL_GUARD_SOD["rows"]}
|
||
assert round(sod, 2) == rows["떼"] and round(trench, 2) == rows["터파기"]
|
||
assert (
|
||
abs(((d["top_m"] - d["bottom_m"]) / 2) ** 2 + d["height_m"] ** 2 - d["slant_m"] ** 2) < 0.01
|
||
)
|
||
sheet = _sheet("soil_guard", form="떼", height_m=0.5, length_m=10)
|
||
assert sheet["figure"] and sheet["unit_label"] == "개소당"
|
||
other = _sheet("soil_guard", form="돌(찰)", height_m=0.5, length_m=10)
|
||
assert other["figure"] is None and "떼흙막이" in other["figure_reason"]
|
||
|
||
|
||
def test_바닥막이_그림_사유는_표와_같은_말이고_기초잡석은_산출_조건() -> None:
|
||
sheet = _sheet("bed_sill", rubble=0.3, form="돌붙임(찰)", area_m2=12, height_m=0.3)
|
||
texts = _texts(sheet)
|
||
assert BED_SILL_TRENCH_NOTE in sheet["notes"] and BED_SILL_TRENCH_NOTE in texts
|
||
assert "기초잡석 T=0.3 m — 산출 조건" in texts
|
||
dry = _sheet("bed_sill", form="돌붙임(메)", area_m2=12, height_m=0.3)
|
||
assert (
|
||
not any("기초잡석" in t for t in _texts(dry)) and BED_SILL_TRENCH_NOTE not in dry["notes"]
|
||
)
|
||
|
||
|
||
def test_개거는_표가_서도_치수를_못_정한_까닭() -> None:
|
||
sheet = _sheet("open_ditch", ditch_spec="콘크리트 개거 150×200", length_m=5)
|
||
assert sheet["rows"] and sheet["figure"] is None and "확인 대기" in sheet["figure_reason"]
|
||
l_type = _sheet("open_ditch", ditch_spec="L형수로 H=0.2", length_m=5)
|
||
assert l_type["rows"] and "단면 그림이 없어" in l_type["figure_reason"]
|