Files
Aislo/A00_Common/design/logic/design_calc_node_route.ts
T

60 lines
2.6 KiB
TypeScript

/* =============================================================================
* A00_Common/design/logic/design_calc_node_route.ts
* 계산 Node 입구(`design_calc_node.ts`)의 노선 몫(PLAN 511-B B-5) — 화면 노선 편집과 같은 TS.
*
* route.polyline 입력 route_polyline { points · curve_flags · radii · locks · arcs · min_radius_m } →
* { cleaned: 겹친 점(0.5 m) 뺀 노드 · nodes: 노드 요약(cleaned 자리) · vertices: 선 ·
* curves: 곡선(node_first · last = cleaned 자리) · edits: 곡선표 편집표 }
* — 서버 노선 저장 `_write_planned_polyline`(편집 갈래 · 파이썬은 파일 꼴 반올림만)
* ========================================================================== */
import {
buildEditedPolyline,
DUPLICATE_TOLERANCE_M,
type Vertex,
} from "../../../B05_Profile/logic/B05_Profile_UI_RouteEdit_Curve";
import { nodeEdits } from "../../../B05_Profile/logic/B05_Profile_UI_RouteEdit_Edits";
export interface RouteInputs {
route_polyline?: {
points: Vertex[];
curve_flags?: Array<boolean | null> | null;
radii?: Array<number | null> | null;
locks?: Array<string | null> | null;
arcs?: Array<number | null> | null;
min_radius_m: number;
};
}
/** id → 셈(입구 `RUNNERS` 에 얹음). */
export function routeRunners(inputs: RouteInputs): Record<string, () => unknown> {
return {
"route.polyline": () => {
const at = inputs.route_polyline;
if (!at) throw new Error("노선 입력(route_polyline) 없음");
const flags = at.curve_flags ?? null;
const radii = at.radii ?? null;
// 겹친 점을 편집값과 함께 거름 — 곡선 자리 번호 = 저장 노드 자리(파이썬 `build_planned_polyline`)
const cleaned: Vertex[] = [];
const on: boolean[] = [];
const forced: Array<number | null> = [];
at.points.forEach((point, index) => {
const last = cleaned[cleaned.length - 1];
if (last && Math.hypot(point[0] - last[0], point[1] - last[1]) <= DUPLICATE_TOLERANCE_M)
return;
cleaned.push(point);
on.push(flags && index < flags.length ? Boolean(flags[index]) : true);
forced.push(radii && index < radii.length ? radii[index] : null);
});
const line = buildEditedPolyline(cleaned, on, forced, at.min_radius_m);
return {
cleaned,
nodes: line.nodes,
vertices: line.vertices,
curves: line.curves,
edits: nodeEdits(at.points, flags, radii, at.locks ?? null, at.arcs ?? null),
};
},
};
}