Files
dronevideoplayer/docs/history/2026-06-17_지리정보-측점-프레임-맵핑구조-분석.md
minsung eaf7134309 fix: 히스토리 검증 훅 UTF-8 강제 + 측점 맵핑 문서 추가
- guard-history-fields.py: Windows cp949 stdin에서 한글 필드 정규식
  미스매치로 발생하던 false block 및 에러 mojibake 수정 (stdin/stderr UTF-8 강제)
- docs/geo-station-mapping.html: 지리정보·측점·프레임 맵핑 구조 +
  station 기준 재생 설계 문서
- docs/history: 2026-06-17 맵핑 구조 분석 기록

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 09:31:34 +09:00

4.0 KiB

지리정보 + 측점 + 프레임 맵핑 구조 분석

작업일: 2026-06-17 작업명: 지리정보·측점·프레임 맵핑 구조 소스 분석 + station 기준 재생 HTML 문서화 소요 시간: 18분 Context 사용량: input 60k / output 8k tokens 이슈: #0


목적

영상 프레임 ↔ 측점 ↔ 지리정보(POI/중심선)가 현재 소스에서 어떻게 맵핑되는지 코드 기반으로 파악. 추가로 "시간 기준이 아닌 station(측점) 기준 재생"을 위한 맵핑 구조를 HTML 문서로 출력.

분석 대상 파일

핵심 결론

맵핑 키 = 프레임 번호

  • 드론 CSV의 frame_cnt = 영상 프레임 ↔ GPS+자세 연결고리
  • time = frame / fps
  • fps 불일치 발견: 클라 VIDEO_FPS = 30000/1001 = 29.97, 서버 DEFAULT_FPS = 30. seek는 frame번호 기반이라 실害 적으나 서버 FrameMatch.time 부정확.

데이터 소스 (GEO_DATA_DIR 기본 samplevideo/)

  1. *회덕*.csv — 드론 비행로그 (frame_cnt, lat, lon, alt, yaw, pitch, roll, focal_len)
  2. building/*POI*위경도*.csv — 지장물 (타원체고 버전 우선)
  3. building/*측점*위경도*.csv — 측점
  4. pythonsource/input/center.csv — 선로 중심선 224점 (타원체고 col5)
  5. *.srt — terrain offset (로드만, 거의 미사용)

투영 파이프라인

geo(lat,lon,z) → ENU world(m) → 카메라 상대벡터 → 회전(yaw/pitch/roll) → 핀홀 투영 px,py(0~1)
  • 월드 원점 = 첫 측점 (측량 기준점), 드론 frame[0] 아님 → 드론 GPS 오차 회피
  • 서버/클라 투영 구현 2벌 (서버=cos(lat) 평면근사, 클라=EPSG:5186 TM proj4) — 정밀도 차이

두 방향 질의

  • findFramesForPoi(name): 측점명 → 전 프레임 투영 → FOV 안 → 연속구간 그룹화(GAP=30) → 구간별 중심 프레임. (StationVerify 점프)
  • findPoisForFrame(n): 프레임 → 보이는 POI 목록.

클라 실시간 오버레이

  • idle time에 Map<frameNum, {stationLabels, poiMarkers}> 사전계산
  • RAF 루프: Map 조회 + frameNum→+1 보간 + EMA 스무딩 → canvas
  • 측점은 투영 전 가장 가까운 중심선 점에 스냅 (nearestCL, z도 중심선값)
  • smoothFrame: 드론 자세 ±N프레임 이동평균으로 GPS/IMU 노이즈 제거

측점 순서

  • stationOrder: title \d+K\d+ 파싱 = km측점 ("12K345" = 12.345km). 서버/클라 동일 함수.

Station 기준 재생 관점

현재 구조는 "시간(프레임) → 지리정보" 단방향 표시 중심. station 기준 재생 = 측점 → 대표 프레임 → seek 역방향이 핵심.

  • 이미 존재하는 빌딩블록: findFramesForPoi (측점→최적 프레임), onSeekToFrame (프레임→currentTime(frame/fps)).
  • station 기준 타임라인을 만들려면: 전 측점에 대해 findFramesForPoi 1회 일괄 호출 → 측점별 대표 프레임 테이블 구성 → km 순 정렬 → 측점 간 이동 = seek.
  • 산출물: 맵핑 구조 + station 기준 재생 설계를 정리한 HTML (docs/geo-station-mapping.html).

후속 참고

  • fps 불일치(30 vs 29.97) 정리 검토 가치 있음
  • 서버/클라 투영 알고리즘 통일 여부 결정 필요 (현재 클라가 정밀)
  • station 기준 재생용 측점→프레임 테이블 API(/api/geo/station-index 등) 신설 검토