/* ============================================================================= * design_structure_pipe_calc.ts * 배관 명세 계산 — 관 길이(자동) · 보호공 높이 안내. 계산 자리 = ② TS 를 서버 Node 로: * 관 길이는 횡단 기하 `computeStoredLayouts`(B06 · 서버 Node 진입점이 같은 함수로 `pipe_length_m` 를 * 셈 · 시험 test_b06_pipe_length) 그대로 — 여기서 새로 셈하지 않음 · 화면에 보이기만(저장 안 함). * 높이 = 손 입력 · 횡단도 조정 높이는 B06 `withSpecDefaults` 가 같은 키(`*_revet_height_m`)에 실음 · * 빈 칸 안내 = 관경 기준 최소 높이(`pipeWallMinHeightM` ↔ 파이썬 `pipe_wall_min_height_m` 짝). * ========================================================================== */ import { pipeWallMinHeightM } from "../../common_util/common_util_culvert_sets"; import type { CrossSection } from "../../B06_Section/B06_Section_Api_Fetch"; import { computeStoredLayouts } from "../../B06_Section/B06_Section_Structure_Layouts"; import { PIPE_MATCH_M } from "./design_selection"; /** 횡단 측점 목록을 대는 곳 — 횡단 보기가 자료를 받으면 걸어 둠(종단만 연 동안은 없음). */ let sectionsSource: (() => readonly CrossSection[] | null) | null = null; export function setPipeSectionsSource(source: () => readonly CrossSection[] | null): void { sectionsSource = source; } /** 관 길이(m) — 그 관의 주인 측점(관 자리에서 가장 가까운 측점) 횡단 기하 값 · 못 세우면 저장된 * `pipe_length_m` · 그것도 없으면 null. */ export function pipeLengthM(chainageM: number | null): number | null { const sections = sectionsSource?.() ?? null; if (chainageM === null || !sections?.length) return null; const holders = sections.filter( (s) => Math.abs((s.culvert?.chainage_m ?? Infinity) - chainageM) < PIPE_MATCH_M, ); if (!holders.length) return null; const owner = holders.reduce((a, b) => Math.abs(b.chainage_m - chainageM) < Math.abs(a.chainage_m - chainageM) ? b : a, ); const drawn = computeStoredLayouts(owner, sections)?.culvert?.pipe?.lengthM; const length = typeof drawn === "number" && drawn > 0 ? drawn : owner.design?.pipe_length_m; return typeof length === "number" && length > 0 ? length : null; } /** 흙막이 높이 빈 칸 안내 — 관경 기준 최소 높이(엔진이 빈 칸을 이 값으로 그림). */ export function guardHeightHint(diameterMm: string): string { const d = Number(diameterMm || "1000") / 1000; return `비우면 관경 기준 ${pipeWallMinHeightM(d)}`; }