diff --git a/app/map-context.tsx b/app/map-context.tsx index 29a0934..dc06d43 100644 --- a/app/map-context.tsx +++ b/app/map-context.tsx @@ -1,7 +1,8 @@ 'use client' import React, { createContext, useContext, useRef, useState, ReactNode } from 'react' -import Map from 'ol/Map'; +// import Map from 'ol/Map'; +import { Map } from 'maplibre-gl'; import { fromLonLat } from 'ol/proj'; // 定义MapContext的类型 @@ -44,20 +45,23 @@ export function MapProvider({ children }: MapProviderProps) { const setMap = (map: Map, layers: any[]) => { // 监听视图变化事件 - const view = map.getView(); + // const view = map.getView(); // 监听视图的缩放变化 - view.on('change:resolution', () => { + map.on('zoom', () => { setMapState(prevState => ({ ...prevState, - zoomLevel: view.getZoom() || 11 + zoomLevel: map.getZoom() || 11 })); }); // 监听视图的中心点变化 - view.on('change:center', () => { - const center = view.getCenter() - + map.on('move', () => { + const center = map.getCenter() + setMapState(prevState => ({ + ...prevState, + center: center + })); }); mapRef.current = map; @@ -67,8 +71,14 @@ export function MapProvider({ children }: MapProviderProps) { const flyTo = (options: { center: [number, number]; zoom: number; duration?: number }) => { if (mapRef.current) { - mapRef.current.getView().animate({ - center: fromLonLat(options.center), + // mapRef.current.getView().animate({ + // center: fromLonLat(options.center), + // zoom: options.zoom, + // duration: options.duration || 1000 + // }) + + mapRef.current.flyTo({ + center: options.center, zoom: options.zoom, duration: options.duration || 1000 }) @@ -78,19 +88,22 @@ export function MapProvider({ children }: MapProviderProps) { const zoomIn = () => { if (mapRef.current) { - mapRef.current.getView().setZoom(mapRef.current.getView().getZoom()! + 1) + // mapRef.current.getView().setZoom(mapRef.current.getView().getZoom()! + 1) + mapRef.current.zoomIn() } } const zoomOut = () => { if (mapRef.current) { - mapRef.current.getView().setZoom(mapRef.current.getView().getZoom()! - 1) + // mapRef.current.getView().setZoom(mapRef.current.getView().getZoom()! - 1) + mapRef.current.zoomOut() } } const zoomTo = (zoom: number) => { if (mapRef.current) { - mapRef.current.getView().setZoom(zoom) + // mapRef.current.getView().setZoom(zoom) + mapRef.current.zoomTo(zoom) } } @@ -109,8 +122,13 @@ export function MapProvider({ children }: MapProviderProps) { const reset = () => { if (mapRef.current) { - mapRef.current.getView().setCenter([103.851959, 1.290270]) - mapRef.current.getView().setZoom(11) + // mapRef.current.getView().setCenter([103.851959, 1.290270]) + // mapRef.current.getView().setZoom(11) + mapRef.current.flyTo({ + center: [103.851959, 1.290270], + zoom: 11, + duration: 1000 + }) } } diff --git a/components/map-component.tsx b/components/map-component.tsx index e4c1c8e..15635e6 100644 --- a/components/map-component.tsx +++ b/components/map-component.tsx @@ -1,20 +1,19 @@ 'use client' import React, { useEffect, useRef } from 'react' -import maplibregl from 'maplibre-gl' -import VectorTileLayer from 'ol/layer/VectorTile.js' +import maplibregl, { ProjectionDefinition } from 'maplibre-gl' import 'maplibre-gl/dist/maplibre-gl.css' import { useMap } from '@/app/map-context' import { apply, applyStyle } from 'ol-mapbox-style'; import { useTheme } from '@/components/theme-provider' -import TileWMS from 'ol/source/TileWMS.js'; -import Map from 'ol/Map'; -import View from 'ol/View'; -import TileLayer from 'ol/layer/Tile'; -import { transformExtent, fromLonLat } from 'ol/proj.js'; -import StadiaMaps from 'ol/source/StadiaMaps.js'; -import XYZ from 'ol/source/XYZ'; -import 'ol/ol.css'; +// import TileWMS from 'ol/source/TileWMS.js'; +// import Map from 'ol/Map'; +// import View from 'ol/View'; +// import TileLayer from 'ol/layer/Tile'; +// import { transformExtent, fromLonLat } from 'ol/proj.js'; +// import StadiaMaps from 'ol/source/StadiaMaps.js'; +// import XYZ from 'ol/source/XYZ'; +// import 'ol/ol.css'; import { useMapLocation } from '@/hooks/use-map-location' interface MapComponentProps { @@ -23,10 +22,7 @@ interface MapComponentProps { zoom?: number } -const interval = 3 * 60 * 60 * 1000; -const step = 15 * 60 * 1000; -const frameRate = 0.5; // frames per second -const extent = transformExtent([-126, 24, -66, 50], 'EPSG:4326', 'EPSG:3857'); +// const extent = transformExtent([-126, 24, -66, 50], 'EPSG:4326', 'EPSG:3857'); export function MapComponent({ style = 'https://api.maptiler.com/maps/019817f1-82a8-7f37-901d-4bedf68b27fb/style.json?key=hj3fxRdwF9KjEsBq8sYI', @@ -40,34 +36,68 @@ export function MapComponent({ useEffect(() => { if (!mapContainer.current) return - const tileWmsLayer = new TileLayer({ - extent: extent, - source: new TileWMS({ - attributions: ['Iowa State University'], - url: 'https://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi', - params: { 'LAYERS': 'nexrad-n0r-wmst' }, - }), - opacity: 0.7, - }); + // const tileWmsLayer = new TileLayer({ + // extent: extent, + // source: new TileWMS({ + // attributions: ['Iowa State University'], + // url: 'https://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi', + // params: { 'LAYERS': 'nexrad-n0r-wmst' }, + // }), + // opacity: 0.7, + // }); - const map = new Map({ - target: mapContainer.current, - view: new View({ - center: fromLonLat(location.center), - zoom: location.zoom, - projection: 'EPSG:3857', + // const map = new Map({ + // target: mapContainer.current, + // view: new View({ + // center: fromLonLat(location.center), + // zoom: location.zoom, + // projection: 'EPSG:3857', - showFullExtent: true, - enableRotation: true + // showFullExtent: true, + // enableRotation: true - }), + // }), + // }) + + // apply(map, style).then(() => { + // map.addLayer(tileWmsLayer) + // }) + + const map = new maplibregl.Map({ + container: mapContainer.current, + style: style, + center: location.center, + zoom: location.zoom, + canvasContextAttributes: { + contextType: 'webgl2', // 请求 WebGL2 + antialias: true // 打开多重采样抗锯齿 + } }) - apply(map, style).then(() => { - map.addLayer(tileWmsLayer) + map.on('style.load', () => { + map.setProjection({ + type: 'globe' + }) + + map.addSource('nexrad', { + type: 'raster', + tiles: [ + // 'https://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r-t.cgi?service=WMS&version=1.3.0&request=GetMap&layers=nexrad-n0r-wmst&styles=&format=image/png&transparent=true&crs=EPSG:3857&bbox={bbox-epsg-3857}&width=256&height=256' + 'http://127.0.0.1:3050/tiles/{z}/{x}/{y}?time=202507220012' + ], + tileSize: 256 + }); + + map.addLayer({ + id: 'nexrad-layer', + type: 'raster', + source: 'nexrad', + paint: { 'raster-opacity': 0.8 } + }); }) - setMap(map, [tileWmsLayer]) + + setMap(map, []) }, [mapContainer]) diff --git a/package-lock.json b/package-lock.json index 6c88720..dfa0e92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3320,6 +3320,7 @@ "version": "5.6.1", "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-5.6.1.tgz", "integrity": "sha512-TTSfoTaF7RqKUR9wR5qDxCHH2J1XfZ1E85luiLOx0h8r50T/LnwAwwfV0WVNh9o8dA7rwt57Ucivf1emyeukXg==", + "license": "BSD-3-Clause", "dependencies": { "@mapbox/geojson-rewind": "^0.5.2", "@mapbox/jsonlint-lines-primitives": "^2.0.2",