- ScatterplotLayer → IconLayer (ship-triangle/gear-diamond SVG 정적 캐시) - shipIconSvg.ts: MapLibre와 동일한 삼각형/마름모 SVG + mask 모드 - 선박 COG 회전 반영 (getAngle), 어구는 회전 없음 - 모델별 색상 배지 ScatterplotLayer 추가 (각 모델 offset) - correlation 데이터 비동기 로드 후 store.updateCorrelation() 동기화 - CorrPosition에 cog 필드 추가 (세그먼트 방향 계산) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
41 lines
1.5 KiB
TypeScript
41 lines
1.5 KiB
TypeScript
/**
|
|
* deck.gl IconLayer용 SVG 아이콘 생성 유틸.
|
|
* MapLibre ship-triangle / gear-diamond 형태와 동일.
|
|
* Data URI로 캐싱하여 반복 생성 방지.
|
|
*/
|
|
|
|
const ICON_SIZE = 64;
|
|
|
|
/** 선박 삼각형 SVG (heading 0 = north, 위쪽 꼭짓점) */
|
|
function createShipTriangleSvg(): string {
|
|
const s = ICON_SIZE;
|
|
return `<svg xmlns="http://www.w3.org/2000/svg" width="${s}" height="${s}" viewBox="0 0 ${s} ${s}">
|
|
<polygon points="${s / 2},2 ${s * 0.12},${s - 2} ${s / 2},${s * 0.62} ${s * 0.88},${s - 2}" fill="white"/>
|
|
</svg>`;
|
|
}
|
|
|
|
/** 어구 마름모 SVG */
|
|
function createGearDiamondSvg(): string {
|
|
const s = ICON_SIZE;
|
|
return `<svg xmlns="http://www.w3.org/2000/svg" width="${s}" height="${s}" viewBox="0 0 ${s} ${s}">
|
|
<polygon points="${s / 2},4 ${s - 4},${s / 2} ${s / 2},${s - 4} 4,${s / 2}" fill="white"/>
|
|
</svg>`;
|
|
}
|
|
|
|
function svgToDataUri(svg: string): string {
|
|
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
|
|
}
|
|
|
|
// ── 정적 캐시 (모듈 로드 시 1회 생성) ──
|
|
const SHIP_TRIANGLE_URI = svgToDataUri(createShipTriangleSvg());
|
|
const GEAR_DIAMOND_URI = svgToDataUri(createGearDiamondSvg());
|
|
|
|
export const SHIP_ICON_MAPPING = {
|
|
'ship-triangle': { url: SHIP_TRIANGLE_URI, width: ICON_SIZE, height: ICON_SIZE, anchorY: ICON_SIZE * 0.62, mask: true },
|
|
'gear-diamond': { url: GEAR_DIAMOND_URI, width: ICON_SIZE, height: ICON_SIZE, anchorY: ICON_SIZE / 2, mask: true },
|
|
};
|
|
|
|
export const SHIP_ICON_ATLAS = SHIP_TRIANGLE_URI;
|
|
export const GEAR_ICON_ATLAS = GEAR_DIAMOND_URI;
|
|
export { ICON_SIZE };
|