首页| 论坛| 消息
主题:有难度哦/Qt基于通用地图组件实现航迹规划和模拟/动态标注轨迹线/带序号和方向箭头指示
liudianwu发表于 2025-10-09 08:15
## 一、前言说明
### 1、功能概述
航迹规划功能允许用户在地图上通过单击操作逐个添加航线途经点,系统自动生成带有方向指示的连续航迹线,并支持对航线进行动态编辑。主要功能包括:
- 支持在地图上单击添加标注点,点位按添加顺序自动递增编号;
- 自动生成带箭头方向指示的航迹线,清晰展示航行方向;
- 实现航线标注点的拖曳编辑,实时更新航迹与箭头方向;
- 支持删除指定航点或清空全部航点,删除后自动重排序并重绘航线;
- 地图上的标注点与表格数据联动:点击地图点可选中对应表格行,选中表格行时地图点自动高亮;
- 航点支持带序号图标的可视化显示,提升可读性;
- 航线数据支持自动加载与持久化保存,保障用户体验连续性。
### 2、核心难点与技术实现
#### 2.1 **通用化方向箭头绘制**
尽管部分主流地图平台(如百度地图、高德地图)提供了原生的箭头线绘制接口,但其样式固定、扩展性差,难以满足多样化业务场景的需求。为此,系统采用**基于标注点的通用化箭头实现方案**,确保兼容所有支持标注点(Marker)的地图组件。
具体实现思路如下:
- 在每两个相邻航点之间,计算其连线的方位角(即方向角);
- 根据计算出的角度,动态生成一个代表箭头方向的标注点;
- 该箭头标注点使用自定义图标(如SVG箭头图像),并通过设置旋转属性(rotation)与航向保持一致;
- 箭头图标可灵活替换,仅需更换图片资源即可适配不同视觉风格,极大增强了系统的可维护性与一致性。
此方法避免了依赖特定地图厂商的高级绘图接口,实现了“一次开发,多平台适配”的目标。
#### 2.2 **航点拖曳编辑与实时更新机制**
为提升交互体验,系统支持用户直接在地图上拖动航点以调整航线。此功能的核心挑战在于:**拖动一个航点时,需同步更新与其相邻的两条航段及其对应的箭头方向**。
实现方案如下:
- 为每个航点标注绑定“拖曳开始”与“拖曳结束”事件监听;
- 拖曳过程中,实时获取当前鼠标位置,更新该航点坐标;
- 动态重新计算受影响的前后两段航迹线的坐标数据,并刷新对应的折线(Polyline)对象;
- 同时重新计算相邻两段航迹的方向角,更新前后两个箭头标注点的旋转角度;
- 拖曳结束后,触发数据持久化,保存最新航线状态。
得益于前期地图组件良好的事件封装机制,各类覆盖物的事件监听可按需绑定与解绑,保证了系统性能与稳定性。

## 二、效果图

## 三、代码使用
```cpp
#include "frmmapdrawmarkerline.h"
#include "ui_frmmapdrawmarkerline.h"
#include "qthelper.h"
#include "maphelper.h"
#include "webview.h"
#include "mapdrawmarkerline.h"
frmMapDrawMarkerLine::frmMapDrawMarkerLine(QWidget *parent) : QWidget(parent), ui(new Ui::frmMapDrawMarkerLine)
{
ui->setupUi(this);
this->initForm();
this->initTable();
this->loadTable();
//mapObj->load();
QTimer::singleShot(500, mapObj, SLOT(load()));
//QMetaObject::invokeMethod(mapObj, "load", Qt::QueuedConnection);
}
frmMapDrawMarkerLine::~frmMapDrawMarkerLine()
{
delete ui;
}
void frmMapDrawMarkerLine::initForm()
{
//设置右侧固定宽度
ui->frameRight->setFixedWidth(AppData::RightWidth);
flag = "moveMarker";
center = "121.56358,31.11566";
//实例化浏览器控件并加入到布局
webView = new WebView(this);
webView->setLayout(ui->gridLayout);
connect(webView, SIGNAL(loadSuccess()), this, SLOT(on_btnDrawMarkerLine_clicked()));
//实例化地图类
MapCore mapCore = (MapCore)AppConfig::MapDrawCore;
int zoom = MapHelper::getMapZoom(mapCore, this->objectName());
mapObj = MapHelper::getMapObj(this, mapCore);
mapObj->setWebView(webView);
mapObj->setSaveFile(SaveFile);
mapObj->setMapLocal(AppConfig::MapDrawLocal);
mapObj->setMapType(AppConfig::MapDrawType);
mapObj->setCenterPoint(center);
mapObj->setZoom(zoom);
//实例化封装类
drawMarkerLine = new MapDrawMarkerLine(this);
connect(drawMarkerLine, SIGNAL(updatePoints()), this, SLOT(on_btnGetMarkerLine_clicked()));
connect(drawMarkerLine, SIGNAL(markerClick(QString)), this, SLOT(markerClick(QString)));
connect(drawMarkerLine, SIGNAL(receivePoints(QStringList)), this, SLOT(receivePoints(QStringList)));
connect(webView, SIGNAL(receiveDataFromJs(QStr

浏览大图
下一页 (1/6)
回帖(0):

全部回帖(0)»
最新回帖
收藏本帖
发新帖