You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击按钮后如何修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 10:05:37