feat(B06): 도수로 · 돌붙임 실시간 반영 · 물넘이 포장 chute 연결(136-1 · 136-2)

- 폼 → 횡단 캐시 한 곳(applyPipeOptionsToCache)에서 관 · BOX · 세월교 · 물넘이 포장 chute 갈아 끼움 + 카드 다시 그림
- chute(values, 머리) · _chute 같은 인자 · 물넘이 세트에 ford_chute_{n}_* (파이썬 · TS 짝)
- 물넘이 오버레이에 유출측 성토사면 띠 · B08 집계 gfordpavechute 같은 열
- 시험: test_136_chute_form_cache 새로 · 거울 · test_52_3 · test_120 늘림

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015sDZSjFvoiDjdGpgj3muc3
This commit is contained in:
2026-10-09 14:49:41 +09:00
co-authored by Claude Opus 5.5
parent c0cf0ab90a
commit b66dce4313
10 changed files with 357 additions and 40 deletions
+27 -17
View File
@@ -126,27 +126,33 @@ function sideSpec(
return spec;
}
/** 도수로 · 돌붙임(90-2) — 첫 상자(`chute_add_{n}_*`) 구조 · 두께(cm → m · 빈 값 30 cm) · 구조를 안
* 고르면 null. 횡단이 유출 성토사면을 따라 띠로 그림. 파이썬 짝 `_chute`. */
/** 도수로 · 돌붙임(90-2) — 첫 상자(`{head}_{n}_*` · 물넘이 포장 = `ford_chute` · 136-2) 구조 · 두께
* (cm → m · 빈 값 30 cm) · 구조를 안 고르면 null. 횡단이 유출 성토사면을 따라 띠로 그림. 파이썬 짝 `_chute`. */
export function chute(
values: Record<string, unknown>,
head = "chute_add",
): { structure: string; thickness_m: number } | null {
const pattern = new RegExp(`^${head}_(\\d+)_structure$`);
const picked = Object.entries(values)
.flatMap(([key, value]) => {
const hit = /^chute_add_(\d+)_structure$/.exec(key);
const hit = pattern.exec(key);
const structure = String(value ?? "").trim();
return hit && structure ? [[Number(hit[1]), structure] as const] : [];
})
.sort((a, b) => a[0] - b[0]);
if (!picked.length) return null;
const [n, structure] = picked[0];
const cm = num(values[`chute_add_${n}_thickness`], null);
const cm = num(values[`${head}_${n}_thickness`], null);
return { structure, thickness_m: round((cm && cm > 0 ? cm : CHUTE_THICKNESS_CM) / 100, 3) };
}
/** 도수로 · 돌붙임이 있으면 세트에 `chute` 로 실음(90-2). */
function withChute(spec: CulvertSetSpec, values: Record<string, unknown>): CulvertSetSpec {
const found = chute(values);
function withChute(
spec: CulvertSetSpec,
values: Record<string, unknown>,
head = "chute_add",
): CulvertSetSpec {
const found = chute(values, head);
if (found) spec.chute = found;
return spec;
}
@@ -417,17 +423,21 @@ function fordPavementSet(
: null;
const used = degree ?? fallback;
const span = width && width > 0 ? width : FORD_PAVEMENT_DEFAULT_WIDTH_M;
return {
type: "ford_pavement",
span_m: span,
// 노선 중심에서 잰 깊이. 없으면 화면이 파임을 그리지 않는다(수치를 지어내지 않는다).
depth_m: depth && depth > 0 ? depth : null,
slope_pct: used !== null ? round(Math.tan((used * Math.PI) / 180) * 100, 4) : legacy,
defaulted: defaulted(values, [
["ford_width_m", "월류 폭", span],
["ford_slope_deg", "경사각", fallback],
]),
};
return withChute(
{
type: "ford_pavement",
span_m: span,
// 노선 중심에서 잰 깊이. 없으면 화면이 파임을 그리지 않는다(수치를 지어내지 않는다).
depth_m: depth && depth > 0 ? depth : null,
slope_pct: used !== null ? round(Math.tan((used * Math.PI) / 180) * 100, 4) : legacy,
defaulted: defaulted(values, [
["ford_width_m", "월류 폭", span],
["ford_slope_deg", "경사각", fallback],
]),
},
values,
"ford_chute",
);
}
/** BOX암거 1개소의 세트 제원(구체 + 날개벽 연장). */