diff --git a/B05_Profile/B05_Profile_UI_Profile_Edit.ts b/B05_Profile/B05_Profile_UI_Profile_Edit.ts index e6892e8e..2679735b 100644 --- a/B05_Profile/B05_Profile_UI_Profile_Edit.ts +++ b/B05_Profile/B05_Profile_UI_Profile_Edit.ts @@ -174,6 +174,14 @@ export interface EditOverlayOptions { onStation: (chainageM: number, delta: number) => void; } +/** + * 두 측점 목록이 **같은 측점**을 가리키는 것으로 볼 누가거리 차(m). + * + * 사이드바 구조물 목록은 표기 규칙(`n+ 0.0`)대로 0.1m 로 반올림한 값을 들고 있어 종단 + * 정본의 원값과 최대 0.05m 어긋난다. 실제로 이만큼 붙은 별개 측점은 없다. + */ +const SAME_STATION_TOLERANCE_M = 0.1; + function overlayButton( repeater: { start: (action: () => void) => void }, className: string, @@ -241,19 +249,28 @@ export function createEditOverlay(options: EditOverlayOptions): HTMLElement { * 측점선 자체는 그대로라 버튼만 살짝 비켜선다. * * 확정을 거친 구조물 측점은 종단 정본(alignment.stations)에 **이미 병합**돼 있어 - * 사이드바 목록(irregular)과 이중으로 잡힌다 — 같은 chainage(소수 3자리)는 한 번만 - * 버튼을 단다(2026-08-04 사용자 보고: 구조물 측점 버튼이 2개씩 생김). + * 사이드바 목록(irregular)과 이중으로 잡힌다 — 겹치면 한 번만 버튼을 단다 + * (2026-08-04 사용자 보고: 구조물 측점 버튼이 2개씩 생김). + * + * 겹침 판정은 **거리**로 한다. 두 목록의 누가거리가 소수 3자리까지 같지 않기 때문이다 — + * 종단 정본은 원값(`85.594514`), 사이드바 목록은 표기 규칙대로 0.1m 로 반올림한 값 + * (`85.6`)을 들고 있어 키 비교로는 서로 다른 측점으로 잡혔다. 그 결과 버튼이 두 벌 생기고, + * 사이드바 쪽 버튼을 누르면 정본 측점에서 몇 mm 떨어진 **가짜 변화점**이 승격돼 그 구간 + * 기울기가 수천 %로 튀었다(2026-09-03 사용자 보고 · 실측 11,858%). */ - const alignmentStationKeys = new Set( - alignment.stations.map((station) => chainageKey(station.chainage_m)), - ); const stationPlacements = [ ...alignment.stations.map((station) => ({ chainage: station.chainage_m, plan: station.plan_elevation_m, })), ...irregular - .filter((station) => !alignmentStationKeys.has(chainageKey(station.chainage_m))) + .filter( + (station) => + !alignment.stations.some( + (merged) => + Math.abs(merged.chainage_m - station.chainage_m) <= SAME_STATION_TOLERANCE_M, + ), + ) .map((station) => ({ chainage: station.chainage_m, plan: planElevationAtSample(alignment, station.chainage_m),