- logic 새 파일 다섯 — Cross_Wall_Geom(벽 1매) · Cross_Wall_Hatch_Geom(무늬 띠 · 물빼기 · 도수로 띠 · 원지반선) · Cross_Excavation_Geom(벽 터파기) · Cross_Design_Surface_Geom(암선 · 포장층) · Cross_Revetment_Geom(독립 기슭막이 배치) - logic 으로 옮김 — Body_Guard → Cross_Body_Guard · Structure_Layouts · Route_Carry_Patch(내용 그대로 · import 경로만) - inferStationInterval → common_util_station(글자표 없는 자리 · common_util_svg 는 다시 내보냄) — Node 묶음 ui_template_locale 끌림 끊음 - 부르는 쪽 import 줄 · 등록부 ts 경로 · 시험 · 도우미 경로 - test_472_3 GEOMETRY_PULLS 다섯 줄 걷음 · Wall_Hatch · Excavation · Design_Surface 세 줄은 Culvert · Box · Ford 그림 파일(518-2)이 그리기 함수로 부르는 동안 남김 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
48 lines
2.3 KiB
TypeScript
48 lines
2.3 KiB
TypeScript
/* =============================================================================
|
|
* common_util_station.ts
|
|
* 측점 화면 표기 한 벌 — B05 · B06 목록 · 폼 · 툴팁 · 종단 표시가 모두 이것을 씀
|
|
* (`common_util_svg` 가 다시 내보냄 · B05 는 `formatStation` 이름으로 가져다 씀). 가져오는 것이 없는
|
|
* 순수 함수라 서버 Node · 시험 헬퍼에서도 그대로 돎.
|
|
* ========================================================================== */
|
|
|
|
/** 측점 라벨 — "STA" 접두사 없이 `측점번호+잔여거리`(예: `4+0` · `5+20`).
|
|
* 화면 표기만 거리를 정수로(119.8 → 5+20 · 2026-09-29 사용자 확정) — 입력 · 저장값은 소수 그대로.
|
|
* `decimals = 1` = 소수 한 자리까지(B05 평면 스냅 간격 0.1 의 MC · 390-5 · 정수면 그대로 `5+0`). */
|
|
export function stationLabel(chainage: number, interval: number, decimals: 0 | 1 = 0): string {
|
|
const safeInterval = interval > 0 ? interval : 1;
|
|
let stationNumber = Math.floor((chainage + 1e-6) / safeInterval);
|
|
let remainder = chainage - stationNumber * safeInterval;
|
|
if (Math.abs(remainder) < 0.05) remainder = 0;
|
|
if (remainder >= safeInterval - 0.05) {
|
|
stationNumber += 1;
|
|
remainder = 0;
|
|
}
|
|
return stationPartsLabel(stationNumber, remainder, decimals);
|
|
}
|
|
|
|
/** 이미 나눈 측점번호 · 잔여거리의 표기 — 거리는 정수로 보이기만(`decimals = 1` = 소수 한 자리까지). */
|
|
export function stationPartsLabel(
|
|
stationNumber: number,
|
|
remainder: number,
|
|
decimals: 0 | 1 = 0,
|
|
): string {
|
|
const scale = decimals ? 10 : 1;
|
|
return `${stationNumber}+${Math.round(remainder * scale) / scale}`;
|
|
}
|
|
|
|
/** 측점 간격을 실제 측점 배열에서 되짚는다(최빈 간격). 라벨 표기의 분모다. */
|
|
export function inferStationInterval(stations: Array<{ chainage_m: number }>): number {
|
|
const counts = new Map<number, number>();
|
|
for (let index = 1; index < stations.length; index += 1) {
|
|
const difference = stations[index].chainage_m - stations[index - 1].chainage_m;
|
|
if (difference <= 0) continue;
|
|
const rounded = Math.round(difference * 10) / 10;
|
|
counts.set(rounded, (counts.get(rounded) ?? 0) + 1);
|
|
}
|
|
return (
|
|
[...counts.entries()].sort(
|
|
([intervalA, countA], [intervalB, countB]) => countB - countA || intervalB - intervalA,
|
|
)[0]?.[0] ?? 1
|
|
);
|
|
}
|