From bafa652562280c07476598f82f1aa59bb5873ac7 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Wed, 9 Sep 2026 07:20:52 +0900 Subject: [PATCH] =?UTF-8?q?feat(B08):=20=EC=B1=84=EC=A7=91=EC=84=9D=20?= =?UTF-8?q?=EA=B3=B5=EC=A0=9C=EB=A5=BC=20=EA=B0=88=EB=9E=98=EB=B3=84?= =?UTF-8?q?=EB=A1=9C=20=EB=83=84=20=E2=80=94=20=EB=B0=9B=EB=8A=94=20?= =?UTF-8?q?=EC=AA=BD=EC=9D=B4=20=EC=B6=95=EC=9D=84=20=EB=A7=9E=EC=B6=B0=20?= =?UTF-8?q?=EB=BA=84=20=EC=88=98=20=EC=9E=88=EA=B2=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 축이 다른 값을 그냥 빼면 암에서 15% 어긋남(우리가 만드는 어긋남). 갈래를 실어 보내 유토곡선이 ×C 로 다짐 축에 맞춰 빼게 함 - 갈래를 못 가른 구조물 몫은 계수가 없어 따로 냄(환산 안 함) - ⚠ 벽 입적 ↔ 원바닥 암 부피의 관계를 정한 원문이 없음(캐면 부풀고 쌓으면 공극) — 그 가정은 어느 쪽으로 가도 남으므로 가정은 그대로 두고 축만 맞춤. 실무 시트가 그냥 뺀다는 사실까지 값과 함께 보냄 - tmp/tests 3건 추가 Co-Authored-By: Claude Opus 5 (1M context) --- .../B08_Quantity_Engine_HaulInputs.py | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/B08_Quantity/B08_Quantity_Engine_HaulInputs.py b/B08_Quantity/B08_Quantity_Engine_HaulInputs.py index 5c8e3045..03e03d35 100644 --- a/B08_Quantity/B08_Quantity_Engine_HaulInputs.py +++ b/B08_Quantity/B08_Quantity_Engine_HaulInputs.py @@ -41,6 +41,23 @@ VOLUME_BASIS_KEY = "volume_basis" VOLUME_BASIS_NATURAL = "natural" SPOIL_COMPONENT = "잔토처리" +COLLECTED_STONE_COMPONENT = "채집석" + +#: 채집석 공제를 **갈래별로** 낸다 (2026-09-09 세 창 확정 — 축을 맞추기로). +#: ⚠ 이 값은 **벽 입적(제자리 완성 부피)**이다 — 자연·다짐 어느 축으로도 환산한 적 없다. +#: 굳이 가르면 자연 축 쪽이라 받는 쪽이 **×C 로 다짐 축에 맞춰** 뺀다. +#: ⚠⚠ **벽 입적과 원바닥 암 부피의 관계를 정한 원문이 없다** — 캐면 부풀고(L) 벽에 쌓으면 +#: 공극이 생기는데 그 값이 품셈·교본·지식DB 어디에도 없다. **실무 시트도 그냥 뺀다** +#: (울진 「채집석 −274.66」이 사토에서 바로 빠진다). 그 가정은 어느 쪽으로 가도 남으므로 +#: **가정은 그대로 두고 축만 맞춘다** — 축이 다른 값을 그냥 빼는 것은 우리가 만드는 어긋남이다. +#: ⚠ 갈래를 모르는 구조물 몫은 **환산하지 않는다**(계수가 없다) — 따로 낸다. +COLLECTED_STONE_BY_GROUND_KEY = "collected_stone_by_ground_m3" +COLLECTED_STONE_UNKNOWN_KEY = "collected_stone_ground_unknown_m3" +COLLECTED_STONE_BASIS_NOTE = ( + "벽 입적(제자리 부피) — 자연 축으로 보고 받는 쪽이 ×C 로 다짐 축에 맞춰 뺌." + " ⚠ 벽 입적과 원바닥 암 부피의 관계를 정한 원문이 없음(캐면 부풀고 쌓으면 공극이 생기나" + " 그 값이 어디에도 없음). 실무 시트는 그냥 뺌 — 우리는 축만 맞춤" +) def _center(structure: dict[str, Any]) -> float | None: @@ -59,18 +76,33 @@ def haul_inputs(unit_quantity_table: dict[str, Any] | None) -> dict[str, Any]: if not unit_quantity_table: return { COLLECTED_STONE_KEY: None, + COLLECTED_STONE_BY_GROUND_KEY: {}, + COLLECTED_STONE_UNKNOWN_KEY: None, STRUCTURE_SPOIL_KEY: None, STRUCTURE_SPOIL_POINTS_KEY: [], VOLUME_BASIS_KEY: VOLUME_BASIS_NATURAL, } total = 0.0 points: list[dict[str, Any]] = [] + stone_by_ground: dict[str, float] = {} + stone_unknown = 0.0 for structure in unit_quantity_table.get("structures") or []: amount = 0.0 + stone = 0.0 for component in structure.get("components") or []: - if str(component.get("name") or "") != SPOIL_COMPONENT: + name = str(component.get("name") or "") + if name == COLLECTED_STONE_COMPONENT: + stone += float(component.get("amount") or 0.0) + if name != SPOIL_COMPONENT: continue amount += float(component.get("amount") or 0.0) + # 채집석 — 그 구조물의 지반 갈래로 담는다. 갈래를 못 가른 구조물 몫은 따로 둔다. + if stone > 0: + ground = str(structure.get("ground_type") or "") + if ground: + stone_by_ground[ground] = stone_by_ground.get(ground, 0.0) + stone + else: + stone_unknown += stone if amount <= 0: continue total += amount @@ -92,6 +124,11 @@ def haul_inputs(unit_quantity_table: dict[str, Any] | None) -> dict[str, Any]: collected = unit_quantity_table.get(COLLECTED_STONE_KEY) return { COLLECTED_STONE_KEY: collected, + COLLECTED_STONE_BY_GROUND_KEY: { + key: round(value, 3) for key, value in sorted(stone_by_ground.items()) + }, + COLLECTED_STONE_UNKNOWN_KEY: round(stone_unknown, 3) if stone_unknown else 0.0, + "collected_stone_basis": COLLECTED_STONE_BASIS_NOTE, STRUCTURE_SPOIL_KEY: round(total, 3) if points or total else None, STRUCTURE_SPOIL_POINTS_KEY: sorted(points, key=lambda row: row["chainage_m"]), # 총량에도 상태를 적는다 — 측점값을 안 쓰는 쪽도 상태를 알아야 한다.