如何在react-leaflet中实现类似Ellipsis Drive的时间戳选择与地图居中组件
在React-Leaflet中实现时间戳选择与地图居中组件
1. 核心依赖准备
先安装必要的包:
npm install react-leaflet leaflet react-datepicker date-fns
2. 实现时间选择组件(支持单/范围切换)
自定义一个时间选择器,支持切换单时间戳和时间范围模式:
import React, { useState } from 'react'; import DatePicker from 'react-datepicker'; import 'react-datepicker/dist/react-datepicker.css'; const TimestampSelector = ({ onTimeChange }) => { const [isRange, setIsRange] = useState(false); const [selectedTime, setSelectedTime] = useState(new Date()); const [timeRange, setTimeRange] = useState([null, null]); const handleTimeSelect = (value) => { if (isRange) { setTimeRange(value); onTimeChange({ type: 'range', value }); } else { setSelectedTime(value); onTimeChange({ type: 'single', value }); } }; return ( <div className="timestamp-selector" style={{ padding: '10px', background: 'white', borderRadius: '4px', boxShadow: '0 2px 4px rgba(0,0,0,0.1)' }}> <div style={{ marginBottom: '8px' }}> <label> <input type="checkbox" checked={isRange} onChange={(e) => setIsRange(e.target.checked)} /> 启用时间范围选择 </label> </div> {isRange ? ( <DatePicker selectsRange startDate={timeRange[0]} endDate={timeRange[1]} onChange={handleTimeSelect} dateFormat="yyyy-MM-dd HH:mm" placeholderText="选择开始和结束时间" /> ) : ( <DatePicker selected={selectedTime} onChange={handleTimeSelect} dateFormat="yyyy-MM-dd HH:mm" showTimeSelect timeFormat="HH:mm" timeIntervals={15} placeholderText="选择时间戳" /> )} </div> ); }; export default TimestampSelector;
3. 实现地图居中控制组件
利用React-Leaflet的useMap钩子获取地图实例,实现一键居中到目标区域:
import React from 'react'; import { useMap } from 'react-leaflet'; const MapCenterControl = ({ centerCoords = [51.505, -0.09], zoom = 13 }) => { const map = useMap(); const handleCenterMap = () => { map.setView(centerCoords, zoom); }; return ( <button onClick={handleCenterMap} style={{ padding: '8px 12px', margin: '10px', background: 'white', border: 'none', borderRadius: '4px', boxShadow: '0 2px 4px rgba(0,0,0,0.1)', cursor: 'pointer' }} > 重置地图居中 </button> ); }; export default MapCenterControl;
4. 整合到React-Leaflet地图中
将两个组件与图层结合,根据选中的时间更新图层数据或参数:
import React, { useState } from 'react'; import { MapContainer, TileLayer, GeoJSON } from 'react-leaflet'; import TimestampSelector from './TimestampSelector'; import MapCenterControl from './MapCenterControl'; import 'leaflet/dist/leaflet.css'; // 模拟带时间维度的图层数据 const timeAwareGeoData = [ { timestamp: new Date('2024-01-01'), features: [/* 替换为你的GeoJSON要素数据 */] }, { timestamp: new Date('2024-01-02'), features: [/* 替换为你的GeoJSON要素数据 */] } ]; const TimeAwareMap = () => { const [currentLayerData, setCurrentLayerData] = useState(timeAwareGeoData[0].features); const handleTimeChange = (timeConfig) => { // 根据选中的时间过滤或切换图层数据 let filteredData = []; if (timeConfig.type === 'single') { const match = timeAwareGeoData.find(item => item.timestamp.toDateString() === timeConfig.value.toDateString() ); filteredData = match?.features || []; } else { filteredData = timeAwareGeoData .filter(item => item.timestamp >= timeConfig.value[0] && item.timestamp <= timeConfig.value[1] ) .flatMap(item => item.features); } setCurrentLayerData(filteredData); }; return ( <div style={{ height: '100vh', width: '100%' }}> <MapContainer center={[51.505, -0.09]} zoom={13} style={{ height: '100%', width: '100%' }}> <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' /> <GeoJSON data={currentLayerData} /> {/* 挂载时间选择组件到地图右上角 */} <div style={{ position: 'absolute', top: '10px', right: '10px', zIndex: 1000 }}> <TimestampSelector onTimeChange={handleTimeChange} /> </div> {/* 挂载地图居中控件到地图左下角 */} <div style={{ position: 'absolute', bottom: '10px', left: '10px', zIndex: 1000 }}> <MapCenterControl /> </div> </MapContainer> </div> ); }; export default TimeAwareMap;
关键说明
- 时间选择逻辑:根据单时间/范围模式,过滤对应时间维度的图层数据,更新
GeoJSON组件的data属性;如果是带时间参数的TileLayer(比如WMS服务),可以动态修改url中的时间参数实现图层切换。 - 地图居中:通过
useMap获取Leaflet原生地图实例,调用setView方法实现精准居中,可自定义默认中心点和缩放级别。 - 样式自定义:可根据需求调整组件的位置、外观,匹配目标UI风格。
内容的提问来源于stack exchange,提问作者Mirza Zohaib Baig
相关产品推荐
相关产品推荐

