- 부품 처음값 spoil_bank 형상 · 3D = none · 형상 부품 「사토(성토 채움)」 지움 - 사토 단면 셈 파이썬 · TS 짝 지움(Engine_SpoilFill · common_util_spoil_fill · spoil_fill 옵션 · fill_area_beyond) - 카드 그림 · 면적표 줄 · 모달 띠 · 고름 선 · B07 표 「사토장」 칸 지움(빈 줄로 되돌림) - B08 수량 · 유토 배분(haul-plan) 미사용 확인 · 남은 사토 값 = [저장] 서버 재계산 · 브라우저 단계 다시 셈으로 정리 - 시험 고쳐 씀: 322_1 · 349_0n · b06_spoil_fill_allocation(남은 값 정리) · spoil_fill_mirror(죽은 길) · 52_9 · cross_design_mirror · 150 · 164 · 179_4 · 316 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VmC34fsxxbweEG3RUjs3Mn
82 lines
3.9 KiB
TypeScript
82 lines
3.9 KiB
TypeScript
/* =============================================================================
|
|
* B06_Section_Cross_Enforce.ts
|
|
* 계산 묶음 cross 단계의 [확정] 보정(PLAN 349-0n) — 서버 `_enforce_stored_designs` 차례 그대로
|
|
* (미교차 넓힘 → 포장 구간 → 세월교 노면 하강). 넓힘은 `B06_Section_Cross_Stage`.
|
|
*
|
|
* facilityRanges · facilityAt 새 노선 관 · 구조물 자리 → 측점마다 포장 · 기울임 · 노면 하강.
|
|
* ⚠ ① 짝 — `B06_Section_Router_Design.py` `pavement_ranges` · `ford_surface_drops` · `paved_at` ·
|
|
* `ford_drop_at` + `B06_Section_Engine_Tilt.py` `tilt_ranges` · `tilt_args`.
|
|
* 거울 시험 `resources/tester/test_349_0n_cross_enforce_mirror.py`.
|
|
* 세트 · 포장 · 맹암거 제원은 이미 있는 짝(`buildCulvertSets` · `pavementSpecsFrom` · `underdrainSpecsFrom`).
|
|
* 순수 — 화면 · fetch · 세션 없음.
|
|
* ========================================================================== */
|
|
|
|
import { buildCulvertSets, type CulvertPipePoint } from "@util/common_util_culvert_sets";
|
|
import { catalogRow } from "@util/common_util_structure_catalog";
|
|
import {
|
|
pavementSpecsFrom,
|
|
type PavementStructureInput,
|
|
} from "@util/common_util_structure_pavement";
|
|
import { underdrainSpecsFrom, type UnderdrainInput } from "@util/common_util_structure_underdrain";
|
|
|
|
/** 포장 · 기울임 · 노면 하강 판정 폭(m) — 파이썬 `EDGE_TOLERANCE_M` · `_FORD_DROP_TOLERANCE_M`. */
|
|
const EDGE_M = 0.02;
|
|
|
|
export type FacilityStructure = PavementStructureInput &
|
|
UnderdrainInput & { structure_id?: string | null };
|
|
|
|
export interface FacilityRanges {
|
|
paved: Array<[number, number]>;
|
|
tilt: Array<[number, number, number | null]>;
|
|
drops: Array<[number, number]>;
|
|
}
|
|
|
|
const num = (value: unknown): number | null => {
|
|
const parsed = typeof value === "string" && value.trim() ? Number(value) : value;
|
|
return typeof parsed === "number" && Number.isFinite(parsed) ? parsed : null;
|
|
};
|
|
|
|
/** 관 · 구조물 → 포장 구간 · 기울임 구간 · 세월교 하강(서버와 같은 차례 — 첫 것이 이김). */
|
|
export function facilityRanges(
|
|
pipes: readonly CulvertPipePoint[],
|
|
structures: readonly FacilityStructure[],
|
|
): FacilityRanges {
|
|
// ponytail: 레지스트리 기본값 없이 세트를 지음 — 물넘이 폭 · 경사를 비운 관만 기본 상수(10 m · 3°)
|
|
const sets = buildCulvertSets(pipes, {});
|
|
const pavementIds = new Set(
|
|
structures.filter((s) => catalogRow(s.type_id)?.shape === "pavement").map((s) => s.type_id),
|
|
);
|
|
const paved: FacilityRanges["paved"] = pavementSpecsFrom(structures, pavementIds).map((s) => [
|
|
s.start_m,
|
|
s.end_m,
|
|
]);
|
|
const tilt: FacilityRanges["tilt"] = [];
|
|
const drops: FacilityRanges["drops"] = [];
|
|
for (const [at, spec] of sets) {
|
|
if (spec.type === "ford_pavement") {
|
|
const half = (num(spec.span_m) ?? 0) / 2;
|
|
paved.push([at - half, at + half]);
|
|
tilt.push([at - half, at + half, num(spec.slope_pct)]);
|
|
}
|
|
const depth = num(spec.overflow_depth_m) ?? 0;
|
|
if (spec.type === "ford" && depth > 0) drops.push([at, depth]);
|
|
}
|
|
// 노면 = 표준 경사 · 암거 경사는 맹암거 하단 경계만(371-3 · 파이썬 `tilt_ranges` 짝)
|
|
for (const drain of underdrainSpecsFrom(structures))
|
|
tilt.push([drain.chainage_m, drain.chainage_m, null]);
|
|
return { paved, tilt, drops };
|
|
}
|
|
|
|
/** 그 측점의 포장 · 기울임 · 노면 하강 — 횡단 엔진 입력 칸 이름 그대로. */
|
|
export function facilityAt(ranges: FacilityRanges, chainageM: number) {
|
|
const inside = (start: number, end: number) =>
|
|
start - EDGE_M <= chainageM && chainageM <= end + EDGE_M;
|
|
const hit = ranges.tilt.find(([start, end]) => inside(start, end));
|
|
return {
|
|
paved: ranges.paved.some(([start, end]) => inside(start, end)),
|
|
tilted: hit !== undefined,
|
|
tiltPct: hit?.[2] ?? null,
|
|
surfaceDropM: ranges.drops.find(([at]) => Math.abs(chainageM - at) <= EDGE_M)?.[1] ?? 0,
|
|
};
|
|
}
|