feat(B08): 채집석 공제를 갈래별로 냄 — 받는 쪽이 축을 맞춰 뺄 수 있게
- 축이 다른 값을 그냥 빼면 암에서 15% 어긋남(우리가 만드는 어긋남). 갈래를 실어 보내 유토곡선이 ×C 로 다짐 축에 맞춰 빼게 함 - 갈래를 못 가른 구조물 몫은 계수가 없어 따로 냄(환산 안 함) - ⚠ 벽 입적 ↔ 원바닥 암 부피의 관계를 정한 원문이 없음(캐면 부풀고 쌓으면 공극) — 그 가정은 어느 쪽으로 가도 남으므로 가정은 그대로 두고 축만 맞춤. 실무 시트가 그냥 뺀다는 사실까지 값과 함께 보냄 - tmp/tests 3건 추가 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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"]),
|
||||
# 총량에도 상태를 적는다 — 측점값을 안 쓰는 쪽도 상태를 알아야 한다.
|
||||
|
||||
Reference in New Issue
Block a user