mapbox-gl:Style is not done loading

本文解决了一个常见的Mapbox GL JS错误,即在样式完全加载前尝试调用地图绘制方法导致的问题。通过添加一个监听器,在样式加载完成后执行绘制逻辑,确保了地图的正确显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个错误是因为画的时候样式还没加载完成,下面就调用了。
在一些论坛上也能找到别人有遇到这些问题:
https://stackoverflow.com/questions/44394573/mapbox-gl-js-style-is-not-done-loading?rq=1
https://www.javaear.com/question/44394573.html

这个时候在你调用的的方法中加一个监听:

function loadSurface(_map, option) {
            //监听等样式加载完成以后再调用
            _map.on('load', function () {
            	//完成以后再处理当前逻辑 
                _map.setLayoutProperty('regionFillLayer', 'visibility', 'visible');
                _map.setFilter('regionFillLayer', filter);
                _map.setPaintProperty('regionFillLayer', "fill-extrusion-color", {
                    "property": "REGIONNAME",
                    "type": "categorical",
                    "stops": option
                });
                _map.setPaintProperty('regionFillLayer', "fill-extrusion-height", 1);
                _map.setPaintProperty('regionFillLayer', "fill-extrusion-opacity", 0.5);
            });
        }

不知道这样讲能不能看懂 毕竟不是专业前端。简单总结就是加一个监听,实在不行加一个延迟都行,但是不保险

showDevicesOnMap(devices) { // 存储当前设备列表,用于后续更新状态 this.currentDevices = devices; // 清除旧图层和事件监听 this.removeExistingLayers(); // 创建GeoJSON数据源(确保每个特征有唯一ID) const geojson = { type: "FeatureCollection", features: devices.map((device, index) => ({ type: "Feature", id: device.channelId, // 确保id唯一 geometry: { type: "Point", coordinates: [device.longitude, device.latitude], }, properties: { ...device, index: index + 1, // isSelected: this.selectedDeviceIds.has(device.channelId), }, })), }; // 添加数据源 this.mapObj.addSource("devices-source", { type: "geojson", data: geojson, generateId: true, // 如果特征本身没有id,则生成一个 }); // 预加载图标 const loadPromises = [ this.loadImageSafe("jk_online", "/images/jk_online.png"), this.loadImageSafe("jk_unline", "/images/jk_unline.png"), ]; // 加载图标并添加图层 Promise.all(loadPromises) .then(() => { // // 添加设备图标层 this.mapObj.addLayer({ id: "devices-layer", type: "symbol", source: "devices-source", interactive: true, // 显式启用交互 layout: { "icon-image": [ "case", ["==", ["get", "online"], true], "jk_online", "jk_unline", ], "icon-size": [ "interpolate", ["linear"], ["zoom"], 10, 0.5, // 当缩放级别为10时,大小为0.5 22, 1.0, // 当缩放级别为22时,大小为1.0 ], "icon-anchor": "bottom", "icon-allow-overlap": true, // 防止图标被隐藏 }, }); // 添加序号背景层(圆形) this.mapObj.addLayer({ id: "label-backgrounds", type: "circle", source: "devices-source", paint: { "circle-radius": 10, "circle-color": [ "case", ["==", ["feature-state", "isSelected"], true], "#FF6666", "#45CCDA", ], "circle-stroke-color": "#fff", "circle-translate": [0, -28], // 向上平移,与图标位置配合 }, }); // 添加序号文本层 this.mapObj.addLayer({ id: "device-labels", type: "symbol", source: "devices-source", layout: { "text-field": ["get", "index"], "text-size": 12, "text-offset": [0, -2.4], // 调整位置到背景圆中心 "text-anchor": "center", "text-allow-overlap": true, }, paint: { "text-color": "#FFFFFF", "text-halo-color": "rgba(0, 0, 0, 0.5)", "text-halo-width": 1, }, }); // 设置初始特征状态 devices.forEach((device) => { this.mapObj.setFeatureState( { source: "devices-source", id: device.channelId }, { isSelected: this.selectedDeviceIds.has(device.channelId) } ); }); // 设置初始特征状态 this.updateFeatureStates(); // 点击事件处理 this.mapObj.off("click"); // 移除旧的监听器,避免重复绑定 this.mapObj.on("click", (e) => { const features = this.mapObj.queryRenderedFeatures(e.point, { layers: ["devices-layer"] }); if (features.length > 0) { console.log(features, '0000000000'); this.toggleDeviceSelection(features[0].properties.channelId); } }); }) .catch((error) => { console.error("图层添加失败:", error); }); }, // 选中 toggleDeviceSelection(deviceId) { console.log(deviceId, '11111111111'); // 更新选中状态 const newSelectedId = this.selectedDeviceId === deviceId ? null : deviceId; this.selectedDeviceId = newSelectedId; console.log(newSelectedId, '2222222'); // 更新所有特征的状态 // 使用Set实现多选切换 const newSelectedIds = new Set(this.selectedDeviceIds); if (newSelectedIds.has(deviceId)) { newSelectedIds.delete(deviceId); // 如果已选中,则取消 } else { newSelectedIds.add(deviceId); // 否则选中 } this.selectedDeviceIds = newSelectedIds; // 更新地图上所有特征的状态 this.updateFeatureStates(); // 立即更新特征状态 this.mapObj.setFeatureState( { source: 'devices-source', id: deviceId }, { isSelected: this.selectedDeviceIds.has(deviceId) } ); // 通知父组件 this.$emit("device-selected", newSelectedId, deviceId); }, // 更新所有特征状态 updateFeatureStates() { console.log('5555555555'); const source = this.mapObj.getSource("devices-source"); if (!source) return; // 使用设备列表而非遍历特征 this.currentDevices.forEach(device => { const isSelected = this.selectedDeviceIds.has(device.channelId); this.mapObj.setFeatureState( { source: "devices-source", id: device.channelId }, { isSelected } ); }); },选中更新的时候,有isSelected数据为true,页面不更新背景色
最新发布
07-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值