Merge remote-tracking branch 'origin/main_laptop_1' into sub_laptop_1

# Conflicts:
#	B08_Quantity/B08_Quantity_Engine_Pipe.py
This commit is contained in:
2026-09-09 12:10:09 +09:00
10 changed files with 659 additions and 20 deletions
+18 -1
View File
@@ -329,6 +329,23 @@ export function attachCulvertSets(
): number {
if (sets.size === 0) return 0;
let attached = 0;
// ⚠⚠ **관 자리와 측점 자리는 최대 0.5m 어긋난다 — 그것이 설계다**(2026-09-09 실측).
// 측점을 만들 때 정수 미터가 같은 격자 측점이 있으면 그리로 스냅한다(횡단 파일명이
// 정수 미터라 두 측점이 한 파일을 덮어쓰는 것을 막는 가드). 관 440.241 은 측점 440.0 위에 선다.
// ⇒ 0.02m 로만 보면 그런 관은 어느 측점에도 안 붙어 **그림도 수량도 통째로 빠진다.**
// ⇒ **가장 가까운 측점 하나**는 거리와 무관하게 그 관의 자리로 본다(짝: 파이썬 `attach_culvert_sets`).
const owner = new Map<number, number>();
for (const [pipeChainage] of sets) {
let nearest: number | null = null;
for (const section of sections) {
const value = num(section.chainage_m, null);
if (value === null) continue;
if (nearest === null || Math.abs(value - pipeChainage) < Math.abs(nearest - pipeChainage)) {
nearest = value;
}
}
if (nearest !== null) owner.set(pipeChainage, nearest);
}
for (const section of sections) {
const chainage = num(section.chainage_m, null);
if (chainage === null) continue;
@@ -336,7 +353,7 @@ export function attachCulvertSets(
// 연동 대상 종류만 폭의 절반까지 옆 측점에 걸친다.
let reach = CHAINAGE_TOLERANCE_M;
if (SPAN_LINKED_TYPES.has(String(spec.type))) reach += (num(spec.span_m, 0) ?? 0) / 2;
if (Math.abs(chainage - pipeChainage) <= reach) {
if (Math.abs(chainage - pipeChainage) <= reach || owner.get(pipeChainage) === chainage) {
// ⚠ 스펙에 **그 시설이 놓인 누가거리**를 함께 얹는다(2026-09-08, 짝: 파이썬
// `attach_culvert_sets`). 세트는 폭의 절반까지 옆 측점에도 붙으므로, 이것이 없으면
// 소비처가 「소유 측점」을 못 가려 **같은 시설을 여러 측점에서 센다**.