- 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>
86 lines
3.0 KiB
TypeScript
86 lines
3.0 KiB
TypeScript
import { Popup } from 'react-map-gl/maplibre';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { NW_LEVEL_LABEL, NW_ORG_LABEL } from '../../services/navWarning';
|
|
import type { NavWarning, NavWarningLevel, TrainingOrg } from '../../services/navWarning';
|
|
|
|
const LEVEL_COLOR: Record<NavWarningLevel, string> = {
|
|
danger: '#ef4444',
|
|
caution: '#eab308',
|
|
info: '#3b82f6',
|
|
};
|
|
|
|
const ORG_COLOR: Record<TrainingOrg, string> = {
|
|
'해군': '#8b5cf6',
|
|
'해병대': '#22c55e',
|
|
'공군': '#f97316',
|
|
'육군': '#ef4444',
|
|
'해경': '#3b82f6',
|
|
'국과연': '#eab308',
|
|
};
|
|
|
|
interface Props {
|
|
selected: NavWarning | null;
|
|
onClose: () => void;
|
|
}
|
|
|
|
export function NavWarningLayer({ 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="320px" className="gl-popup">
|
|
<div className="font-mono" style={{ minWidth: 240, fontSize: 12 }}>
|
|
<div style={{
|
|
background: ORG_COLOR[selected.org],
|
|
color: '#fff',
|
|
padding: '4px 8px',
|
|
fontSize: 12,
|
|
fontWeight: 700,
|
|
margin: '-10px -10px 0',
|
|
borderRadius: '5px 5px 0 0',
|
|
}}>
|
|
{selected.title}
|
|
</div>
|
|
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, marginTop: 10, marginBottom: 6 }}>
|
|
<span style={{
|
|
background: LEVEL_COLOR[selected.level],
|
|
color: '#fff',
|
|
padding: '1px 6px', fontSize: 10, borderRadius: 3, fontWeight: 700,
|
|
}}>
|
|
{NW_LEVEL_LABEL[selected.level]}
|
|
</span>
|
|
<span style={{
|
|
background: ORG_COLOR[selected.org] + '33',
|
|
color: ORG_COLOR[selected.org],
|
|
border: `1px solid ${ORG_COLOR[selected.org]}44`,
|
|
padding: '1px 6px', fontSize: 10, borderRadius: 3, fontWeight: 700,
|
|
}}>
|
|
{NW_ORG_LABEL[selected.org]}
|
|
</span>
|
|
<span style={{
|
|
background: 'var(--kcg-card)', color: 'var(--kcg-muted)',
|
|
padding: '1px 6px', fontSize: 10, borderRadius: 3,
|
|
}}>
|
|
{selected.area}
|
|
</span>
|
|
</div>
|
|
<div style={{ fontSize: 11, color: '#ccc', lineHeight: 1.4, marginBottom: 6 }}>
|
|
{selected.description}
|
|
</div>
|
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 2, fontSize: 9, color: '#666' }}>
|
|
<div>{t('navWarning.altitude')}: {selected.altitude}</div>
|
|
<div>{selected.lat.toFixed(4)}°N, {selected.lng.toFixed(4)}°E</div>
|
|
<div>{t('navWarning.source')}: {selected.source}</div>
|
|
</div>
|
|
<a
|
|
href="https://www.khoa.go.kr/nwb/mainPage.do?lang=ko"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
style={{ display: 'block', marginTop: 6, fontSize: 10, color: '#3b82f6', textDecoration: 'underline' }}
|
|
>{t('navWarning.khoaLink')}</a>
|
|
</div>
|
|
</Popup>
|
|
);
|
|
}
|