기존 GhiVideo 저장소 HEAD의 트래킹 소스 362개 파일을 복제. (node_modules·storage·빌드 산출물·대용량 미디어는 .gitignore 규칙대로 제외) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
61 lines
2.2 KiB
Markdown
61 lines
2.2 KiB
Markdown
# 2026-06-23 — 드론 경로 맨앞(지평선) 오차 컷 + 경로표고 슬라이더 동적 상한
|
|
|
|
**소요 시간**: 약 15분
|
|
**Context 사용량**: input ~155k / output ~17k tokens (추정)
|
|
|
|
---
|
|
|
|
## 요청
|
|
1. 드론 궤적이 **맨 앞(진행방향 먼 쪽)** 에서 휘어/튀는 오차. 해결?
|
|
2. 경로 표고 슬라이더 상한 120의 근거 없음 → **데이터 기반 동적 상한(옵션 1)** 적용.
|
|
|
|
---
|
|
|
|
## 1. 맨 앞(지평선) 오차 — 전방 거리 컷
|
|
|
|
### 원인
|
|
z=42(지면)면 드론은 지면 위 ~20m뿐. 먼 앞쪽 점일수록 내려보는 각이 얕아져(지평선 근접) GPS·표고 오차가 화면에서 크게 증폭 → 끝이 휘어/튐. 기하적으로 신뢰 불가 구간.
|
|
|
|
### 해결 — `StationOverlay.tsx` 드론 경로 빌드 루프
|
|
진행방향 전방거리(`cc.fwd`)가 `MAX_FWD=200m`를 넘으면 그리기 중단. (i 증가=시간 진행=전방으로 이동, fwd 단조증가 → `break`로 조기 종료, 연산도 절약.)
|
|
|
|
```ts
|
|
const MAX_FWD = 200; // 전방 거리 컷(m)
|
|
for (let i = lo; i <= hi; i += STEP) {
|
|
const [la, lo2] = sm(i);
|
|
const cc = toCameraCoords(drone, la, lo2, Z, params, worldOrigin);
|
|
if ((cc.fwd ?? 0) > MAX_FWD) break; // 지평선쪽 중단
|
|
...
|
|
}
|
|
```
|
|
|
|
> 더 멀리 보고 싶으면 MAX_FWD↑, 더 깔끔히 자르려면 ↓. (드론 고도가 낮을수록 작게.)
|
|
|
|
---
|
|
|
|
## 2. 경로 표고 슬라이더 동적 상한 (옵션 1)
|
|
|
|
기존 `max={120}`은 근거 없는 라운드 값. → **중심선(centerline) 데이터의 최대 지면표고 + 10m** 로 자동 설정. 데이터 없으면 60 폴백.
|
|
|
|
```ts
|
|
import { ..., useMemo } from 'react';
|
|
const pathZMax = useMemo(() => {
|
|
let m = 0;
|
|
for (const c of storeCenterline) if (typeof c.z === 'number' && c.z > m) m = c.z;
|
|
return m > 0 ? Math.ceil(m + 10) : 60;
|
|
}, [storeCenterline]);
|
|
// 슬라이더:
|
|
<ParamRow label="경로 표고" ... max={pathZMax} ... />
|
|
```
|
|
|
|
데이터셋이 바뀌어도 그 구간 지형 최고점에 맞춰 상한이 자동 조정됨.
|
|
|
|
---
|
|
|
|
## 변경 파일
|
|
- `client/src/components/overlay/StationOverlay.tsx`
|
|
- 드론 경로 루프: `MAX_FWD=200` 전방 컷(`cc.fwd` 기준 break)
|
|
- `useMemo` import + `pathZMax`(중심선 max z +10) + 경로표고 슬라이더 `max={pathZMax}`
|
|
|
|
빌드: `index-BzoF-8z_.js` ✓
|