스테이션바 — 측점 검색 재설계(교차 방식·배지 일치)·시점/종점 표기 체계

검색 재설계 (5단계 진화):
- 전 구간(모든 세그먼트) 검색: 현재 세그먼트는 배지가 쓰는 데이터(viewedRef)에서
  부호 교차 탐지 → 착지 배지값 == 검색값(오차 0). 타 세그먼트는 CSV 인덱스
  (가상 fps·djmd dt 보정) → 세그먼트 자동 전환+시크
- 통과 = 값을 '가로지르는' 모든 순간(선형보간) — 종전 ±20m 창 방식은 호버 구간에서
  통과 병합·착지 흔들림을 유발해 제거. 3s 채터 병합, 최근접 폴백(TOL 이내)
- 같은 값 재Enter = 무조건 다음 통과(시크 정착 지연에도 순환), 랩어라운드

시점/종점 표기 체계:
- 배지: 시점 이전 '시점-NNN'(전환점 0 연속 카운트다운), 종점 이후 '종점+NNN'
  (지나온 거리+주시거리 — 단조 증가, 통과 순간과 연속), 횡이탈 '노선밖 NNN'
- 마크: '종점'(노선 끝 통과 위치), 종점 이후 시작/끝 마크 '종점+NNN' 표기(kmText),
  종점 이후 1000m 단위 마크(종점+1000 …), fmtKm 단수 측점 보존(6+998 → 7+000 왜곡 제거)
- ViewedPoint: viewOffM·offSide·beyondM 필드 추가

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-15 16:27:30 +09:00
co-authored by Claude Fable 5
parent 87b66d9ed4
commit 0a7044d79b
2 changed files with 326 additions and 71 deletions
@@ -14,10 +14,13 @@ import { cssVars, px } from '../../utils/cssVars';
import { MileageMarker } from '../MileageMarker/MileageMarker';
import styles from './Timeline.module.scss';
/** 미터값 → "158+160" (10m 단위). 음수면 빈 문자열. */
/** 미터값 → "158+160". 10m 배수 근처(±2m)는 10m 로 스냅(GPS 잡음 정리),
* 아니면 1m 그대로 — 끝 측점이 6+998 처럼 단수일 때 7+000 으로 왜곡되지 않게. */
function fmtKm(m: number): string {
if (m < 0) return '';
const r = Math.round(m / 10) * 10;
const r1 = Math.round(m);
const r10 = Math.round(r1 / 10) * 10;
const r = Math.abs(r1 - r10) < 2 ? r10 : r1;
return `${Math.floor(r / 1000)}+${String(r % 1000).padStart(3, '0')}`;
}
@@ -129,7 +132,7 @@ export function Timeline({
// 측점값 없음(s.km<0) 또는 '그 위치에 실제 측점값이 존재하지 않음'(kmExists=false,
// 좌표 반경만으로 잡힌 통과)은 측점값 라벨을 그리지 않는다. (마커 동그라미는 별도로 유지)
if (s.km < 0 || s.kmExists === false) continue;
const w = labelW(fmtKm(s.km));
const w = labelW(s.kmText ?? fmtKm(s.km));
if (s.px - lastPx >= (lastW + w) / 2) {
showMileage[i] = true;
lastPx = s.px;
@@ -295,7 +298,7 @@ export function Timeline({
s.km >= 0 && showMileage[i] ? (
<MileageMarker
key={`stkm-${i}`}
marker={{ id: `stkm-${i}`, value: fmtKm(s.km), left: s.px, mileage: 0 }}
marker={{ id: `stkm-${i}`, value: s.kmText ?? fmtKm(s.km), left: s.px, mileage: 0 }}
/>
) : null,
)}