Initial commit
This commit is contained in:
278
QB303_MAP_DISPLAY_IMPLEMENTATION.md
Normal file
278
QB303_MAP_DISPLAY_IMPLEMENTATION.md
Normal file
@@ -0,0 +1,278 @@
|
||||
# QB303设备地图显示功能实现
|
||||
|
||||
## 🎯 功能概述
|
||||
|
||||
成功为QB303设备实现了地图显示功能,模仿无人机的上图方式,实现了从WebSocket数据获取到地图可视化的完整流程。
|
||||
|
||||
## 🚀 实现特点
|
||||
|
||||
### **1. 数据流程**
|
||||
- ✅ **WebSocket数据接收**: 监听`qb303_device_status`消息
|
||||
- ✅ **数据解析和存储**: 解析QB303特有的数据格式
|
||||
- ✅ **本地缓存**: 数据持久化到localStorage
|
||||
- ✅ **地图可视化**: 实时显示在3D地图上
|
||||
|
||||
### **2. 地图显示特性**
|
||||
- ✅ **专用图标**: QB303设备使用独特的绿色标识
|
||||
- ✅ **实时位置**: 根据经纬度和高度实时定位
|
||||
- ✅ **姿态显示**: 使用yaw角度控制设备朝向
|
||||
- ✅ **状态标签**: 显示设备编号和状态信息
|
||||
- ✅ **点击交互**: 点击设备显示详细信息
|
||||
|
||||
## 📊 数据结构
|
||||
|
||||
### **WebSocket输入数据**
|
||||
```javascript
|
||||
{
|
||||
"biz_code": "qb303_device_status",
|
||||
"data": {
|
||||
"sn": "QB303_SN_001",
|
||||
"host": {
|
||||
"battle_unit_code": "QB303_UNIT_001", // 作战单元代码(主键)
|
||||
"platform_type": 1, // 平台类型
|
||||
"health_status": 1, // 健康状态 1=正常
|
||||
"latitude": 39.9042, // 纬度
|
||||
"longitude": 116.4074, // 经度
|
||||
"altitude": 50, // 高度(米)
|
||||
"velocity": 15.5, // 总速度(m/s)
|
||||
"velocity_x": 10.2, // X轴速度
|
||||
"velocity_y": 8.5, // Y轴速度
|
||||
"velocity_z": -2.1, // Z轴速度
|
||||
"roll": 5.2, // 翻滚角(度)
|
||||
"pitch": -3.8, // 俯仰角(度)
|
||||
"yaw": 125.6, // 偏航角(度)
|
||||
"sid": "SID_001", // 系统标识
|
||||
"report_time": 1640995200000 // 上报时间
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **标准化后的设备数据**
|
||||
```javascript
|
||||
{
|
||||
equipmentId: "QB303_UNIT_001", // 使用battle_unit_code作为主键
|
||||
equipmentType: "QB303设备", // 设备类型
|
||||
category: "特种平台", // 设备分类
|
||||
status: "正常", // 运行状态
|
||||
function: "QB303平台设备", // 功能描述
|
||||
online_status: true, // 在线状态
|
||||
latitude: 39.9042, // 纬度
|
||||
longitude: 116.4074, // 经度
|
||||
altitude: 50, // 高度
|
||||
|
||||
// QB303特有字段
|
||||
velocity: 15.5, // 总速度
|
||||
velocity_x: 10.2, // X轴速度分量
|
||||
velocity_y: 8.5, // Y轴速度分量
|
||||
velocity_z: -2.1, // Z轴速度分量
|
||||
roll: 5.2, // 翻滚角
|
||||
pitch: -3.8, // 俯仰角
|
||||
yaw: 125.6, // 偏航角
|
||||
battleUnitCode: "QB303_UNIT_001", // 作战单元代码
|
||||
sn: "QB303_SN_001", // 设备序列号
|
||||
sid: "SID_001", // 系统标识符
|
||||
reportTime: 1640995200000 // 数据上报时间
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 核心实现
|
||||
|
||||
### **1. 数据处理层** (`src/pages/dataGovernanceDashboard/views/homeShow/index.vue`)
|
||||
|
||||
```javascript
|
||||
// WebSocket消息处理
|
||||
if (message.biz_code == "qb303_device_status") {
|
||||
let qbData = message.data;
|
||||
let battleUnitCode = qbData.host?.battle_unit_code || qbData.sn;
|
||||
|
||||
let qbEquipmentInfo = {
|
||||
equipmentId: battleUnitCode,
|
||||
equipmentType: 'QB303设备',
|
||||
category: getQB303Category(qbData.host?.platform_type),
|
||||
status: getQB303Status(qbData.host?.health_status),
|
||||
online_status: qbData.host?.health_status === 1,
|
||||
latitude: qbData.host?.latitude || 0,
|
||||
longitude: qbData.host?.longitude || 0,
|
||||
altitude: qbData.host?.altitude || 0,
|
||||
// ... 更多QB303特有字段
|
||||
};
|
||||
|
||||
// 添加或更新设备到列表
|
||||
const equipmentIndex = otherEquipmentList.value.findIndex(
|
||||
equipment => equipment.equipmentId === qbEquipmentInfo.equipmentId
|
||||
);
|
||||
|
||||
if (equipmentIndex !== -1) {
|
||||
Object.assign(otherEquipmentList.value[equipmentIndex], qbEquipmentInfo);
|
||||
} else {
|
||||
otherEquipmentList.value.push(qbEquipmentInfo);
|
||||
}
|
||||
|
||||
// 保存到本地存储
|
||||
localStorage.setItem("index-otherEquipmentList", JSON.stringify(otherEquipmentList.value));
|
||||
}
|
||||
```
|
||||
|
||||
### **2. 地图显示层** (`src/utils/aixiaorui.ts`)
|
||||
|
||||
```javascript
|
||||
// QB303设备数据存储
|
||||
qb303DeviceData: {
|
||||
[key: string]: any
|
||||
} = {}
|
||||
|
||||
// 加载QB303设备到地图
|
||||
加载QB303设备(key: string, data: any) {
|
||||
if (!this.qb303DeviceData[key]["deviceImage"]) {
|
||||
// 创建QB303设备图标
|
||||
const deviceImage = new mars3d.graphic.ModelEntity({
|
||||
name: "QB303设备",
|
||||
position: [data.longitude, data.latitude, data.altitude || 0],
|
||||
style: {
|
||||
url: this.getQB303DeviceIcon(),
|
||||
heading: data.yaw || 0, // 使用偏航角
|
||||
scale: 1.2,
|
||||
minimumPixelSize: 40,
|
||||
highlight: {
|
||||
silhouetteColor: "#00ff00", // 绿色高亮
|
||||
},
|
||||
label: {
|
||||
text: `QB303-${data.battleUnitCode || key}`,
|
||||
fillColor: Cesium.Color.LIME, // 绿色标签
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 添加点击事件
|
||||
deviceImage.on(mars3d.EventType.click, (event) => {
|
||||
this.emit("qb303DeviceClick", {
|
||||
equipmentId: data.equipmentId,
|
||||
deviceData: data,
|
||||
position: [data.longitude, data.latitude, data.altitude]
|
||||
});
|
||||
});
|
||||
|
||||
this.graphicLayer.addGraphic(deviceImage);
|
||||
this.qb303DeviceData[key]["deviceImage"] = deviceImage;
|
||||
} else {
|
||||
// 更新现有设备位置和姿态
|
||||
const deviceImage = this.qb303DeviceData[key]["deviceImage"];
|
||||
deviceImage.position = [data.longitude, data.latitude, data.altitude || 0];
|
||||
deviceImage.style.heading = data.yaw || 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **3. 地图集成层** (`src/components/aixiaorui/index.vue`)
|
||||
|
||||
```javascript
|
||||
// 定时加载QB303设备数据
|
||||
timer = setInterval(() => {
|
||||
// QB303设备
|
||||
if(!m3Data.qb303DeviceData){
|
||||
m3Data.qb303DeviceData={}
|
||||
}
|
||||
|
||||
// 从localStorage获取QB303设备数据
|
||||
const localQB303Data = localStorage.getItem("index-otherEquipmentList");
|
||||
if (localQB303Data) {
|
||||
const qb303Devices = JSON.parse(localQB303Data).filter(item =>
|
||||
item.equipmentType === 'QB303设备'
|
||||
);
|
||||
|
||||
qb303Devices.forEach(device => {
|
||||
const key = device.equipmentId || device.battleUnitCode;
|
||||
if (key && device.online_status) {
|
||||
if (!m3Data.qb303DeviceData[key]) {
|
||||
m3Data.qb303DeviceData[key] = {}
|
||||
}
|
||||
m3Data.qb303DeviceData[key].info = {...device}
|
||||
}
|
||||
});
|
||||
|
||||
m3Data.loadrQB303DeviceData()
|
||||
}
|
||||
}, 2 * 1000)
|
||||
|
||||
// 监听QB303设备点击事件
|
||||
m3Data.on("qb303DeviceClick",(value)=>{
|
||||
console.info("QB303设备点击事件:",value)
|
||||
alert(`QB303设备: ${value.equipmentId}\n位置: ${value.position.join(', ')}\n状态: ${value.deviceData.status || '运行中'}`)
|
||||
})
|
||||
```
|
||||
|
||||
## 🎮 使用方法
|
||||
|
||||
### **1. 测试QB303设备显示**
|
||||
|
||||
在浏览器控制台执行:
|
||||
```javascript
|
||||
// 测试单个QB303设备
|
||||
testQB303Data()
|
||||
|
||||
// 测试多个QB303设备
|
||||
testMultipleQB303Data()
|
||||
```
|
||||
|
||||
### **2. 查看设备列表**
|
||||
|
||||
在装备列表面板中:
|
||||
- 切换到"其他装备"标签页
|
||||
- 查看QB303设备列表
|
||||
- 设备显示详细的位置、速度、姿态信息
|
||||
|
||||
### **3. 地图交互**
|
||||
|
||||
在3D地图上:
|
||||
- QB303设备显示为绿色标识的图标
|
||||
- 点击设备图标查看详细信息
|
||||
- 设备会根据实时数据更新位置和朝向
|
||||
|
||||
## 🔍 关键特性
|
||||
|
||||
### **与无人机显示的差异**
|
||||
| 特性 | 无人机 | QB303设备 |
|
||||
|------|--------|-----------|
|
||||
| **图标颜色** | 蓝色/白色 | 绿色 |
|
||||
| **标签前缀** | 设备名称 | QB303- |
|
||||
| **高亮颜色** | 红色 | 绿色 |
|
||||
| **数据源** | DJI API + WebSocket | 纯WebSocket |
|
||||
| **主键字段** | device_sn | battle_unit_code |
|
||||
| **姿态控制** | attitude_head | yaw |
|
||||
|
||||
### **数据同步机制**
|
||||
1. **WebSocket实时接收** → QB303设备状态数据
|
||||
2. **数据标准化处理** → 转换为统一格式
|
||||
3. **localStorage缓存** → 本地数据持久化
|
||||
4. **定时地图同步** → 每2秒更新地图显示
|
||||
5. **实时位置更新** → 设备移动时更新位置
|
||||
|
||||
## 🚀 扩展功能
|
||||
|
||||
### **可以进一步添加的功能**
|
||||
- ✨ **轨迹显示**: 显示QB303设备的历史轨迹
|
||||
- ✨ **速度矢量**: 显示设备的运动方向和速度
|
||||
- ✨ **状态面板**: 点击设备显示详细的控制面板
|
||||
- ✨ **告警提示**: 设备异常时的视觉告警
|
||||
- ✨ **编队显示**: 多个QB303设备的编队关系
|
||||
|
||||
## 📋 注意事项
|
||||
|
||||
1. **数据格式**: QB303设备使用`battle_unit_code`作为唯一标识,与无人机的`device_sn`不同
|
||||
2. **坐标系**: 确保经纬度数据的坐标系统一致
|
||||
3. **性能优化**: 大量设备时考虑分页加载或距离过滤
|
||||
4. **错误处理**: 数据异常时的容错机制
|
||||
5. **内存管理**: 及时清理不再使用的设备图形对象
|
||||
|
||||
## ✅ 实现状态
|
||||
|
||||
- [x] QB303设备数据接收和解析
|
||||
- [x] 设备数据标准化和存储
|
||||
- [x] 地图图标显示和定位
|
||||
- [x] 实时位置和姿态更新
|
||||
- [x] 设备点击交互事件
|
||||
- [x] 与现有系统的集成
|
||||
- [x] 测试功能和调试工具
|
||||
|
||||
QB303设备的地图显示功能已经完全实现,可以像无人机一样在3D地图上实时显示设备的位置、状态和详细信息!🎯✨
|
||||
Reference in New Issue
Block a user