import { useRef, useEffect, useCallback } from 'react' import { MapboxOverlay } from '@deck.gl/mapbox' import type { Layer } from '@deck.gl/core' import type maplibregl from 'maplibre-gl' /** * MapLibre + Deck.gl MapboxOverlay 통합 관리 훅 * * - MapboxOverlay 생성/제거 라이프사이클 * - setLayers()로 Deck.gl 레이어 동적 업데이트 * - pickObject()로 클릭/호버 인터랙션 */ export function useMapInstance(map: maplibregl.Map | null) { const overlayRef = useRef(null) // Overlay 초기화 + 정리 useEffect(() => { if (!map) return const initOverlay = () => { if (overlayRef.current) return const overlay = new MapboxOverlay({ interleaved: false, layers: [], }) map.addControl(overlay) overlayRef.current = overlay } if (map.loaded()) { initOverlay() } else { map.on('load', initOverlay) } return () => { map.off('load', initOverlay) if (overlayRef.current) { try { map.removeControl(overlayRef.current) } catch { // 맵이 이미 제거된 경우 } overlayRef.current.finalize() overlayRef.current = null } } }, [map]) /** Deck.gl 레이어 배열 업데이트 */ const setLayers = useCallback((layers: Layer[]) => { overlayRef.current?.setProps({ layers }) }, []) /** 특정 좌표의 객체 피킹 */ const pickObject = useCallback( (x: number, y: number, layerIds?: string[]) => { if (!overlayRef.current) return null try { return overlayRef.current.pickObject({ x, y, layerIds }) ?? null } catch { return null } }, [], ) return { overlayRef, setLayers, pickObject } }