# 기능: StationBar 완전 폴더-구동화 (하드코딩/Mock 제거) ## 목표 StationBar(영상 하단 측점 바)가 표시하는 **모든 데이터를 선택한 폴더의 파일에서** 가져오게 한다. 코드에 노선 데이터를 하드코딩하지 않는다. 폴더 CSV에 없는 정보(노선명·방향·시종점 역명·구조물)는 폴더 내 보조 파일 `.route.json`(없으면 `route.json`)에서 읽는다. ## 사용자 보고 / 현상 - 빈 화면에서도 mock 노선("신탄진"~"대전", `158k700`)이 보였음 → StationBar 폴더 로드 전 숨김으로 1차 처리 완료. - 잔여: 폴더 로드 후에도 터미널명·이정(mileage) 배지가 **mock**(ROUTE_LEGS 픽셀 앵커, Timeline 하드코딩)에서 나옴. ## 현재 소스 (감사 결과 요약) | 표시 요소 | 현재 소스 | 분류 | |----------|----------|------| | 트랙 px 경계/스케일/transform | mocks/route.ts | LAYOUT(유지) | | 방향 구간색·이정 라벨(kmLabels) | geoStore frames+stations 계산 | 이미 폴더-구동 | | 커서 이정 배지 텍스트 | `formatMileage(mileageAtPx(cursorPx))` = mock ROUTE_LEGS | ROUTE DATA → 폴더 | | 터미널명 신탄진/대전 | Timeline.tsx 하드코딩 | ROUTE DATA → route.json | | 노선명/방향/길이/시간 | mocks/routeInfo.ts (대부분 미사용) | ROUTE DATA → route.json | | 구조물(교량/터널) | mocks/segments.ts(미사용) / POI category | ROUTE DATA → route.json + POI | > mocks/{routeInfo,segments,timeline,mileage}.ts 의 다수 export는 현재 **미사용(dead)**. route.ts 의 ROUTE_LEGS만 mileage.ts 경유로 커서 배지에 실사용. ## 보조 파일 `route.json` (이미 생성: samplevideo/하행)회덕-대전조차장.route.json) ```json { "routeInfo": { "name","direction","lengthKm","durationSec","startStationName","endStationName" }, "structures": [ { "id","type":"bridge|tunnel","name","startMileage","endMileage" } ] } ``` - 위치: 영상과 같은 폴더 루트. 파일명 `.route.json` 우선, 없으면 `route.json`. UTF-8. - 모든 필드 optional. 없으면 폴더 CSV에서 유도(터미널명=첫/끝 측점 title) 또는 미표시. ## 변경 설계 (To-Be) 1. **types/geo.ts**: `RouteMeta`(routeInfo + structures) 추가, `FolderGeoData`·store shape에 `routeMeta: RouteMeta | null`. 2. **utils/geoData.ts**: `parseRouteMeta(files)` — `.route.json`/`route.json` 탐색 → `await file.text()` → `JSON.parse`. `loadFolderGeoData` 반환에 `routeMeta` 추가. 3. **store/geoStore.ts**: `routeMeta` 상태 + `loadFromFolder`에서 set, `clear()`에서 null. 4. **stationbar/StationBar.tsx**: - 커서 이정 배지: mock `mileageAtPx(cursorPx)` 대신 **폴더 데이터 기반 실제 km**(viewedRef의 km = 드론GPS 최근접 측점, 이미 계산됨) 사용. - 구조물 마커: `routeMeta.structures`(mileage→최근접 프레임 시간→px)로 생성. (POI category 보조는 유지 가능) - Timeline에 `startStationName/endStationName` 전달: `routeMeta.routeInfo` 우선, 없으면 첫/끝 측점 title. 5. **stationbar/components/Timeline/Timeline.tsx**: 하드코딩 "신탄진"/"대전" 제거 → props로 수신(없으면 빈 문자열/미표시). 6. **mocks**: 미사용 dead export는 그대로 두되(삭제 안 함), 실사용 ROUTE_LEGS 의존(커서 배지)은 4번으로 제거. LAYOUT 기하 상수는 UI 레이아웃이므로 유지. ## 완료 기준 - `npm run build -w client` 통과(타입 에러 0). - 폴더 선택 시: 커서 배지 이정·터미널명·구조물이 **route.json + 폴더 CSV**에서 나온다. mock ROUTE_LEGS/하드코딩 신탄진·대전 미사용. - route.json 없는 폴더: 크래시 없이 측점 title 기반 폴백(터미널명=첫/끝 측점) 또는 미표시. - 영상명/노선 비의존. ## 토큰 사용 기록 > 추정치(k=1,000). 측정 합계 = subagent 총 토큰. | 단계 | 에이전트 | 입력(추정) | 출력(추정) | 측정 합계 | |------|----------|-----------|-----------|----------| | ①조사 | Explore 감사(StationBar mock 매핑) | ~55k | ~7k | ~80k | | ①설계 | 본 문서 + route.json 작성 | 오케스트레이터 | — | — | | ②구현 | DEV (geoData/geoStore/types + StationBar/Timeline) | ~50k | ~5k | 55.5k | | ③검수 | 오케스트레이터 직접(빌드+grep 검증) | — | — | — | ## 구현 결과 (완료) - ✅ `route.json` 보조 파일 로딩(`.route.json`→`route.json`), geoStore `routeMeta`. - ✅ 커서 이정 배지: 폴더 데이터(viewedRef.km, 드론 GPS 최근접 측점) 기반. mock `mileageAtPx`(ROUTE_LEGS) 런타임 의존 제거(주석만 잔존). - ✅ 터미널명: route.json `routeInfo` → 폴백 첫/끝 측점 title. Timeline 하드코딩 신탄진/대전 제거(props 전환). - ✅ 구조물: route.json `structures`(mileage→시간→px), 없으면 POI category 폴백. - ✅ `npm run build -w client` 통과. mock 파일/dead export는 보존(삭제 안 함), LAYOUT 기하 상수 유지.