我正在尝试在 React 应用程序(不使用包装器)中使用 Mapbox GL JS 将 geojson 数据呈现为一个层,当用户单击按钮时数据会更新。看来我只能在“组件确实安装”useEffect 中使用 .on load 事件侦听器创建图层,并且我只能在此 .on 加载代码块的范围内向图层添加数据。每当用户单击按钮时,如何更新 Mapbox 图层数据的源,通过对本地后端的 API 调用获取新数据并在地图上呈现?
我曾尝试在文档和在线搜索此信息,但似乎只能找到“组件确实安装”上可用数据的示例,而不是通过 API 动态更新的示例。
谢谢你的帮助。
请参见下面的代码:
import React, {useEffect, useState, useRef} from 'react';
import {getLayerDataFromBackend} from './apiService/MapData';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
import {mapboxToken} from '.env';
const mapComponent = () => {
const mapContainer = useRef(null);
const map = useRef(null);
const [lng, setLng] = useState(-3.5);
const [lat, setLat] = useState(54.5);
const [zoom, setZoom] = useState(5);
const [geojsonLayerData, setGeojsonLayerData]= useState([])
const [userClickedButtonState, setUserClickedButtonState]=useState({start_date: /*today's date 00.00*/, end_date: /*today's date 23.59*/})
useEffect(() => {
if (map.current) return;
map.current = new mapboxgl.Map({
container: mapContainer.current,
style: 'mapbox://styles/mapbox/outdoors-v11',
center: [lng, lat],
zoom: zoom,
});
map.current.addControl(new mapboxgl.NavigationControl());
map.current.on('load', function () {
const geojson = {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [],
},
};
map.current.addSource('routing-data', geojson);
map.current.addLayer({
id: 'routing-layer',
type: 'line',
source: 'routing-data',
layout: {
'line-join': 'round',
'line-cap': 'round',
},
paint: {
'line-color': ['get', 'color'],
'line-width': 10,
},
});
// map.current.getSource('routing-data').setData(geojson);
// seems to be how to add data to the layer source but only works on mount within the map.current.on('load') scope
})
},[])
useEffect(() => {
getNewLayerData();
}, [userClickedButtonState]);
mapboxgl.accessToken = mapboxToken;
const getNewLayerData = () => {
getLayerDataFromBackend(
userClickedButtonState.start_date,
userClickedButtonState.end_date,
).then(res => setGeojsonLayerData(res));
};
const handleChangeGeojson = () => {
const start_date = userClickedButtonState.start_date++
const end_date = userClickedButtonState.end_date++
setUserClickedButtonState({
start_date:start_date,
end_date:end_date
})
}
return (
<div>
<button
onClick={handleChangeGeojson}
>
Download next days geojson data from backend
</button>
<div
style={{height: '50rem', marginTop: '8rem'}}
ref={mapContainer}
className="map-container"></div>
</div>
</div>
)
}
export default mapComponent