fix(b08): 옹벽 기초 터파기 옆면 1:0.5 — 실무 식생옹벽블럭 기초 터파기와 같은 자리에서 기울기(브레인 판정 고침)
- 밑폭 2.2(기초 1.6 + 여유 0.3×2) · 윗폭 = 밑폭 + 0.5 × 판 깊이 × 2 = 2.9 · 깊이 0.7 → m당 터파기 1.54 → 1.785 · 되메우기 0.36 → 0.605 · 잔토 1.18 그대로 - 검증 프로젝트 내역 본체 124,202,681 → 124,424,547원(+221,866 = 구조물터파기 0~1m 15.4→17.85㎥ +213,375 · 되메우기 24.6→27.05㎥ +8,491) - 그림 터파기 점선을 사다리꼴로 · 「밑폭 2.20 · 윗폭 2.90 × 깊이 0.70」 · 표 사유와 같은 말 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
This commit is contained in:
@@ -152,7 +152,10 @@ def billing_of(
|
|||||||
|
|
||||||
|
|
||||||
#: 단면으로 터파기를 세운 줄의 사유 — 표 사유·구조물도 그림이 **같은 말**(브레인 판정 2026-09-14).
|
#: 단면으로 터파기를 세운 줄의 사유 — 표 사유·구조물도 그림이 **같은 말**(브레인 판정 2026-09-14).
|
||||||
SECTION_TRENCH_NOTE = "터파기는 기초 폭 + 양쪽 여유로 수직 — 지반선이 제원에 없어 비탈분 제외"
|
SECTION_TRENCH_NOTE = (
|
||||||
|
"터파기는 기초 폭 + 양쪽 여유 · 옆면 1:0.5(판 깊이 기준)"
|
||||||
|
" — 벽 높이 몫은 지반선이 제원에 없어 제외"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def earthwork_missing_note(entry: dict[str, Any]) -> str | None:
|
def earthwork_missing_note(entry: dict[str, Any]) -> str | None:
|
||||||
@@ -202,8 +205,9 @@ def section_trench_components(
|
|||||||
) -> tuple[list[dict[str, Any]], float] | None:
|
) -> tuple[list[dict[str, Any]], float] | None:
|
||||||
"""단면이 있는 관측 줄의 터파기·되메우기·잔토(`destination: earthwork`)와 파는 깊이(m).
|
"""단면이 있는 관측 줄의 터파기·되메우기·잔토(`destination: earthwork`)와 파는 깊이(m).
|
||||||
|
|
||||||
⚠ 브레인 판정 — 기초 폭 + 양쪽 여유(0.3, 같은 파일 식생옹벽블럭 기초 터파기)로 **수직** ·
|
⚠ 같은 파일 식생옹벽블럭 기초 터파기 식 — 밑폭 = 기초 폭 + 양쪽 여유 0.3 · 옆면 1:0.5
|
||||||
깊이 = 기초 + 버림 + 기초잡석 · **비탈분(벽 높이 몫)은 안 셈**(지반선이 제원에 없음).
|
(윗폭 = 밑폭 + 0.5 × 판 깊이 × 2) · 깊이 = 기초 + 버림 + 기초잡석 · 벽 높이 몫은 안 셈
|
||||||
|
(지반선이 제원에 없음). 브레인 판정 2026-09-14 — 처음 수직에서 1:0.5 로 고침.
|
||||||
⚠ 되메우기 = 터파기 − 그 안에 든 것(기초·전단키 콘크리트 + 버림 + 기초잡석) — 잔토 = 든 것.
|
⚠ 되메우기 = 터파기 − 그 안에 든 것(기초·전단키 콘크리트 + 버림 + 기초잡석) — 잔토 = 든 것.
|
||||||
"""
|
"""
|
||||||
section = entry.get("section") or {}
|
section = entry.get("section") or {}
|
||||||
@@ -211,11 +215,12 @@ def section_trench_components(
|
|||||||
if not trench:
|
if not trench:
|
||||||
return None
|
return None
|
||||||
footing, key, blinding = section["footing"], section["key"], section["blinding"]
|
footing, key, blinding = section["footing"], section["key"], section["blinding"]
|
||||||
clearance = trench["clearance_m"]
|
clearance, slope = trench["clearance_m"], trench.get("side_slope", 0.0)
|
||||||
width = footing["width_m"] + 2 * clearance
|
width = footing["width_m"] + 2 * clearance
|
||||||
depth = footing["thickness_m"] + blinding["thickness_m"] + rubble_thickness_m
|
depth = footing["thickness_m"] + blinding["thickness_m"] + rubble_thickness_m
|
||||||
|
top_width = width + 2 * slope * depth
|
||||||
key_below = max(key["depth_m"] - blinding["thickness_m"] - rubble_thickness_m, 0.0)
|
key_below = max(key["depth_m"] - blinding["thickness_m"] - rubble_thickness_m, 0.0)
|
||||||
excavation = width * depth + key["width_m"] * key_below
|
excavation = (width + top_width) / 2 * depth + key["width_m"] * key_below
|
||||||
layer_width = footing["width_m"] + 2 * blinding["overhang_m"] - key["width_m"]
|
layer_width = footing["width_m"] + 2 * blinding["overhang_m"] - key["width_m"]
|
||||||
filled = (
|
filled = (
|
||||||
footing["width_m"] * footing["thickness_m"]
|
footing["width_m"] * footing["thickness_m"]
|
||||||
@@ -224,10 +229,11 @@ def section_trench_components(
|
|||||||
)
|
)
|
||||||
backfill = excavation - filled
|
backfill = excavation - filled
|
||||||
basis = (
|
basis = (
|
||||||
f"(기초 폭 {footing['width_m']:g} + 여유 {clearance:g}×2) × 깊이 {depth:.2f}"
|
f"(밑폭 {width:.2f}(기초 {footing['width_m']:g} + 여유 {clearance:g}×2)"
|
||||||
|
f" + 윗폭 {top_width:.2f}(1:{slope:g})) ÷ 2 × 깊이 {depth:.2f}"
|
||||||
f"(기초 {footing['thickness_m']:g} + 버림 {blinding['thickness_m']:g}"
|
f"(기초 {footing['thickness_m']:g} + 버림 {blinding['thickness_m']:g}"
|
||||||
f" + 기초잡석 {rubble_thickness_m:g})"
|
f" + 기초잡석 {rubble_thickness_m:g})"
|
||||||
f" · {SECTION_TRENCH_NOTE} · 여유는 소광리 식생옹벽블럭 기초 터파기"
|
f" · {SECTION_TRENCH_NOTE} · 여유·기울기는 소광리 식생옹벽블럭 기초 터파기"
|
||||||
)
|
)
|
||||||
rows = [
|
rows = [
|
||||||
("터파기", excavation, basis),
|
("터파기", excavation, basis),
|
||||||
|
|||||||
@@ -297,22 +297,23 @@ def _wall_figure(
|
|||||||
# 터파기 — 표 줄과 같은 식(기초 폭 + 양쪽 여유 · 수직 · 기초 윗면에서 기초잡석 밑까지). 점선.
|
# 터파기 — 표 줄과 같은 식(기초 폭 + 양쪽 여유 · 수직 · 기초 윗면에서 기초잡석 밑까지). 점선.
|
||||||
trench = section.get("trench")
|
trench = section.get("trench")
|
||||||
clearance = trench["clearance_m"] if trench else 0.0
|
clearance = trench["clearance_m"] if trench else 0.0
|
||||||
|
side = (trench or {}).get("side_slope", 0.0) * (f_t + b_t + rubble)
|
||||||
dig_bottom = -(b_t + rubble)
|
dig_bottom = -(b_t + rubble)
|
||||||
if trench:
|
if trench:
|
||||||
shapes.append(
|
shapes.append(
|
||||||
_path(
|
_path(
|
||||||
[
|
[
|
||||||
(-clearance, f_t),
|
(-clearance - side, f_t),
|
||||||
(-clearance, dig_bottom),
|
(-clearance, dig_bottom),
|
||||||
(f_w + clearance, dig_bottom),
|
(f_w + clearance, dig_bottom),
|
||||||
(f_w + clearance, f_t),
|
(f_w + clearance + side, f_t),
|
||||||
],
|
],
|
||||||
"guide",
|
"guide",
|
||||||
dash=True,
|
dash=True,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
right = max(f_w + over, f_w + clearance) + 0.2
|
right = max(f_w + over, f_w + clearance + side) + 0.2
|
||||||
weep_area, weep_dia, _weep_basis = weep_hole_spec(sheet.get("options") or {})
|
weep_area, weep_dia, _weep_basis = weep_hole_spec(sheet.get("options") or {})
|
||||||
blinding_width = f_w + 2 * over - k_w
|
blinding_width = f_w + 2 * over - k_w
|
||||||
shapes += [
|
shapes += [
|
||||||
@@ -359,8 +360,9 @@ def _wall_figure(
|
|||||||
if trench:
|
if trench:
|
||||||
shapes.append(
|
shapes.append(
|
||||||
_text(
|
_text(
|
||||||
f"터파기 폭 {f_w + 2 * clearance:.2f} × 깊이 {f_t - dig_bottom:.2f} m"
|
f"터파기 밑폭 {f_w + 2 * clearance:.2f} · 윗폭 {f_w + 2 * (clearance + side):.2f}"
|
||||||
f" (기초 {f_w:g} + 여유 {clearance:g}×2)",
|
f" × 깊이 {f_t - dig_bottom:.2f} m (기초 {f_w:g} + 여유 {clearance:g}×2"
|
||||||
|
f" · 옆면 1:{trench.get('side_slope', 0.0):g})",
|
||||||
(right, f_t + 0.25),
|
(right, f_t + 0.25),
|
||||||
"left",
|
"left",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -45,7 +45,8 @@
|
|||||||
},
|
},
|
||||||
"trench": {
|
"trench": {
|
||||||
"clearance_m": 0.3,
|
"clearance_m": 0.3,
|
||||||
"note": "소광리 「옹벽2.0」 탭에 터파기 줄이 없음 → 같은 파일 「식생옹벽블럭(H=2.0)」 F31 기초 터파기 밑폭 = 기초 폭 + 0.6(양쪽 0.3). 브레인 판정(2026-09-14) — 수직 · 비탈분 제외(지반선이 제원에 없음)"
|
"side_slope": 0.5,
|
||||||
|
"note": "소광리 「옹벽2.0」 탭에 터파기 줄이 없음 → 같은 파일 「식생옹벽블럭(H=2.0)」 F31·H31 기초 터파기 — 밑폭 = 기초 폭 + 0.6(양쪽 0.3) · 윗폭 = 밑폭 + 0.5 × 판 깊이 × 2(옆면 1:0.5). 브레인 판정(2026-09-14, 수직 → 1:0.5 로 고침) · 벽 높이 몫은 지반선이 제원에 없어 제외"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"components": [
|
"components": [
|
||||||
|
|||||||
@@ -157,21 +157,22 @@ def _amounts(structure: dict) -> dict:
|
|||||||
return {row["name"]: row for row in structure["components"]}
|
return {row["name"]: row for row in structure["components"]}
|
||||||
|
|
||||||
|
|
||||||
def test_옹벽_터파기는_기초_폭과_양쪽_여유로_수직이고_토공으로만_간다() -> None:
|
def test_옹벽_터파기는_기초_폭과_양쪽_여유_옆면_1대0점5이고_토공으로만_간다() -> None:
|
||||||
wall = _wall_table()
|
wall = _wall_table()
|
||||||
rows = _amounts(wall)
|
rows = _amounts(wall)
|
||||||
# 폭 1.6 + 0.3×2 = 2.2 · 깊이 기초 0.4 + 버림 0.1 + 기초잡석 0.2 = 0.7 → 1.54/m
|
# 밑폭 1.6 + 0.3×2 = 2.2 · 깊이 0.4 + 0.1 + 0.2 = 0.7 · 옆면 1:0.5 → 윗폭 2.9
|
||||||
assert abs(rows["터파기"]["amount"] - 15.4) < 1e-9
|
# (2.2 + 2.9) ÷ 2 × 0.7 = 1.785/m
|
||||||
# 든 것 = 기초·전단키 0.745 + (버림 + 잡석) 1.45 × 0.3 = 1.18 → 되메우기 0.36/m
|
assert abs(rows["터파기"]["amount"] - 17.85) < 1e-9 # 수직일 때 15.4(2026-09-14 판정으로 고침)
|
||||||
|
# 든 것 = 기초·전단키 0.745 + (버림 + 잡석) 1.45 × 0.3 = 1.18 → 되메우기 0.605/m
|
||||||
assert abs(rows["잔토처리"]["amount"] - 11.8) < 1e-9
|
assert abs(rows["잔토처리"]["amount"] - 11.8) < 1e-9
|
||||||
assert abs(rows["되메우기"]["amount"] - 3.6) < 1e-9
|
assert abs(rows["되메우기"]["amount"] - 6.05) < 1e-9 # 수직일 때 3.6
|
||||||
assert {rows[k]["destination"] for k in ("터파기", "되메우기", "잔토처리")} == {"earthwork"}
|
assert {rows[k]["destination"] for k in ("터파기", "되메우기", "잔토처리")} == {"earthwork"}
|
||||||
assert abs(rows["기초잡석"]["amount"] - 2.9) < 1e-9 # 원문 버림 0.145 × 2
|
assert abs(rows["기초잡석"]["amount"] - 2.9) < 1e-9 # 원문 버림 0.145 × 2
|
||||||
assert wall["trench_depth_m"] == 0.7
|
assert wall["trench_depth_m"] == 0.7
|
||||||
assert "비탈분 제외" in rows["터파기"]["basis"]
|
assert "1:0.5" in rows["터파기"]["basis"] and "지반선" in rows["터파기"]["basis"]
|
||||||
# 잡석을 얇게 두면 전단키가 그 밑으로 나와 그 몫을 더 팜: 2.2×0.6 + 0.35×0.1
|
# 잡석을 얇게 두면 전단키가 그 밑으로 나와 그 몫을 더 팜: (2.2+2.8)/2×0.6 + 0.35×0.1
|
||||||
thin = _amounts(_wall_table(rubble=0.1))
|
thin = _amounts(_wall_table(rubble=0.1))
|
||||||
assert abs(thin["터파기"]["amount"] - 13.55) < 1e-9
|
assert abs(thin["터파기"]["amount"] - 15.35) < 1e-9
|
||||||
|
|
||||||
|
|
||||||
def test_옹벽_물구멍관은_제원_칸이_닿고_돌쌓기와_같은_규격으로_합쳐진다() -> None:
|
def test_옹벽_물구멍관은_제원_칸이_닿고_돌쌓기와_같은_규격으로_합쳐진다() -> None:
|
||||||
@@ -196,8 +197,11 @@ def test_옹벽_그림은_기초잡석_두께를_산출_조건에서_받고_사
|
|||||||
_wall_sheet() | {"options": {"length_m": 10}},
|
_wall_sheet() | {"options": {"length_m": 10}},
|
||||||
)
|
)
|
||||||
trench = [note for note in table_notes if "터파기" in note]
|
trench = [note for note in table_notes if "터파기" in note]
|
||||||
assert trench and trench[0] in texts and "비탈분 제외" in trench[0]
|
assert trench and trench[0] in texts and "지반선" in trench[0]
|
||||||
assert "터파기 폭 2.20 × 깊이 0.80 m (기초 1.6 + 여유 0.3×2)" in texts # 잡석 0.3
|
# 잡석 0.3 → 깊이 0.8 · 한쪽 0.4
|
||||||
|
assert (
|
||||||
|
"터파기 밑폭 2.20 · 윗폭 3.00 × 깊이 0.80 m (기초 1.6 + 여유 0.3×2 · 옆면 1:0.5)" in texts
|
||||||
|
)
|
||||||
assert not any(text.startswith("기초잡석") for text in _texts(build_figure(_wall_sheet(), 0)))
|
assert not any(text.startswith("기초잡석") for text in _texts(build_figure(_wall_sheet(), 0)))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user