- 대상선박 우클릭 컨텍스트 메뉴로 항적 조회 (6h~5d) - Mercator: PathLayer(고정) + TripsLayer(애니메이션) + ScatterplotLayer(포인트) - Globe: MapLibre 네이티브 line + arrow + circle 레이어 - rAF 직접 overlay 조작으로 React 재렌더링 방지 - SVG 아이콘 data URL 캐시로 네트워크 재요청 방지 - 항적 조회 시 자동 fitBounds (전체 항적 뷰포트 맞춤) - API 프록시 /api/ais-target/:mmsi/track 엔드포인트 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
31 lines
897 B
TypeScript
31 lines
897 B
TypeScript
/**
|
|
* Ship SVG 아이콘을 미리 fetch하여 data URL로 캐시.
|
|
* Deck.gl IconLayer가 매번 iconAtlas URL을 fetch하지 않도록
|
|
* 인라인 data URL을 전달한다.
|
|
*/
|
|
const SHIP_SVG_URL = '/assets/ship.svg';
|
|
|
|
let _cachedDataUrl: string | null = null;
|
|
let _promise: Promise<string> | null = null;
|
|
|
|
function preloadShipIcon(): Promise<string> {
|
|
if (_cachedDataUrl) return Promise.resolve(_cachedDataUrl);
|
|
if (_promise) return _promise;
|
|
_promise = fetch(SHIP_SVG_URL)
|
|
.then((res) => res.text())
|
|
.then((svg) => {
|
|
_cachedDataUrl = `data:image/svg+xml;base64,${btoa(svg)}`;
|
|
return _cachedDataUrl;
|
|
})
|
|
.catch(() => SHIP_SVG_URL);
|
|
return _promise;
|
|
}
|
|
|
|
/** 캐시된 data URL 또는 폴백 URL 반환 */
|
|
export function getCachedShipIcon(): string {
|
|
return _cachedDataUrl ?? SHIP_SVG_URL;
|
|
}
|
|
|
|
// 모듈 임포트 시 즉시 로드 시작
|
|
preloadShipIcon();
|