【QT--使用百度地图API显示地图并绘制路线】

QT--使用百度地图API显示地图并绘制路线

  • 前言
  • 准备工作
    • 申请百度地图密钥(AK)
    • 安装开发环境
  • 开发过程
    • 新建项目
    • ui界面
    • GPSManager类
    • 主窗口
    • Map
  • 效果展示

前言

先吐槽一下下,本身qt学的就不咋滴,谁想到第一件事就是让写一个上位机工具,根据CAN总线传来的位置信息,在地图上去绘制路线,并获取当前路段的限速信息等。当听到这个需求的时候,第一时间是有点懵逼的。自己原本是没接触过这方面的知识,而且qt学的也特别的垃圾,但是以我的性格还是答应了下来。最终也是花了几天的时间做了出来。通过做这个简单的小工具,自己也学到了还能多。接下来我就简单说一说如何使用百度地图API来显示地图并根据位置信息绘制路线这一功能。其他的就不方便说了。

准备工作

申请百度地图密钥(AK)

在使用百度地图之前,我们需要拥有一个自己的百度账号,申请注册成为百度开发者,然后我们需要创建一个浏览器端应用,就可以获取到一个唯一的服务秘钥(AK)
具体的步骤小伙伴们可以去看一些其他博主的文章,这里我就不详细的去说了。

安装开发环境

说到开发环境,这里我踩了很多的坑啊,这里我来强调一下。
首先我的qt版本是5.14.2,在安装QT的时候一定把MSVC2017给选上!!!不然后面写代码导入模块时会出错的。
还有就是一定要安装一个Visual Studio 2017,因为我QT上是MSVC2017,所以这里我安装的是Visual Studio 2017。
如果环境搞得差不多了,就可以进行下面的开发了。

开发过程

新建项目

打开QT新建一个Application,在Kits页面将MSVC2017勾选上,如下图:
在这里插入图片描述
新建完成后,打开.pro文件添加如下代码:

QT +=webenginewidgets

重新构建一下项目,如果出现错误,请检查前面的开发环境。

ui界面

在这里插入图片描述
其中包括三个QLabel用来显示信息,分别是GPS信息,Speed信息,和绘制情况信息,一个按钮,来触发绘制,还有一个webEngineView,这个需要在Designer下拖拽上去。

GPSManager类

一、gpsmanager.h

#ifndef GPSMANAGER_H
#define GPSMANAGER_H
#include <QObject>
#include <QWebEngineView>
class GPSManager : public QObject
{Q_OBJECTpublic:explicit GPSManager(QObject *parent = nullptr);signals:void routeDrawn();void speedLimitReceived(int limit);void gpsUpdated(double latitude, double longitude);public slots:void drawRoute(QWebEnginePage *webPage);void setGPSLocation(double latitude, double longitude);
public:int getSpeedLimit(double latitude, double longitude);
private:double currentLatitude;double currentLongitude;};
#endif // GPSMANAGER_H

这个类旨在处理Qt应用程序中与GPS相关的功能。它发射信号以通知应用程序其他部分有关路线绘制、速度限制更新和GPS坐标更改的信息,并提供槽和函数来执行这些操作。
二、gpsmanager.cpp
构造函数:

GPSManager::GPSManager(QObject *parent) : QObject(parent)
{currentLatitude = 0.0;currentLongitude = 0.0;
}

这是 GPSManager 类的构造函数。它初始化了 currentLatitude 和 currentLongitude 两个成员变量为0.0。

drawRoute 函数:

void GPSManager::drawRoute(QWebEnginePage *webPage)
{// 在这里触发在 HTML 页面中编写的 JavaScript 代码来绘制路线QString javascriptCode = QString("drawNewPoint(%1, %2);").arg(currentLatitude).arg(currentLongitude);if (webPage) {// 执行 JavaScript 代码webPage->runJavaScript(javascriptCode);qDebug() << javascriptCode << endl;}// 获取限速信息并触发信号int speedLimit = getSpeedLimit(currentLatitude, currentLongitude);emit speedLimitReceived(speedLimit);// 触发路线绘制完成的信号emit routeDrawn();
}

这个函数用于绘制路线。它构建一个包含纬度和经度信息的 JavaScript 代码字符串,然后通过 QWebEnginePage 对象的 runJavaScript 方法在 HTML 页面中执行该代码。接着,它调用 getSpeedLimit 函数获取速度限制信息,并通过 emit 发射 speedLimitReceived 信号,以及发射 routeDrawn 信号表示路线绘制完成。

setGPSLocation 函数

void GPSManager::setGPSLocation(double latitude, double longitude)
{// 设置 GPS 位置currentLatitude = latitude;currentLongitude = longitude;emit gpsUpdated(currentLatitude, currentLongitude);qDebug("setGPSLocation");
}

这个函数用于设置 GPS 的位置信息。它接受纬度和经度作为参数,并将这些值存储在 currentLatitude 和 currentLongitude 成员变量中。然后,它通过 emit 发射 gpsUpdated 信号表示 GPS 位置已更新。

getSpeedLimit 函数:

int GPSManager::getSpeedLimit(double latitude, double longitude)
{// 在这里查询限速信息,这是一个示例// 实际上,你需要与地图数据提供商的API进行交互来获取限速信息// 这里我们模拟返回一个随机的限速值作为示例int randomSpeedLimit = QRandomGenerator::global()->bounded(30, 110); // 生成30到109之间的随机数return randomSpeedLimit;
}

这个函数用于获取速度限制信息。它是一个示例函数,实际中你需要与地图数据提供商的API进行交互来获取真实的速度限制信息。在示例中,它返回一个随机的速度限制值,范围在30到109之间。

主窗口

一、mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QWebEngineView>
#include <QtWebChannel>
#include "gpsmanager.h"
#include <QTimer>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;//QWebEngineView *mapView;GPSManager *gpsManager;QTimer *timer;
private slots:void onGpsUpdated(double latitude, double longitude);void onRouteDrawn();void onSpeedLimitReceived(int limit);void on_pushButton_clicked();void onTimerTimeout();
};
#endif // MAINWINDOW_H

这个头文件定义了 MainWindow 类,该类是 Qt C++ 应用程序的主窗口。它包含了一些成员变量,包括用户界面对象、GPS 管理器和定时器,以及一些用于处理信号和事件的槽函数。这些槽函数用于响应与 GPS 更新、路线绘制、速度限制等相关的事件。
二、mainwindow.cpp
构造函数:

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 创建GPSManager对象gpsManager = new GPSManager(this);// 连接GPSManager的信号与MainWindow的槽函数connect(gpsManager, &GPSManager::gpsUpdated, this, &MainWindow::onGpsUpdated);connect(gpsManager, &GPSManager::routeDrawn, this, &MainWindow::onRouteDrawn);connect(gpsManager, &GPSManager::speedLimitReceived, this, &MainWindow::onSpeedLimitReceived);ui->webEngineView->setUrl(QUrl("D:/QtCode/Google/map.html"));timer = new QTimer(this);timer->setInterval(5000);
}

这是 MainWindow 类的构造函数。在其中,进行了如下操作:
初始化用户界面 (ui->setupUi(this))。
创建 GPSManager 对象,用于处理 GPS 相关的操作。
连接 GPSManager 的信号与 MainWindow 的槽函数,以便在 GPS 更新、路线绘制和速度限制接收时执行相应操作。
设置 QWebEngineView 显示的网页 URL。
创建一个定时器 timer,并设置其定时间隔为 5000 毫秒(5秒)。

析构函数:

MainWindow::~MainWindow()
{delete ui;delete gpsManager;delete timer; // 释放定时器对象
}

这是 MainWindow 类的析构函数,用于释放动态分配的对象,包括用户界面对象 (ui)、GPSManager 对象和定时器对象。

槽函数 onGpsUpdated:

void MainWindow::onGpsUpdated(double longitude, double latitude)
{// 在这里可以更新UI以显示当前GPS坐标// 例如,更新UI的标签或其他元素qDebug("onGpsUpdated");ui->gps->setText(QString::number(longitude, 'f', 10) + " " + QString::number(latitude, 'f', 10));
}
这个槽函数用于处理 GPS 更新事件,更新用户界面上显示的 GPS 坐标信息。

槽函数 onRouteDrawn:

void MainWindow::onRouteDrawn()
{// 在这里可以执行与路线绘制相关的操作// 例如,显示路线的标签或其他元素ui->route->setText("正在绘制路线...");
}

这个槽函数用于处理路线绘制完成事件,更新用户界面上显示的信息。

槽函数 onSpeedLimitReceived:

void MainWindow::onSpeedLimitReceived(int limit)
{// 在这里可以更新UI以显示限速信息// 例如,显示限速信息的标签或其他元素ui->speed->setText("Speed Limit:" + QString::number(limit));
}

这个槽函数用于处理速度限制接收事件,更新用户界面上显示的限速信息。

槽函数 on_pushButton_clicked:

void MainWindow::on_pushButton_clicked()
{if (ui->pushButton->text() == "绘制") {connect(timer, &QTimer::timeout, this, &MainWindow::onTimerTimeout);timer->start();ui->pushButton->setText("取消绘制");} else {ui->pushButton->setText("绘制");timer->stop();ui->route->setText("");}
}

这个槽函数用于处理按钮点击事件。如果按钮上的文本是 “绘制”,则连接定时器的超时信号到 onTimerTimeout 槽函数,并启动定时器以触发路线绘制。如果按钮上的文本是 “取消绘制”,则停止定时器并重置界面上显示的路线信息。

槽函数 onTimerTimeout:

void MainWindow::onTimerTimeout()
{// 在定时器槽函数中调用gpsManager的函数lng = lng - 0.0003;lat = lat - 0.0003;gpsManager->setGPSLocation(lng, lat);gpsManager->drawRoute(ui->webEngineView->page());qDebug("%.10f %.10f", lng, lat);
}

这个槽函数用于处理定时器超时事件。在超时时,它调用 gpsManager 的函数来模拟 GPS 位置的变化,并触发路线绘制。在示例中,lng 和 lat 分别减小了0.0003,表示模拟GPS位置的移动。

Map

map.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>运输轨迹图</title>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=key"></script>
</head>
<body>
<div style="width:100%; height:100vh; border:1px solid gray" id="container"></div><script type="text/javascript">var map; // 保存地图对象var polyline; // 保存绘制的路线var points = []; // 保存所有点坐标// 创建地图函数function createMap() {// 如果地图对象不存在,创建地图map = new BMap.Map("container");map.centerAndZoom(new BMap.Point(116.404, 39.915), 13);map.addControl(new BMap.NavigationControl());               // 添加平移缩放控件map.addControl(new BMap.ScaleControl());                    // 添加比例尺控件map.addControl(new BMap.OverviewMapControl());              // 添加缩略地图控件map.enableScrollWheelZoom(true);// 初始化地图大小resizeMap();// 监听窗口大小变化事件,以动态调整地图大小window.addEventListener("resize", resizeMap);}// 初始化地图createMap();// 定义绘制路线的函数function drawRoute() {// 生成坐标点var trackPoint = [];for (var i = 0; i < points.length; i++) {trackPoint.push(new BMap.Point(points[i].lng, points[i].lat));}// 如果路线已存在,先清除//if (polyline) {//    map.removeOverlay(polyline);//}// 创建路线polyline = new BMap.Polyline(trackPoint, {strokeColor:"green", strokeWeight:6, strokeOpacity:1});map.addOverlay(polyline);}// 定义绘制新点的函数function drawNewPoint(lng, lat) {// 添加新的点坐标到 points 数组中var newPoint = { lng: lng, lat: lat };points.push(newPoint);// 如果超过最大长度,删除最早的点坐标if (points.length > 10) {points.splice(0, points.length - 10);}// 调用绘制路线函数以绘制新的路线drawRoute();// 获取最后一个点的坐标var lastPoint = new BMap.Point(lng, lat);// 计算地图视野以包含整个路线var view = map.getViewport(points);// 调整视野以确保最后一个点在地图中央var centerPoint = view.center;map.centerAndZoom(centerPoint, view.zoom);map.setCenter(lastPoint);}// 自适应地图大小function resizeMap() {var container = document.getElementById("container");var viewportWidth = window.innerWidth || document.documentElement.clientWidth;var viewportHeight = window.innerHeight || document.documentElement.clientHeight;container.style.width = viewportWidth + "px";container.style.height = viewportHeight + "px";map.setViewport();}
</script>
</body>
</html>

效果展示

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/82311.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

x86架构基础汇编知识

​ 通用寄存器 EAX 32位 函数返回值 AX 低16位 AH 高八位 AL 低八位 EBX 32位 ECX 32位 循环次数&#xff0c;this指针 EDX 32位 EBP 32位 栈底寄存器 ESP 32位 栈顶寄存器 ESI 源索引寄存器 EDI 目标索引寄存器 EIP 无法直接通过汇编操作 例子 mov al&#xff0c;0xff …

python 第一次作业

1.使用turtle换一个五环 2.设计这样一个程序&#xff1a;输入一个数字 判断它是不是一个质数 使用turtle换一个五环&#xff1a; >>> import turtle #导入模块 >>> turtle.width(10) #设置圆圈宽度 >>> turtle.color("blue&qu…

Tomcat7+ Weak Password Backend Getshell Vulnerability

漏洞描述 Tomcat 支持通过后端部署 war 文件&#xff0c;所以我们可以直接将 webshell 放入 Web 目录下。为了访问后端&#xff0c;需要权限。 Tomcat7 的权限如下&#xff1a; 经理&#xff08;后台管理&#xff09; 管理器-GUI&#xff08;HTML 页面的权限&#xff09;管理…

WMS系统库存条码管理

1. 定义 库存条码管理是WMS系统中的一项关键功能&#xff0c;通过对仓库内货物进行条码标识和管理&#xff0c;实现对库存的精确追踪和控制。库存条码可以是一维条码&#xff08;如条形码&#xff09;或二维条码&#xff08;如QR码&#xff09;&#xff0c;用于唯一标识和识别…

华为数通方向HCIP-DataCom H12-821题库(单选题:361-380)

第361题 如图所示是一台路由器的BGP输出信息。那么以下关于这段信息的描述,错误的是哪一项? <Huawei>display bgp error Error Type: Peer Error Peer Address:10.1.1.2 VRFName:Public Error Info: Router-ID conflictA、该路由器邻居地址是10.1.1.2 B、Error Type显…

SpringBoot2.0(mybatis-plus常见的增删改查和分页)

目录 一&#xff0c;mybatis-plus常见注解二&#xff0c;创建一个工具类和启动类三&#xff0c;创建实体类四&#xff0c;创建mapper接口五&#xff0c;创建service接口和impl类六&#xff0c;创建配置类七&#xff0c;创建controller八&#xff0c;使用测试工具测试增删改查和…

Reids Cluster集群部署

服务器端口说明 vim /etc/hosts 1.下载、解压、编译Redis $ mkdir -p /opt/redis && cd /opt/redis $ wget http://download.redis.io/releases/redis-6.0.6.tar.gz $ tar xzf redis-6.0.6.tar.gz 请先检查gcc的版本是否低于5&#xff0c;如果是请先升级&#xff0c…

听GPT 讲Istio源代码--pilot(7)

File: istio/pilot/pkg/model/log.go 在Istio项目中&#xff0c;istio/pilot/pkg/model/log.go文件的作用是定义了Istio Pilot的日志记录功能。 该文件中定义了一个名为log的全局日志记录器&#xff0c;并且还定义了一些与日志记录相关的变量&#xff0c;如verbose、verboseCou…

幸福里基于 Flink Paimon 的流式数仓实践

摘要&#xff1a;本文整理自字节跳动基础架构工程师李国君&#xff0c;在 Streaming Lakehouse Meetup 的分享。幸福里业务是一种典型的交易、事务类型的业务场景&#xff0c;这种业务场景在实时数仓建模中遇到了诸多挑战。本次分享主要介绍幸福里业务基于 Flink & Paimon …

Linux日志管理-logrotate(crontab定时任务、Ceph日志转储)

文章目录 一、logrotate概述二、logrotate基本用法三、logrotate运行机制logrotate参数 四、logrotate是怎么做到滚动日志时不影响程序正常的日志输出呢&#xff1f;Linux文件操作机制方案一方案二 五、logrotate实战--Ceph日志转储参考 一、logrotate概述 logrotate是一个用于…

数据结构--哈希表,哈希函数(或者散列表、散列函数)

目录 哈希表的定义 处理冲突的方法--拉链法 散列查找 常见的散列函数&#xff08;构造哈希函数&#xff09; 除留余数法 直接定址法 数字分析法 平方取中法 处理冲突的方法--开放定址法 &#xff08;1&#xff09;线性探测法&#xff1a; &#xff08;2&#xff09…

mall商城项目:只启动mall-admin情况下Windows环境的部署

文章目录 前提ideaMysql创建数据库mall,导入项目document/sql文件夹下的mall.sql文件,初始化数据RedisPostMan登录接口测试运行前提 mall项目gitee 如果项目只启动mall-admin,仅需安装MySQL、Redis即可 idea IDEA的安装与使用请参考搜索插件仓库,安装插件Lombok;将项目下…

速腾聚创80线激光雷达ros驱动安装

1. 激光雷达硬件连接 1.1 工具准备 1.2 硬件连接 设置PC Ubuntu1804静态IP&#xff0c;速腾聚创16线激光雷达出厂默认发送到192.168.1.102&#xff0c;在连接前可以通过wireshark抓包工具进行检测&#xff1b; sudo wireshark 正常发送UDP数据流才算正常接入&#xff01; 2. 软…

C语言入门Day_22 初识指针

目录 前言&#xff1a; 1.内存地址 2.指针的定义 3.指针的使用 4.易错点 5.思维导图 前言&#xff1a; 之前我们学过变量可以用来存储数据&#xff0c;就像一个盒子里面可以放不同的球一样。 这是一个方便大家理解专业概念的比喻。 在计算机世界里面&#xff0c;数据实…

怎么防止360安全卫士修改默认浏览器?

默认的浏览器 原先选项是360极速浏览器&#xff08;如果有安装的话&#xff09;&#xff0c;我这里改成了Chrome。 先解锁 才能修改。

千巡翼X1 让航测无人机更小更轻更高效

利用无人机进行航空摄影测量&#xff0c;已成为测绘外业生产的主要方式&#xff0c;不仅方便快捷&#xff0c;更能全面准确获得成果。近年来&#xff0c;凭借快速高效、机动灵活、安全可靠、低成本等诸多优势&#xff0c;小型多旋翼无人机逐渐成为一些航测项目作业的新利器。 千…

Redis——渐进式遍历和数据库管理命令

介绍 如果使用keys * 这样的操作&#xff0c;将Redis中所有的key都获取到&#xff0c;由于Redis是单线程工作&#xff0c;这个操作本身又要消耗很多时间&#xff0c;那么就会导致Redis服务器阻塞&#xff0c;后续的操作无法正常执行 而渐进式遍历&#xff0c;通过多次执行遍历…

【PowerQuery】PowerBI Pro账户的自动刷新

在数据和模型通过发布或者上传方式上传到PowerBI Pro中,如何来进行数据刷新呢?数据源依然在本地,而数据模型已经发布到PowerBI Pro云端服务中。如果数据源更新,我们的模型如何进行自动刷新呢? PowerBI Pro如果需要基于本地数据源更新进行模型更新需要部署相应的数据网关服…

智能合约漏洞案例,Euler Finance 1.96 亿美元闪电贷漏洞分析

智能合约漏洞案例&#xff0c;Euler Finance 1.96 亿美元闪电贷漏洞分析 2023 年 3 月 13 日上午 08:56:35 UTC&#xff0c;DeFi 借贷协议 Euler Finance 遭遇闪电贷攻击。 Euler Finance 是一种作为无许可借贷协议运行的协议。其主要目标是为用户提供各种加密货币的借贷便利。…

斯里兰卡投资促进部中国招商大使率考察团到访深兰科技

9月13日&#xff0c;来华访问的斯里兰卡投资促进部政府考察团&#xff0c;在斯里兰卡投资促进部中国招商大使吴克向的率领下&#xff0c;到访深兰科技集团&#xff0c;并与深兰科技集团董事副总裁刘园桂等进行了会谈。 考察团随行人员包括Sri Lanka Sithara Limited公司总裁Mr.…