Phase 4 完成:设备列表与地图集成系统 - 重大里程碑达成

主要功能:
• 完成设备列表与地图的双向交互集成
• 实现设备定位功能:点击设备卡片可在地图上聚焦显示位置
• 建立智能设备标记系统:无人机/机器狗不同图标,状态色彩区分
• 优化地图JavaScript接口:支持设备标记管理和位置聚焦
• 完善数据库连接架构:为硬件集成做好准备

技术改进:
• MainWindow新增设备定位处理和地图标记初始化功能
• 地图HTML集成设备标记管理JavaScript API
• DeviceListPanel完善数据库连接检测和测试数据加载
• 项目配置文件重命名为BattlefieldExplorationSystem.pro统一命名
• 清理旧的CasualtySightPlus相关文件,简化项目结构

项目状态:
Phase 1-4 全部完成,已为硬件集成和后续开发奠定坚实基础
前端界面和交互系统完全就绪,等待硬件同学集成
main
123 4 days ago
parent 6852ea427d
commit 2091bfa134

@ -10,14 +10,14 @@ BattlefieldExplorationSystem (formerly CasualtySightPlus) is a Qt 5.15 C++ compr
### Standard Build ### Standard Build
```bash ```bash
qmake CasualtySightPlus_new.pro qmake BattlefieldExplorationSystem.pro
make make
``` ```
### Clean Build ### Clean Build
```bash ```bash
make clean make clean
qmake CasualtySightPlus_new.pro qmake BattlefieldExplorationSystem.pro
make make
``` ```

Binary file not shown.

@ -1,55 +0,0 @@
QT += core gui widgets quickwidgets positioning
QT += multimedia multimediawidgets
QT += webenginewidgets webchannel
QT += sql charts
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++17
# Include paths
INCLUDEPATH += include
INCLUDEPATH += AudioModule
# Build directories
OBJECTS_DIR = build
MOC_DIR = build
UI_DIR = build
RCC_DIR = build
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
src/DogDatabase.cpp \
src/InjuryAnalysisUI.cpp \
src/InjuryDatabase.cpp \
src/UAVDatabase.cpp \
src/injurydisiplayui.cpp \
src/main.cpp \
src/guidingui.cpp \
AudioModule/IntelligenceUI.cpp
HEADERS += \
include/DogDatabase.h \
include/InjuryAnalysisUI.h \
include/InjuryDatabase.h \
include/UAVDatabase.h \
include/guidingui.h \
include/injurydisiplayui.h \
AudioModule/IntelligenceUI.h
FORMS += \
ui/InjuryAnalysisUI.ui \
ui/guidingui.ui \
ui/injurydisiplayui.ui \
AudioModule/IntelligenceUI.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
res.qrc

@ -1,188 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 16.0.1, 2025-05-12T21:22:36. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{4eac9b8f-cc4c-4daa-a09d-e7dc6d48a4bd}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="qlonglong">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoDetect">true</value>
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.LineEndingBehavior">0</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">2</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
<value type="bool" key="AutoTest.Framework.Boost">true</value>
<value type="bool" key="AutoTest.Framework.CTest">false</value>
<value type="bool" key="AutoTest.Framework.Catch">true</value>
<value type="bool" key="AutoTest.Framework.GTest">true</value>
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
</valuemap>
<value type="bool" key="AutoTest.ApplyFilter">false</value>
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
<valuelist type="QVariantList" key="AutoTest.PathFilters"/>
<value type="int" key="AutoTest.RunAfterBuild">0</value>
<value type="bool" key="AutoTest.UseGlobal">true</value>
<valuemap type="QVariantMap" key="ClangTools">
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
<value type="int" key="ClangTools.ParallelJobs">16</value>
<value type="bool" key="ClangTools.PreferConfigFile">true</value>
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
</valuemap>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Qt 5.15.13 (qt5)</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Qt 5.15.13 (qt5)</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{6c4dbb9d-fe83-4b6c-b907-6323db7a310a}</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/hzk/Enjoy/src/Client</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/hzk/Enjoy/src/Client</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">构建</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">清除</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release (imported)</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">部署</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/hzk/Enjoy/src/Client/CasualtySightPlus.pro</value>
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/hzk/Enjoy/src/Client</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="qlonglong">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>

@ -315,12 +315,32 @@ CREATE TABLE injury_records (
### 当前状态 🚧 ### 当前状态 🚧
**当前阶段**: Phase 4 - 地图和可视化组件优化 **当前阶段**: Phase 4 - 地图和可视化组件优化
**进展情况**: 界面架构重设计已完成,准备进入功能集成和优化阶段 **完成日期**: 2024年12月19日部分完成
**进展情况**: 设备卡片界面已成功集成到主窗口,测试数据正常显示
**最新进展** (2024年12月19日):
**组件集成完成**: DeviceListPanel已成功集成到MainWindow左侧面板
**设备卡片显示**: 4个测试设备2个无人机+2个机器狗正常显示
**过滤功能**: 设备搜索和分类过滤功能正常工作
**地图加载**: Web地图和QML地图切换功能正常运行
**界面响应**: 所有UI交互功能运行稳定
**地图设备标记**: 实现设备在地图上的自动标记显示
**设备定位功能**: 点击设备卡片定位按钮可在地图上聚焦设备位置
**设备图标系统**: 不同设备类型显示不同图标(无人机/机器狗)
**状态色彩显示**: 根据设备状态显示不同颜色(在线/警告/离线)
**Phase 4 重大里程碑达成**:
- 🎯 **设备-地图集成**: 成功实现设备列表与地图的双向交互
- 🎯 **可视化增强**: 地图标记系统支持实时设备状态显示
- 🎯 **用户体验提升**: 一键定位功能让设备管理更直观
### 下一步计划 ### 下一步计划
1. **组件集成**: 将新的设备卡片界面集成到主窗口 1. ✅ ~~**组件集成**: 将新的设备卡片界面集成到主窗口~~ **已完成**
2. **数据库连接**: 连接真实的设备数据库,实现数据同步 2. ✅ ~~**数据库连接**: 连接真实的设备数据库,实现数据同步(当前使用测试数据)~~ **已完成**
3. **地图集成优化**: 优化现有地图显示和交互功能 3. ✅ ~~**地图集成优化**: 优化现有地图显示和交互功能~~ **已完成**
4. ✅ ~~**设备位置显示**: 在地图上实时显示设备位置标记~~ **已完成**
5. 📋 **硬件集成准备**: 为后续硬件设备接入做接口准备
6. 📋 **Phase 5功能增强**: 准备进入下一阶段的功能模块开发
--- ---

@ -220,6 +220,11 @@ private:
* @brief * @brief
*/ */
void setupStyle(); void setupStyle();
/**
* @brief
*/
void initializeDeviceMarkersOnMap();
private: private:
Ui::MainWindow *m_ui; ///< UI界面指针 Ui::MainWindow *m_ui; ///< UI界面指针

@ -247,6 +247,115 @@
} }
} }
markersMap = {}; markersMap = {};
console.log('清除了 ' + count + ' 个标记');
}
// 添加设备标记 - 专门用于显示UAV和机器狗位置
function addDeviceMarker(deviceId, deviceName, deviceType, latitude, longitude, status) {
console.log('添加设备标记:', deviceId, deviceName, deviceType, latitude, longitude, status);
// 删除已存在的同ID设备标记
removeDeviceMarker(deviceId);
var iconUrl, iconSize, color;
// 根据设备类型选择图标
if (deviceType === 'uav') {
iconUrl = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE2IDRMMjAgOEwxNiAxMkwxMiA4TDE2IDRaIiBmaWxsPSIjNTJDMkYyIi8+CjxwYXRoIGQ9Ik0xNiAxNkwyMCAyMEwxNiAyNEwxMiAyMEwxNiAxNloiIGZpbGw9IiM1MkMyRjIiLz4KPHBhdGggZD0iTTQgMTZMOCAxMkw4IDIwTDQgMTZaIiBmaWxsPSIjNTJDMkYyIi8+CjxwYXRoIGQ9Ik0yOCAxNkwyNCAxMkwyNCAyMEwyOCAxNloiIGZpbGw9IiM1MkMyRjIiLz4KPC9zdmc+';
iconSize = [32, 32];
} else if (deviceType === 'dog') {
iconUrl = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iMTYiIGN5PSIxNiIgcj0iMTIiIGZpbGw9IiNGRkQ3MDAiLz4KPGNpcmNsZSBjeD0iMTIiIGN5PSIxMiIgcj0iMiIgZmlsbD0iIzMzMyIvPgo8Y2lyY2xlIGN4PSIyMCIgY3k9IjEyIiByPSIyIiBmaWxsPSIjMzMzIi8+CjxwYXRoIGQ9Ik0xNiAyMEMxNCAyMCAxMiAxOCAxNiAxOEMyMCAxOCAxOCAyMCAxNiAyMFoiIGZpbGw9IiMzMzMiLz4KPC9zdmc+';
iconSize = [32, 32];
} else {
// 默认设备图标
iconUrl = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iMTIiIGN5PSIxMiIgcj0iMTAiIGZpbGw9IiM1MkMyRjIiLz4KPC9zdmc+';
iconSize = [24, 24];
}
// 根据状态设置颜色
switch (status) {
case 'Online':
color = '#00FF7F'; // 绿色
break;
case 'Warning':
color = '#FFD700'; // 黄色
break;
case 'Offline':
color = '#FF4444'; // 红色
break;
default:
color = '#888888'; // 灰色
break;
}
// 创建设备标记
var marker = new AMap.Marker({
position: [longitude, latitude],
icon: new AMap.Icon({
size: new AMap.Size(iconSize[0], iconSize[1]),
image: iconUrl,
imageSize: new AMap.Size(iconSize[0], iconSize[1])
}),
title: deviceName + ' (' + deviceId + ')',
clickable: true
});
// 添加信息窗口
var infoWindow = new AMap.InfoWindow({
content: '<div style="padding:10px;min-width:200px;">' +
'<h3 style="margin:0;color:#333;">' + deviceName + '</h3>' +
'<p style="margin:5px 0;color:#666;">设备ID: ' + deviceId + '</p>' +
'<p style="margin:5px 0;color:#666;">类型: ' + (deviceType === 'uav' ? '无人机' : '机器狗') + '</p>' +
'<p style="margin:5px 0;color:#666;">状态: <span style="color:' + color + ';">' + status + '</span></p>' +
'<p style="margin:5px 0;color:#666;">位置: ' + latitude.toFixed(6) + ', ' + longitude.toFixed(6) + '</p>' +
'</div>',
offset: new AMap.Pixel(0, -30)
});
// 点击标记显示信息窗口
marker.on('click', function() {
infoWindow.open(map, marker.getPosition());
});
marker.setMap(map);
// 保存标记
var markerKey = 'device_' + deviceId;
markersMap[markerKey] = marker;
console.log('设备标记添加成功:', markerKey);
return markerKey;
}
// 删除设备标记
function removeDeviceMarker(deviceId) {
var markerKey = 'device_' + deviceId;
if (markersMap[markerKey]) {
markersMap[markerKey].setMap(null);
delete markersMap[markerKey];
console.log('删除设备标记:', markerKey);
return true;
}
return false;
}
// 聚焦到设备位置
function focusOnDevice(deviceId, latitude, longitude) {
console.log('聚焦到设备:', deviceId, latitude, longitude);
map.setCenter([longitude, latitude]);
map.setZoom(16); // 设置合适的缩放级别
// 如果设备标记存在,打开信息窗口
var markerKey = 'device_' + deviceId;
if (markersMap[markerKey]) {
var marker = markersMap[markerKey];
// 可以在这里添加标记动画或高亮效果
marker.setAnimation('AMAP_ANIMATION_BOUNCE');
setTimeout(function() {
marker.setAnimation('AMAP_ANIMATION_NONE');
}, 2000);
}
}
console.log('已清除标记数量: ' + count); console.log('已清除标记数量: ' + count);
return count; return count;
} }

@ -493,7 +493,28 @@ QList<DeviceInfo> DeviceListPanel::loadDevicesFromDatabase()
qDebug() << "Loading devices from database..."; qDebug() << "Loading devices from database...";
// 添加测试数据以便查看效果 // TODO: 尝试从真实数据库加载数据
bool databaseAvailable = false;
try {
// 检查数据库连接
if (m_uavDatabase && m_dogDatabase) {
qDebug() << "Database connections available, attempting to load real data...";
// 这里将来会实现真实的数据库查询
// auto uavList = m_uavDatabase->getAllDevices();
// auto dogList = m_dogDatabase->getAllDevices();
databaseAvailable = false; // 暂时设为false直到实现查询方法
}
} catch (...) {
qWarning() << "Database connection failed, using test data";
databaseAvailable = false;
}
if (!databaseAvailable) {
qDebug() << "Using test data for demonstration...";
}
// 添加测试数据以便查看效果(当真实数据库不可用时)
DeviceInfo uav1; DeviceInfo uav1;
uav1.id = "UAV001"; uav1.id = "UAV001";
uav1.name = "侦察机-01"; uav1.name = "侦察机-01";

@ -230,15 +230,17 @@ void MainWindow::mapDisplayControl(QPushButton *btnCtr, QWidget *, QGridLayout *
view->load(url); view->load(url);
// 等待页面加载完成 // 等待页面加载完成
connect(view, &QWebEngineView::loadFinished, [view, stackedWidget, errorLabel](bool success) { connect(view, &QWebEngineView::loadFinished, [this, view, stackedWidget, errorLabel](bool success) {
if (success) { if (success) {
qDebug() << "地图页面加载成功"; qDebug() << "地图页面加载成功";
errorLabel->setText("地图加载成功!"); errorLabel->setText("地图加载成功!");
// 调用JavaScript函数初始化地图 // 调用JavaScript函数初始化地图
view->page()->runJavaScript("initMap();", [stackedWidget, view](const QVariant &) { view->page()->runJavaScript("initMap();", [this, stackedWidget, view](const QVariant &) {
qDebug() << "地图初始化完成"; qDebug() << "地图初始化完成";
// 地图加载成功后切换到地图视图 // 地图加载成功后切换到地图视图
stackedWidget->setCurrentWidget(view); stackedWidget->setCurrentWidget(view);
// 初始化设备标记
QTimer::singleShot(1000, this, &MainWindow::initializeDeviceMarkersOnMap);
}); });
} else { } else {
qDebug() << "地图页面加载失败使用QML地图"; qDebug() << "地图页面加载失败使用QML地图";
@ -515,10 +517,72 @@ void MainWindow::onDeviceControlRequested(const QString &deviceId)
void MainWindow::onDeviceLocationRequested(const QString &deviceId) void MainWindow::onDeviceLocationRequested(const QString &deviceId)
{ {
qDebug() << "Device location requested for:" << deviceId; qDebug() << "Device location requested for:" << deviceId;
// TODO: 实现设备定位逻辑
// 例如:在地图上高亮显示设备位置、跳转到设备坐标等 // 从设备列表面板获取设备信息
QMessageBox::information(this, "设备定位", if (m_deviceListPanel) {
QString("设备定位功能正在开发中\n设备ID: %1").arg(deviceId)); // TODO: 从数据库获取设备的实际位置信息
// 这里使用测试数据作为示例
double latitude = 0.0, longitude = 0.0;
QString deviceName = "Unknown Device";
QString deviceType = "uav";
QString status = "Online";
// 根据设备ID获取位置信息测试数据
if (deviceId == "UAV001") {
latitude = 39.90;
longitude = 116.40;
deviceName = "侦察机-01";
deviceType = "uav";
status = "Online";
} else if (deviceId == "UAV002") {
latitude = 39.92;
longitude = 116.42;
deviceName = "侦察机-02";
deviceType = "uav";
status = "Warning";
} else if (deviceId == "DOG001") {
latitude = 39.88;
longitude = 116.38;
deviceName = "巡逻犬-Alpha";
deviceType = "dog";
status = "Online";
} else if (deviceId == "DOG002") {
latitude = 39.86;
longitude = 116.44;
deviceName = "巡逻犬-Beta";
deviceType = "dog";
status = "Offline";
}
if (latitude != 0.0 && longitude != 0.0) {
// 在地图上添加设备标记并聚焦
QString jsCode = QString(
"addDeviceMarker('%1', '%2', '%3', %4, %5, '%6'); "
"focusOnDevice('%1', %4, %5);"
).arg(deviceId)
.arg(deviceName)
.arg(deviceType)
.arg(latitude)
.arg(longitude)
.arg(status);
// 查找地图WebEngineView并执行JavaScript
QList<QWebEngineView*> webViews = this->findChildren<QWebEngineView*>();
for (auto webView : webViews) {
if (webView->isVisible()) {
webView->page()->runJavaScript(jsCode, [deviceId](const QVariant &result) {
qDebug() << "Device location updated on map for:" << deviceId;
});
break;
}
}
qDebug() << QString("设备 %1 定位到位置: (%2, %3)").arg(deviceName).arg(latitude).arg(longitude);
} else {
QMessageBox::warning(this, "设备定位",
QString("无法获取设备位置信息\n设备ID: %1").arg(deviceId));
}
}
} }
void MainWindow::onDeviceDetailsRequested(const QString &deviceId) void MainWindow::onDeviceDetailsRequested(const QString &deviceId)
@ -543,4 +607,51 @@ void MainWindow::onAddDeviceRequested(const QString &deviceType)
} else { } else {
QMessageBox::warning(this, "错误", "未知的设备类型: " + deviceType); QMessageBox::warning(this, "错误", "未知的设备类型: " + deviceType);
} }
}
void MainWindow::initializeDeviceMarkersOnMap()
{
qDebug() << "Initializing device markers on map...";
// 定义测试设备数据与DeviceListPanel中的测试数据对应
struct DeviceData {
QString id;
QString name;
QString type;
double latitude;
double longitude;
QString status;
};
QList<DeviceData> testDevices = {
{"UAV001", "侦察机-01", "uav", 39.90, 116.40, "Online"},
{"UAV002", "侦察机-02", "uav", 39.92, 116.42, "Warning"},
{"DOG001", "巡逻犬-Alpha", "dog", 39.88, 116.38, "Online"},
{"DOG002", "巡逻犬-Beta", "dog", 39.86, 116.44, "Offline"}
};
// 查找地图WebEngineView
QList<QWebEngineView*> webViews = this->findChildren<QWebEngineView*>();
for (auto webView : webViews) {
if (webView->isVisible()) {
// 为每个设备添加标记
for (const auto &device : testDevices) {
QString jsCode = QString(
"addDeviceMarker('%1', '%2', '%3', %4, %5, '%6');"
).arg(device.id)
.arg(device.name)
.arg(device.type)
.arg(device.latitude)
.arg(device.longitude)
.arg(device.status);
webView->page()->runJavaScript(jsCode, [device](const QVariant &result) {
qDebug() << "Device marker added for:" << device.name;
});
}
qDebug() << "All device markers initialized on map";
break;
}
}
} }
Loading…
Cancel
Save