kcg-monitoring/frontend/src/components/korea/debug/DevCoordDebug.tsx
htlee 364a34ce10 refactor(debug): 자체 완결형 DevCoordDebug로 전환 — 프로덕션 번들 완전 제거 보장
- lazy + 동적 import로 DEV에서만 청크 로드
- mapRef 기반 이벤트 등록으로 KoreaMap 코드에 디버그 흔적 없음
- 이전 CoordDebugTool/useCoordDebug 삭제
2026-03-26 10:30:58 +09:00

91 lines
3.1 KiB
TypeScript
Raw Blame 히스토리

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* [DEBUG] 좌표 디버그 — 자체 완결형 래퍼
* KoreaMap에서 이 컴포넌트만 동적 import하면 프로덕션 번들에서 완전 제거됨.
* import, 훅, 컴포넌트 모두 이 파일 안에서 독립적으로 존재.
*/
import { useState, useEffect } from 'react';
import { Marker, Popup } from 'react-map-gl/maplibre';
import type { MapRef } from 'react-map-gl/maplibre';
interface CoordPoint {
lat: number;
lng: number;
id: number;
}
function toDMS(dd: number, axis: 'lat' | 'lng'): string {
const dir = axis === 'lat' ? (dd >= 0 ? 'N' : 'S') : (dd >= 0 ? 'E' : 'W');
const abs = Math.abs(dd);
const d = Math.floor(abs);
const mFull = (abs - d) * 60;
const m = Math.floor(mFull);
const s = ((mFull - m) * 60).toFixed(2);
return `${d}°${String(m).padStart(2, '0')}${String(s).padStart(5, '0')}${dir}`;
}
interface Props {
mapRef: React.RefObject<MapRef | null>;
}
/**
* 자체 완결형 디버그 오버레이.
* mapRef를 받아서 직접 click 이벤트를 등록/해제.
* KoreaMap의 기존 코드에 어떤 것도 섞이지 않음.
*/
export default function DevCoordDebug({ mapRef }: Props) {
const [points, setPoints] = useState<CoordPoint[]>([]);
useEffect(() => {
const map = mapRef.current?.getMap();
if (!map) return;
const handler = (e: maplibregl.MapMouseEvent) => {
if (e.originalEvent.ctrlKey || e.originalEvent.metaKey) {
e.originalEvent.preventDefault();
setPoints(prev => [...prev, { lat: e.lngLat.lat, lng: e.lngLat.lng, id: Date.now() }]);
}
};
map.on('click', handler);
return () => { map.off('click', handler); };
}, [mapRef]);
return (
<>
{points.map(cp => (
<div key={cp.id}>
<Marker longitude={cp.lng} latitude={cp.lat}>
<div style={{
width: 12, height: 12, borderRadius: '50%',
background: '#f43f5e', border: '2px solid #fff',
boxShadow: '0 0 6px rgba(244,63,94,0.8)',
}} />
</Marker>
<Popup
longitude={cp.lng}
latitude={cp.lat}
onClose={() => setPoints(prev => prev.filter(p => p.id !== cp.id))}
closeButton={true}
closeOnClick={false}
anchor="bottom"
offset={[0, -10]}
style={{ zIndex: 50 }}
>
<div style={{ fontFamily: 'monospace', fontSize: 11, lineHeight: 1.8, padding: '2px 4px', color: '#fff' }}>
<div style={{ fontWeight: 700, marginBottom: 4, borderBottom: '1px solid rgba(255,255,255,0.3)', paddingBottom: 2, color: '#93c5fd' }}>
WGS84 (EPSG:4326)
</div>
<div><b>DD</b></div>
<div style={{ paddingLeft: 8 }}>{cp.lat.toFixed(6)}°N</div>
<div style={{ paddingLeft: 8 }}>{cp.lng.toFixed(6)}°E</div>
<div style={{ marginTop: 2 }}><b>DMS</b></div>
<div style={{ paddingLeft: 8 }}>{toDMS(cp.lat, 'lat')}</div>
<div style={{ paddingLeft: 8 }}>{toDMS(cp.lng, 'lng')}</div>
</div>
</Popup>
</div>
))}
</>
);
}