kcg-monitoring/frontend/src/components/korea/CoastGuardLayer.tsx
htlee f0c991c9ec refactor: deck.gl 전면 전환 — DOM Marker → GPU 렌더링
- deck.gl 9.2 설치 + DeckGLOverlay(MapboxOverlay interleaved) 통합
- 정적 마커 11종 → useStaticDeckLayers (IconLayer/TextLayer, SVG DataURI)
- 분석 오버레이 → useAnalysisDeckLayers (ScatterplotLayer/TextLayer)
- 불법어선/어구/수역 라벨 → deck.gl ScatterplotLayer/TextLayer
- 줌 레벨별 스케일 (0~6: 0.6x, 7~9: 1.0x, 10~12: 1.4x, 13+: 1.8x)
- NK 미사일 궤적 PathLayer 추가 + 정적 마커 클릭 Popup
- 해저케이블 날짜변경선(180도) 좌표 보정
- 기존 DOM Marker 제거로 렌더링 성능 대폭 개선

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 21:11:56 +09:00

64 lines
2.2 KiB
TypeScript

import { Popup } from 'react-map-gl/maplibre';
import { useTranslation } from 'react-i18next';
import { CG_TYPE_LABEL } from '../../services/coastGuard';
import type { CoastGuardFacility, CoastGuardType } from '../../services/coastGuard';
const TYPE_COLOR: Record<CoastGuardType, string> = {
hq: '#ff6b6b',
regional: '#ffa94d',
station: '#4dabf7',
substation: '#69db7c',
vts: '#da77f2',
navy: '#3b82f6',
};
interface Props {
selected: CoastGuardFacility | null;
onClose: () => void;
}
export function CoastGuardLayer({ selected, onClose }: Props) {
const { t } = useTranslation();
if (!selected) return null;
return (
<Popup longitude={selected.lng} latitude={selected.lat}
onClose={onClose} closeOnClick={false}
anchor="bottom" maxWidth="280px" className="gl-popup">
<div className="popup-body-sm" style={{ minWidth: 200 }}>
<div className="popup-header" style={{
background: TYPE_COLOR[selected.type],
color: selected.type === 'vts' ? '#fff' : '#000',
gap: 6, padding: '6px 10px',
}}>
{selected.type === 'navy' ? (
<span style={{ fontSize: 16 }}></span>
) : selected.type === 'vts' ? (
<span style={{ fontSize: 16 }}>📡</span>
) : (
<span style={{ fontSize: 16 }}>🚔</span>
)}
<strong style={{ fontSize: 13 }}>{selected.name}</strong>
</div>
<div style={{ display: 'flex', gap: 4, marginBottom: 6 }}>
<span style={{
background: TYPE_COLOR[selected.type],
color: selected.type === 'vts' ? '#fff' : '#000',
padding: '2px 8px', borderRadius: 3, fontSize: 10, fontWeight: 700,
}}>
{CG_TYPE_LABEL[selected.type]}
</span>
<span style={{
background: '#333', color: '#4dabf7',
padding: '2px 8px', borderRadius: 3, fontSize: 10, fontWeight: 700,
}}>
{t('coastGuard.agency')}
</span>
</div>
<div style={{ fontSize: 10, color: '#999' }}>
{selected.lat.toFixed(4)}°N, {selected.lng.toFixed(4)}°E
</div>
</div>
</Popup>
);
}