'use client' import React, { createContext, useContext, useRef, useState, ReactNode } from 'react' import { Map } from 'maplibre-gl'; // 定义MapContext的类型 interface MapContextType { mapRef: React.RefObject layers: React.RefObject mapState: MapState currentDatetime: Date | null timelineDatetime: Date | null setMap: (map: Map, layers: any[]) => void flyTo: (options: { center: [number, number]; zoom: number; duration?: number }) => void zoomIn: () => void zoomOut: () => void zoomTo: (zoom: number) => void reset: () => void clearMap: () => void setTime: (date: Date) => void setTimelineTime: (date: Date) => void isMapReady: boolean setOpacity: (opacity: number) => void opacity: React.RefObject } // 创建Context const MapContext = createContext(undefined) // Provider组件的Props类型 interface MapProviderProps { children: ReactNode } interface MapState { zoomLevel: number } // MapProvider组件 export function MapProvider({ children }: MapProviderProps) { const mapRef = useRef(null) const [isMapReady, setIsMapReady] = useState(false) const [mapState, setMapState] = useState({ zoomLevel: 11 }); const mapOpacityRef = useRef(100) const layersRef = useRef([]) const [currentDatetime, setCurrentDatetime] = useState(null) const [timelineDatetime, setTimelineDatetime] = useState(null) const setMap = (map: Map, layers: any[]) => { // 如果已经有地图实例,先清理旧的 if (mapRef.current) { // console.log('Cleaning up previous map instance...'); mapRef.current = null; } // 监听视图的缩放变化 map.on('zoom', () => { setMapState(prevState => ({ ...prevState, zoomLevel: map.getZoom() || 11 })); }); // 监听视图的中心点变化 map.on('move', () => { const center = map.getCenter() setMapState(prevState => ({ ...prevState, center: center })); }); mapRef.current = map; layersRef.current = layers; setIsMapReady(true); } const flyTo = (options: { center: [number, number]; zoom: number; duration?: number }) => { if (mapRef.current) { mapRef.current.flyTo({ center: options.center, zoom: options.zoom, duration: options.duration || 1000 }) } } const zoomIn = () => { if (mapRef.current) { mapRef.current.zoomIn() } } const zoomOut = () => { if (mapRef.current) { mapRef.current.zoomOut() } } const zoomTo = (zoom: number) => { if (mapRef.current) { mapRef.current.zoomTo(zoom) } } const setTime = (date: Date) => { setCurrentDatetime(date) } const reset = () => { if (mapRef.current) { mapRef.current.flyTo({ center: [103.851959, 1.290270], zoom: 11, duration: 1000 }) } } const clearMap = () => { if (mapRef.current) { // console.log('Clearing map instance...'); mapRef.current.remove(); mapRef.current = null; layersRef.current = []; setIsMapReady(false); setMapState({ zoomLevel: 11 }); } } const setOpacity = (opacity: number) => { if (mapRef.current) { mapOpacityRef.current = opacity mapRef.current.triggerRepaint() } } const value: MapContextType = { timelineDatetime, setTimelineTime: setTimelineDatetime, setTime, currentDatetime, mapRef, layers: layersRef, mapState, setMap, flyTo, zoomIn, zoomOut, zoomTo, reset, clearMap, isMapReady, setOpacity, opacity: mapOpacityRef } return ( {children} ) } // 自定义Hook用于使用MapContext export function useMap() { const context = useContext(MapContext) if (context === undefined) { throw new Error('useMap必须在MapProvider内部使用') } return context } // 便捷的Hook,直接返回map实例 export function useMapInstance() { const { mapRef } = useMap() return mapRef.current }