一、前言

实时动态轨迹经历过很多个版本的迭代,此功能最初是一个客户定制的,主要是需要在地图上动态显示GPS的运动轨迹,有个应用场景就是一个带有监控的车子,实时在运动中,后台可以接收到经纬度信息,需要绘制对应的轨迹,相当于这些摄像机点位是动态移动的,这样就可以观测到摄像机的实时位置信息,双击摄像机还可以弹出画面实时预览,很直观。

GPS运动轨迹这个功能,也需要用到js的知识,其实就是封装一个js函数,绘制对应的线条路径,这个轨迹点可能包括的信息有经度、纬度、速度、时间、是否标记、时间等信息,写个结构体封装下,方便后期拓展,是否标记的含义是是否改点同时作为一个设备点添加,分段线的含义。

后面陆续增加了可以设置旋转角度、可以过滤坐标点这两个要点,设置旋转角度采用的是内置的setRotation函数,流程是先从一堆覆盖物中通过唯一标识比如name找到当前要移动的点,然后对这个标注点调用setRotation设置要旋转的角度值,所以这里衍生了另外一个需求,如何计算两个点之间的旋转角度值,这个值必须是提前计算好的,这就要用到数学知识了,用atan2来计算,同时做矫正。

二、功能特点

  1. 定时器排队下载省市轮廓图点坐标集合存储到JS文件。
  2. 支持一个行政区域多个不规则区域下载。
  3. 自动计算行政区域的下载轮廓数量。
  4. 可精确选择省份、市区、县城,也可直接输入行政区域的名称。
  5. 可以设置下载间隔、随时开始下载和停止下载。
  6. 提供编辑边界功能,可以直接在地图上编辑好不规则区域的点集合,然后获取边界点集合数据,这个可以用来自己绘制区域拿到数据,比如某个乡镇甚至某个小区的行政区域数据,很牛逼。

三、体验地址

  1. 体验地址:https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A 提取码:o05q 文件名:bin_map.zip
  2. 国内站点:https://gitee.com/feiyangqingyun
  3. 国际站点:https://github.com/feiyangqingyun
  4. 个人主页:https://blog.csdn.net/feiyangqingyun
  5. 知乎主页:https://www.zhihu.com/people/feiyangqingyun/

四、效果图

五、相关代码

void frmMapGps::receiveDataFromJs(const QString &type, const QVariant &data)
{
if (data.isNull()) {
return;
} //qDebug() << "frmMapGps" << type << data;
QString result = data.toString();
if (type == "point") {
if (ui->ckSelectAddr->isChecked()) {
//判断哪里勾选了就设置到哪里
QString point = WebHelper::getLngLat2(result);
//判断哪里勾选了就设置到哪里
if (ui->rbtnStartAddr->isChecked()) {
ui->txtStartAddr->setText(point);
} else {
ui->txtEndAddr->setText(point);
}
}
} else if (type == "routepoints") {
//将查询路径转换成经纬度坐标点集合数据显示
routeDatas.clear();
ui->tableWidgetSource->clearContents();
//可能会有多个路径集合,目前测试下来都是一个路径集合
QStringList datas = result.split("|");
foreach (QString data, datas) {
QStringList points = data.split(";");
routeDatas << points;
int count = points.count();
ui->tableWidgetSource->setRowCount(count);
for (int i = 0; i < count; ++i) {
addItem(ui->tableWidgetSource, i, points.at(i));
}
} setInfo(0, 0, 0);
}
} void frmMapGps::runJs(const QString &js)
{
web->runJs(js);
} void frmMapGps::on_btnSearchData_clicked()
{
QString startAddr = ui->txtStartAddr->text().trimmed();
QString endAddr = ui->txtEndAddr->text().trimmed();
baidu->setRotueInfo(2, 0, startAddr, endAddr);
this->loadMap();
} void frmMapGps::moveMarker()
{
QTableWidget *tableWidget = getTableWidget();
int row = tableWidget->currentRow();
int count = tableWidget->rowCount();
if (row >= 0 && row < count) {
//找出和上一个点之间的角度
int angle = 0;
QString point = tableWidget->item(row, 1)->data(Qt::UserRole).toString();
//第一个点和最后一个点不用处理
if (row > 0 && row < count - 1) {
//上一个点坐标
QString point2 = tableWidget->item(row - 1, 1)->data(Qt::UserRole).toString();
//计算当前上一个点和当前点的旋转角度
angle = WebHelper::getAngle(point2, point);
} //执行移动设备点函数,参数带旋转角度
QString js = QString("moveMarker('%1', '%2', %3)").arg(name).arg(point).arg(angle);
runJs(js); //重新绘制轨迹点
if (ui->cboxMoveMode->currentIndex() == 0) {
//清空之前的轨迹点
js = QString("deleteOverlay('Polyline')");
runJs(js); //取出第一个点到当前焦点所在行的点组成已经走过的轨迹点集合重新绘制
QStringList points;
for (int i = 0; i <= row; ++i) {
points << tableWidget->item(i, 1)->data(Qt::UserRole).toString();
} js = QString("addPolyline('%1')").arg(points.join("|"));
runJs(js);
} //显示当前第几个数据
setInfo(angle, row + 1, count);
tableWidget->setCurrentCell(row + 1, 0);
} else {
on_btnTestData_clicked();
}
} void frmMapGps::on_btnTestData_clicked()
{
QTableWidget *tableWidget = getTableWidget();
if (ui->btnTestData->text() == "模拟轨迹") {
//限制最小数量
if (tableWidget->rowCount() < 2) {
return;
} //第一步: 添加一个标记
name = ui->txtDeviceName->text().trimmed();
if (name.isEmpty()) {
name = "马航MH370";
} //图片文件在可执行文件下的config/device目录
QString icon = "./device/device_airplane.png";
int size = 60;
QString js = QString("addMarker('%1', '', '', '', 60, '%1', 0, 0, '%2', %3)").arg(name).arg(icon).arg(size);
runJs(js); //第二步: 移到第一个点
tableWidget->setFocus();
tableWidget->setCurrentCell(0, 0);
ui->btnTestData->setText("停止模拟");
ui->tabWidget->setTabEnabled(ui->tableWidgetSource->isVisible() ? 1 : 0, false); //第三步: 启动定时器并立即执行一次
int index = ui->cboxMoveInterval->currentIndex();
timer->start(ui->cboxMoveInterval->itemData(index).toInt());
moveMarker();
} else {
//清空标记
QString js = QString("deleteMarker('%1')").arg(name);
runJs(js); //停止定时器
timer->stop();
ui->btnTestData->setText("模拟轨迹");
ui->tabWidget->setTabEnabled(ui->tableWidgetSource->isVisible() ? 1 : 0, true);
}
} void frmMapGps::on_btnCheckData_clicked()
{
if (timer->isActive()) {
return;
} //第一步: 计算总数,求平均值=实际总数/预期总数+1,预期总数>=实际总数则不用处理
int countSource = ui->tableWidgetSource->rowCount();
int countTarget = ui->txtPointCount->text().trimmed().toInt();
if (countTarget >= countSource) {
QUIHelper::showMessageBoxError("目标点数不能大于等于原数据点数!");
ui->txtPointCount->setFocus();
return;
} //第二步: 根据平均值挨个取出值
QStringList points;
int avg = countSource / countTarget + 1;
for (int i = 0; i < countSource; i += avg) {
QString point = ui->tableWidgetSource->item(i, 1)->data(Qt::UserRole).toString();
points << point;
} //必须加上末尾这个作为结束,如果刚好除尽则不用
QString point = ui->tableWidgetSource->item(countSource - 1, 1)->data(Qt::UserRole).toString();
if (points.last() != point) {
points << point;
} //第三步: 将数据重新填入筛选数据列表
int count = points.count();
ui->tableWidgetTarget->clearContents();
ui->tableWidgetTarget->setRowCount(count);
for (int i = 0; i < count; ++i) {
addItem(ui->tableWidgetTarget, i, points.at(i));
} ui->tabWidget->setCurrentIndex(1);
} void frmMapGps::on_btnDrawData_clicked()
{
if (routeDatas.count() == 0) {
QUIHelper::showMessageBoxError("请先单击查询路线获取路线的坐标点集合!");
return;
} //清空之前的轨迹点
runJs("deleteOverlay('Polyline')"); //将收到的路径点集合分线段绘制
foreach (QStringList data, routeDatas) {
QString points = data.join("|");
QString js = QString("addPolyline('%1', '#ff0000')").arg(points);
runJs(js);
}
}

Qt编写地图综合应用56-实时动态轨迹的更多相关文章

  1. Qt编写的开源帖子集合(懒人专用)

    回顾自己学习Qt以来九年了,在这九年多时间里面,从本论坛学习不到不少的东西,今天特意整了一下自己开源过的资源的帖子,整理一起方便大家直接跳转下载,不统计不知道,一统计吓一跳,不知不觉开源了这么多代码, ...

  2. Qt编写项目作品大全(自定义控件+输入法+大屏电子看板+视频监控+楼宇对讲+气体安全等)

    一.自定义控件大全 (一).控件介绍 超过160个精美控件,涵盖了各种仪表盘.进度条.进度球.指南针.曲线图.标尺.温度计.导航条.导航栏,flatui.高亮按钮.滑动选择器.农历等.远超qwt集成的 ...

  3. Qt编写安防视频监控系统(界面很漂亮)

    一.前言 视频监控系统在整个安防领域,已经做到了烂大街的程序,全国起码几百家公司做过类似的系统,当然这一方面的需求量也是非常旺盛的,各种定制化的需求越来越多,尤其是这几年借着人脸识别的东风,发展更加迅 ...

  4. Qt编写自定义控件二动画按钮

    现在的web发展越来越快,很多流行的布局样式,都是从web开始的,写惯了Qt widgets 项目,很多时候想改进一下现有的人机交互,尤其是在现有的按钮上加一些动画的效果,例如鼠标移上去变大,移开还原 ...

  5. Qt编写自定义控件11-设备防区按钮控件

    前言 在很多项目应用中,需要根据数据动态生成对象显示在地图上,比如地图标注,同时还需要可拖动对象到指定位置显示,能有多种状态指示,安防领域一般用来表示防区或者设备,可以直接显示防区号,有多种状态颜色指 ...

  6. Qt编写数据可视化大屏界面电子看板系统

    一.前言 目前大屏大数据可视化UI这块非常火,趁热也用Qt来实现一个,Qt这个一站式超大型GUI超市,没有什么他做不了的,大屏电子看板当然也不在话下,有了QSS和QPainter这两个无敌的工具组合, ...

  7. Qt编写安防视频监控系统18-云台控制

    一.前言 云台控制是视频监控系统中必备的一个功能,对球机进行上下左右的移动,还有焦距的控制,其实核心就是控制XYZ三个坐标轴,为了开发这个模块,特意研究了各种云台控制的方法和开源库比如soap,有些厂 ...

  8. Qt编写数据可视化大屏界面电子看板13-基础版

    一.前言 之前发布的Qt编写的可视化大屏电子看板系统,很多开发者比较感兴趣,也收到了很多反馈意见,纵观市面上的大屏系统,基本上都是B/S结构的web版本,需要在后台进行自定义配置模块,绑定数据源等,其 ...

  9. Qt编写气体安全管理系统10-数据导出

    一.前言 数据导出一般指导出到excel表格,可能有部分用户还需要导出到pdf,因为pdf基本上不可编辑,防止用户重新编辑导出的数据,excel可能绝大部分用过电脑的人都知道,广为流行,主要就是微软的 ...

  10. Qt编写自定义控件61-通用移动

    一.前言 通用移动类,目标就是为了实现放入任意的控件以后,支持鼠标拖动,在容器中或者父类中拖动,这个应用场景非常多,比如在地图上放置的设备,需要用户自行按下拖动到指定的合适的位置,然后保存设备的位置坐 ...

随机推荐

  1. 12 Masked Self-Attention(掩码自注意力机制)

    博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https:// ...

  2. 鸿蒙NEXT开发声明式UI是咋回事?

    大家好,我是 V 哥,ArkTS 是 HarmonyOS 优选的主力应用开发语言,它在 TypeScript 的基础上进行了扩展,提供了声明式 UI 描述.自定义组件和动态扩展 UI 元素的能力.这些 ...

  3. 一图为你揭秘云数据库GaussDB管理平台亮点

    云数据库GaussDB管理平台(TPOPS)是一款即开即用.稳定可靠.管理便捷的数据库运维管理平台.通过该平台,用户可以快速部署安装GauSSDB,实现智能化运维,大幅度提升运维和管理效率.一图带你揭 ...

  4. 鱼香ROS一键安装软件

    一行代码-解决人生烦恼 推荐语:一行代码搭建机器人开发环境(ROS/ROS2/ROSDEP) 开源地址:https://github.com/fishros/install 一键安装指令 wget h ...

  5. 解决 在docker环境中 mosquitto 无法启动 报错等问题

    报错内容 1592979788: Error: Unable to open log file /Users/bigbird/mqttconfig/mosquitto/log/mosquitto.lo ...

  6. chapter 3 introduction to computer science

    主机文件: <chapter3.docx>

  7. 通过wget命令扒站仿站

    在Linux下,通过一个命令就可以把整个站相关的文件全部下载下来. wget -r -p -k -np [网址] 参数说明: -r : 递归下载 -p : 下载所有用于显示 HTML 页面的图片之类的 ...

  8. Python 提取PowerPoint文档中的图片

    如果你需要在多个PowerPoint演示文稿中使用相同的图片,直接从原始PPT中提取并保存图片可以避免重复寻找和下载.此外,将PPT中的重要图片提取出来可以将其作为备份,以防原文件损坏或丢失.本文将通 ...

  9. 哪些网站可以申请免费的纯IP地址https证书

    申请免费纯IP地址HTTPS证书,您可以按照以下步骤进行: 一.选择证书颁发机构(CA) 目前,虽然一些大型云服务提供商(如阿里云.华为云.腾讯云等)已经取消了免费一年期SSL证书的供应,但仍有一些C ...

  10. ubuntu安装fish

    换新电脑后需要安装fish命令行工具,发现总是apt install不成功,后来挂了代理才成功. 然后我想让这个fish的命令能自动导入我以前写的alias命令(点击这里),可是发现网上人家都说fis ...