showDevicesOnMap(devices) {
// 清除旧图层
["devices-layer", "device-labels", "selection-layer"].forEach(
(layerId) => {
if (this.mapObj.getLayer(layerId)) this.mapObj.removeLayer(layerId);
}
);
if (this.mapObj.getSource("devices-source")) {
this.mapObj.removeSource("devices-source");
}
// 创建GeoJSON数据源
const geojson = {
type: "FeatureCollection",
features: devices.map((device, index) => ({
type: "Feature",
id: device.id, // 添加唯一ID用于特征状态管理
geometry: {
type: "Point",
coordinates: [device.longitude, device.latitude],
},
properties: {
...device,
index: index + 1,
isSelected: this.selectedDeviceId === device.id,
},
})),
};
// 添加数据源
this.mapObj.addSource("devices-source", {
type: "geojson",
data: geojson,
generateId: true, // 确保每个特征有唯一ID
});
// 预加载图标
const loadImage = (name, url) => {
return new Promise((resolve) => {
if (this.mapObj.hasImage(name)) return resolve();
this.mapObj.loadImage(url, (error, image) => {
if (error) throw error;
this.mapObj.addImage(name, image);
resolve();
});
});
};
Promise.all([
loadImage("jk_online", "/images/jk_online.png"),
loadImage("jk_unline", "/images/jk_unline.png"),
]).then(() => {
// 添加设备图标层
this.mapObj.addLayer({
id: "devices-layer",
type: "symbol",
source: "devices-source",
layout: {
"icon-image": [
"case",
["==", ["get", "online"], true],
"jk_online",
"jk_unline",
],
"icon-size": 0.8,
"icon-anchor": "bottom",
"icon-allow-overlap": true,
},
});
// 解决方案1:使用独立图层实现序号标签
this.mapObj.addLayer({
id: "device-labels",
type: "symbol",
source: "devices-source",
layout: {
"text-field": ["get", "index"], // 始终显示序号
"text-font": ["Noto Sans Bold"],
"text-size": 12,
"text-offset": [0, -1.8],
"text-anchor": "top",
"text-allow-overlap": true,
},
paint: {
"text-color": "#FFFFFF",
"text-halo-color": "rgba(0, 0, 0, 0.5)",
"text-halo-width": 1,
},
});
// 解决方案2:使用圆形图层模拟背景色
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-width": 1,
"circle-stroke-color": "#fff",
"circle-translate": [0, -22], // 调整位置到图标上方
},
});
});
// 解决方案3:修复点击事件报错
this.mapObj.on(
"click",
["devices-layer", "device-labels", "label-backgrounds"],
(e) => {
if (e.features.length > 0) {
const deviceId = e.features[0].properties.id;
this.toggleDeviceSelection(deviceId);
}
}
);
},
toggleDeviceSelection(deviceId) {
// 更新选中状态
const newSelectedId =
this.selectedDeviceId === deviceId ? null : deviceId;
this.selectedDeviceId = newSelectedId;
// 使用特征状态更新(高性能)
const source = this.mapObj.getSource("devices-source");
source._data.features.forEach((feature) => {
const isSelected = feature.properties.id === newSelectedId;
this.mapObj.setFeatureState(
{ source: "devices-source", id: feature.id },
{ isSelected }
);
});
// 通知父组件
this.$emit("device-selected", newSelectedId);
},没有报错,有数据但是图标和序号全都不显示
最新发布