点击按钮后如何修改Mapbox地图的GeoJSON线路坐标?
问题
我有一个页面,包含一个按钮和一张基于GeoJSON数据源绘制线路的Mapbox地图。我希望用户点击按钮(按钮位于地图外部)时,修改地图上的线路坐标。请帮我解决该按钮的事件绑定问题。
以下是我认为可行但实际无效的代码:
<body> <div> <button type="button" id="sender">Send data</button> <div id="map" class="col-md-9 ms-sm-auto col-lg-9 px-md-4"></div> </div> <script> mapboxgl.accessToken = 'pk.eyJ1IjoibGFnZXJ0cmlwIiwiYSI6ImNsYWthb3gyYzBrYjAzb3FodGNqczBodGoifQ.ZN2ufFAb1kYidqr_eEE-bA'; const map = new mapboxgl.Map({ container: 'map', // Choose from Mapbox's core styles, or make your own style with Mapbox Studio style: 'mapbox://styles/mapbox/dark-v11', center: [-122.486052, 37.830348], zoom: 14 }); map.on('load', () => { map.addSource('route', { 'type': 'geojson', 'data': { 'type': 'Feature', 'properties': {}, 'geometry': { 'type': 'LineString', 'coordinates': [ [-122.483696, 37.833818], [-122.483482, 37.833174], [-122.483396, 37.8327], [-122.483568, 37.832056], [-122.48404, 37.831141], [-122.48404, 37.830497], [-122.483482, 37.82992], [-122.483568, 37.829548], [-122.48507, 37.829446], [-122.4861, 37.828802], [-122.486958, 37.82931], [-122.487001, 37.830802], [-122.487516, 37.831683], [-122.488031, 37.832158], [-122.488889, 37.832971], [-122.489876, 37.832632], [-122.490434, 37.832937], [-122.49125, 37.832429], [-122.491636, 37.832564], [-122.492237, 37.833378], [-122.493782, 37.833683] ] } } }); map.addLayer({ 'id': 'route', 'type': 'line', 'source': 'route', 'layout': { 'line-join': 'round', 'line-cap': 'round' }, 'paint': { 'line-color': '#888', 'line-width': 8 } }); map.setData(); }); const btn = document.getElementById('sender') btn.onclick = () => { map.setData('route', { 'type': 'geojson', 'data': { 'type': 'Feature', 'properties': {}, 'geometry': { 'type': 'LineString', 'coordinates': [ [-122.483482, 37.82992], [-122.483568, 37.829548], [-122.48507, 37.829446], [-122.4861, 37.828802], [-122.486958, 37.82931], [-122.487001, 37.830802], [-122.487516, 37.831683], [-122.488031, 37.832158], [-122.488889, 37.832971], ] } } }); map.addLayer({ 'id': 'route', 'type': 'line', 'source': 'route', 'layout': { 'line-join': 'round', 'line-cap': 'round' }, 'paint': { 'line-color': '#888', 'line-width': 8 } }); } </script> </body>
问题分析与修正
你的代码主要存在以下几个问题:
- Mapbox GL JS 没有
map.setData()这个全局方法,更新数据源需要通过map.getSource('数据源ID').setData()来操作 - 点击按钮时重复调用
map.addLayer('route')会报错,因为ID为route的图层已经在地图加载时创建,无需重复添加,更新数据源后地图会自动刷新线路 - 初始代码中的
map.setData()是无效调用,需要删除
修正后的完整代码:
<body> <div> <button type="button" id="sender">Send data</button> <div id="map" class="col-md-9 ms-sm-auto col-lg-9 px-md-4"></div> </div> <script> mapboxgl.accessToken = 'pk.eyJ1IjoibGFnZXJ0cmlwIiwiYSI6ImNsYWthb3gyYzBrYjAzb3FodGNqczBodGoifQ.ZN2ufFAb1kYidqr_eEE-bA'; const map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/dark-v11', center: [-122.486052, 37.830348], zoom: 14 }); map.on('load', () => { // 添加数据源和初始线路图层 map.addSource('route', { 'type': 'geojson', 'data': { 'type': 'Feature', 'properties': {}, 'geometry': { 'type': 'LineString', 'coordinates': [ [-122.483696, 37.833818], [-122.483482, 37.833174], [-122.483396, 37.8327], [-122.483568, 37.832056], [-122.48404, 37.831141], [-122.48404, 37.830497], [-122.483482, 37.82992], [-122.483568, 37.829548], [-122.48507, 37.829446], [-122.4861, 37.828802], [-122.486958, 37.82931], [-122.487001, 37.830802], [-122.487516, 37.831683], [-122.488031, 37.832158], [-122.488889, 37.832971], [-122.489876, 37.832632], [-122.490434, 37.832937], [-122.49125, 37.832429], [-122.491636, 37.832564], [-122.492237, 37.833378], [-122.493782, 37.833683] ] } } }); map.addLayer({ 'id': 'route', 'type': 'line', 'source': 'route', 'layout': { 'line-join': 'round', 'line-cap': 'round' }, 'paint': { 'line-color': '#888', 'line-width': 8 } }); }); // 绑定按钮点击事件 document.getElementById('sender').addEventListener('click', () => { // 获取数据源并更新数据 const routeSource = map.getSource('route'); if (routeSource) { routeSource.setData({ 'type': 'Feature', 'properties': {}, 'geometry': { 'type': 'LineString', 'coordinates': [ [-122.483482, 37.82992], [-122.483568, 37.829548], [-122.48507, 37.829446], [-122.4861, 37.828802], [-122.486958, 37.82931], [-122.487001, 37.830802], [-122.487516, 37.831683], [-122.488031, 37.832158], [-122.488889, 37.832971] ] } }); } }); </script> </body>
关键修改说明
- 移除了无效的
map.setData()调用 - 使用
map.getSource('route').setData()替代错误的map.setData()方法,正确更新GeoJSON数据源 - 按钮事件改用
addEventListener绑定(和onclick效果一致,但更灵活),点击时仅更新数据源,不再重复添加图层 - 添加了数据源存在性判断,避免地图未加载完成时点击按钮出现报错
内容的提问来源于stack exchange,提问作者Oleksandr Lager
相关产品推荐
相关产品推荐

