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,页面不更新背景色
最新发布