Files
Aislo/common_util/common_util_structure_underdrain.ts
T
eomsangdonandClaude Opus 5.5 486616aabd fix(B06 맹암거): 371-3 노면 = 표준 경사 · 암거 경사 = 형상 하단 경계(높은 쪽 노면 끝 − 높이에서 내림)
- 암거 경사가 노면으로 가던 길 끊음(tilt_ranges None ↔ facilityRanges null · Cross_Refresh · design_pipeline_cross) · 측구 없음 · 낮은 쪽 한 경사 그대로
- underdrainOutline 하단 = 높은 쪽 노면 끝 z − H + 암거 경사 · 절토 교점 · 성토 교점 · 돌 띠 따라감 · 경사 비면 옛 동작
- 저장분은 tilt_pct 달라 서버가 다시 셈 · B06 · B07 같은 함수(묶음 다시 지음)
- 시험 test_288 하단 경계 · 349_0n 맹암거 자리 경사 비움

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Se7ytqbohmBQnfYpwYFnYf
2026-10-17 12:21:00 +09:00

69 lines
2.7 KiB
TypeScript

/* =============================================================================
* common_util/common_util_structure_underdrain.ts
* 맹암거(cross_underdrain · A군 점형) 제원을 횡단 측점에 얹는다(288-1).
*
* 기준 측점(0.02 m 안) 횡단 dict 에 `underdrain` = 높이 · 경사 — 횡단도가 돌 무늬 형상을 그리고,
* 설계 계산은 그 측점을 측구 없이 지대 낮은 쪽 한 경사로 기울임(`tilted`).
* 파이썬 짝 = `B06_Section/B06_Section_Engine_Tilt.py`(`load_underdrains` · `attach_underdrains`).
* 맹암거 종류 = 구조물 표 형상 underdrain(322-1).
* ========================================================================== */
import { catalogRow } from "./common_util_structure_catalog";
const EDGE_TOLERANCE_M = 0.02;
/** 맹암거 제원 — 높이 · 경사가 비면 null(높이 없으면 형상 없음 · 경사 = 형상 하단 경계 · 없으면 노면과 평행 · 371-3). */
export interface UnderdrainSpec {
structure_id: string | null;
chainage_m: number;
height_m: number | null;
slope_pct: number | null;
}
export interface UnderdrainInput {
structure_id?: string | null;
type_id: string;
chainage_m?: number | null;
start_m?: number | null;
options?: Record<string, unknown> | null;
}
const positive = (value: unknown): number | null => {
const parsed = value === "" || value === null || value === undefined ? NaN : Number(value);
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
};
/** 구조물 목록의 맹암거 제원(파이썬 `load_underdrains` 짝). */
export function underdrainSpecsFrom(structures: readonly UnderdrainInput[]): UnderdrainSpec[] {
return structures.flatMap((structure) => {
const at = structure.chainage_m ?? structure.start_m;
if (catalogRow(structure.type_id)?.shape !== "underdrain" || typeof at !== "number") return [];
const options = structure.options ?? {};
return [
{
structure_id: structure.structure_id ?? null,
chainage_m: at,
height_m: positive(options.culvert_height_m),
slope_pct: positive(options.culvert_slope_pct),
},
];
});
}
/** 기준 측점 횡단 dict 에 `underdrain` 을 얹는다(옛 값은 걷음) — 얹은 개수(파이썬 `attach_underdrains` 짝). */
export function attachUnderdrainSpecs(
sections: Array<Record<string, unknown>>,
specs: readonly UnderdrainSpec[],
): number {
let attached = 0;
for (const section of sections) {
delete section.underdrain;
const chainage = Number(section.chainage_m);
const hit = specs.find((spec) => Math.abs(spec.chainage_m - chainage) <= EDGE_TOLERANCE_M);
if (!hit) continue;
section.underdrain = { ...hit };
attached += 1;
}
return attached;
}