60 lines
2.6 KiB
TypeScript
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),
|
|
};
|
|
},
|
|
};
|
|
}
|