【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>
效果展示
相关文章:
【QT--使用百度地图API显示地图并绘制路线】
QT--使用百度地图API显示地图并绘制路线 前言准备工作申请百度地图密钥(AK)安装开发环境 开发过程新建项目ui界面GPSManager类主窗口Map 效果展示 前言 先吐槽一下下,本身qt学的就不咋滴,谁想到第一件事就是让写一个上位机工具,根据CAN总线传…...
C数据结构二.练习题
一.求级数和 2.求最大子序列问题:设给定一个整数序列 ai.az..,a,(可能有负数).设计一个穷举算法,求a 的最大值。例如,对于序列 A {1,-1,1,-1,-1,1,1,1,1.1,-1,-1.1,-1,1,-1},子序列 A[5..9](1,1,1,1,1)具有最大值5 3.设有两个正整数 m 和n,编写一个算法 gcd(m,n),求它们的最大公…...
猫头虎博主第5️⃣期赠书活动:《Java官方编程手册(第12版·Java 17)套装上下册》
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...
(1)数据库 MSQ 数据库 安装 使用 以及增删改查
下载官网:MySQL :: Download MySQL Shell 常见的数据库分为: 关系型数据库, Oracle、MySQL、SQLServer、Access非关系型数据库, MongoDB、Redis、Solr、ElasticSearch、Hive、HBase 安装过程 使用过程...
什么测试自动化测试?
什么测试自动化测试? 做测试好几年了,真正学习和实践自动化测试一年,自我感觉这一个年中收获许多。一直想动笔写一篇文章分享自动化测试实践中的一些经验。终于决定花点时间来做这件事儿。 首先理清自动化测试的概念,广义上来讲&a…...
【踩坑篇】代码中使用 Long 作为 Map的Key存在的问题
本周的工作结束,详述一些在项目代码中实际遇到的一些坑。 代码中遇到这样一个场景: 有个业务接口,接口返回的值是一个JSON格式的字符串,通过JSON解析的方式,解析为格式为: Map<Long, Map<String, O…...
微服务保护-授权规则/规则持久化
授权规则 基本规则 授权规则可以对调用方的来源做控制,有白名单和黑名单两种方式。 白名单:来源(origin)在白名单内的调用者允许访问 黑名单:来源(origin)在黑名单内的调用者不允许访问 点…...
练习敲代码速度
2023年9月18日,周一晚上 今晚不想学习,但又不想玩游戏,于是找了一些练习敲代码的网站来玩玩,顺便练习一下敲代码的速度 目录 参考资料个人推荐第一个 第二个第三个 参考资料 电脑打字慢,有哪些比较好的练打字软件&a…...
uni-app:实现条件判断展示图片(函数判定+三目运算)
一、多条件判断(通过函数进行图片展示) 效果 代码 在data中定义图片信息和要传递的数据信息,在src中写入函数并携带要传递的数据,通过传递的数据在函数中进行判断,并返回对应的图片信息 <template><view&…...
http概念
概念:HTTP,hyper text transfer protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则。 特点: 1.基于TCP协议:面向连接,安全。 2.基于请求-响应模型的:一次请求对应一…...
Postman应用——Variable变量使用(Global、Environment和Collection)
文章目录 变量的使用同名变量优先级Postman内置变量 Global、Environment和Collection变量设置,点击查看。 变量的使用 语法: {{变量名}}使用{{}}包裹变量名,引用设置好的变量。 注意:Environment变量引用前需要先选择已有的环…...
php高级 TP+Redis实现发布订阅和消息推送案例实战
Redis 的发布-订阅模型是一种消息通信模式,它允许客户端之间通过特定的频道进行通信。在这种模型中,有些客户端负责发布消息(发布者),而其他客户端则订阅它们感兴趣的频道并接收这些消息(订阅者)…...
Python 基础入门
给我家憨憨写的python教程 ——雁丘 Python解释器Pycharm的安装部署 关于本专栏一 Python简介1.1 Python优点1.2 支持的编程方式1.3 版本兼容问题1.4 Python的开发环境1.4.1 常用的 Python 编辑器1.4.2 常用的 Python IDE1.4.3 Python IDLE1.4.4 第三方库安装 1.5 Python 的运…...
【跟小嘉学 Rust 编程】二十九、Rust 中的零拷贝序列化解决方案(rkyv)
系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学…...
路由器端口转发
什么是路由器端口转发 路由器端口转发是一种网络配置技术,用于将公共网络(如互联网)上的请求转发到私有网络中的特定设备或服务。它允许外部设备通过路由器访问内部网络中的设备或服务,实现网络上的通信和互动。 路由器端口转发…...
Redis模块一:缓存简介
目录 缓存的定义 应用 生活案例 程序中的缓存 缓存优点 缓存的定义 缓存是⼀个高速数据交换的存储器,使用它可以快速的访问和操作数据。 应用 1.CPU缓存:CPU缓存是位于CPU和内存之间的临时存储器,它的容量通常远小于内存࿰…...
【去除若依首页】有些小项目不需要首页,去除方法
第一步 // // // // // // // // // // // // // // // // // // 修改登录页 Login.vue 中 大概144行 ,注释掉原有跳转。替换为自己的跳转路径 // // // // // // // // // // // // // this.$router.push({ path: this.redirect || …...
Ardupilot — EKF3使用光流室内定位代码梳理
文章目录 前言 1 Copter.cpp 1.1 void IRAM_ATTR Copter::fast_loop() 1.2 void Copter::read_AHRS(void) 1.3 对象ahrs说明 2 AP_AHRS_NavEKF.cpp 2.1 void AP_AHRS_NavEKF::update(bool skip_ins_update) 2.2 void AP_AHRS_NavEKF::update_EKF3(void) 2.3 对象EKF3说…...
【Linux】自动化构建工具 —— make/makefileLinux第一个小程序 - 进度条
📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:Linux 🎯长路漫漫浩浩,万事皆有期待 上一篇博客:Linux编译…...
tensorflow的unet模型
import tensorflow as tf from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Dropout, UpSampling2D, concatenate# 定义 U-Net 模型 def unet(input_size(256, 256, 3)):inputs Input(input_size)# 编码器部分conv1 Conv2D(64, 3, activationrelu, padding…...
(2023 最新版)IntelliJ IDEA 下载安装及配置教程
IntelliJ IDEA下载安装教程(图解) IntelliJ IDEA 简称 IDEA,由 JetBrains 公司开发,是 Java 编程语言开发的集成环境,具有美观,高效等众多特点。在智能代码助手、代码自动提示、重构、J2EE 支持、各类版本…...
react 实现拖动元素
demo使用create-react-app脚手架创建 删除一些文件,创建一些文件后 结构目录如下截图com/index import Movable from ./move import { useMove } from ./move.hook import * as Operations from ./move.opMovable.useMove useMove Movable.Operations Operationse…...
【EI会议】第二届声学,流体力学与工程国际学术会议(AFME 2023)
第二届声学,流体力学与工程国际学术会议 2023 2nd International Conference on Acoustics, Fluid Mechanics and Engineering(AFME 2023) 声学、流体力学两个古老的学科发展至今,无时无刻都在影响着我们的生活。小到日常使用的耳…...
Android StringFog 字符串自动加密
一、StringFog 作用 一款自动对dex/aar/jar文件中的字符串进行加密Android插件工具,正如名字所言,给字符串加上一层雾霭,使人难以窥视其真面目。可以用于增加反编译难度,防止字符串代码重复。 支持java/kotlin。支持app打包生成…...
上四休三,未来的期许
近日“少上一天班,究竟香不香”引发关注,英国媒体2月21日报道,一项全世界目前为止参加人数最多的“四天工作制”试验,不久前在英国取得了成功。很多人表示上过四天班之后,给多少钱也回不去五天班的时代了。 来百度APP畅…...
怎么防止360安全卫士修改默认浏览器?
默认的浏览器 原先选项是360极速浏览器(如果有安装的话),我这里改成了Chrome。 先解锁 才能修改。...
调整参数提高mysql读写速度
要提升MySQL的写入速度,您可以采取一些参数调整和优化措施,这些措施可以根据您的具体应用和环境进行调整。以下是一些常见的参数和优化建议: InnoDB存储引擎: 如果您使用的是InnoDB存储引擎,确保以下参数被设置得合理: innodb_buffer_pool_size:增加内存池大小,以便更多…...
Go expvar包
介绍与使用 expvar 是 exposed variable的简写 expvar包[1]是 Golang 官方为暴露Go应用内部指标数据所提供的标准对外接口,可以辅助获取和调试全局变量。 其通过init函数将内置的expvarHandler(一个标准http HandlerFunc)注册到http包ListenAndServe创建的默认Serve…...
Yolo v8代码逐行解读
train.py文件 1.FILE Path(__file__).resolve() __file__代表的是train.py文件,Path(__file__).resolve()结果是train.py文件的绝对路径。 2.ROOT FILE.parents[0] 获得train.py父目录的绝对路径 3.sys.path 是一个列表list,里面包含了已经添加到系…...
app软件开发公司找用友yonmaker/平台优化是指什么
求递归算法时间复杂度:递归树1.参考资料2.内容1.参考资料 参考网页:求递归算法时间复杂度:递归树 2.内容 递归算法时间复杂度的计算方程式是一个递归方程: T(n){O(1)n1kT(n/m)f(n)n>1T(n) \left\{ \begin{array}{ll} O(1) & n1 \\…...
canvas做的网站/seo关键词排名工具
引言 只要设计到数据,就会涉及到数据的排序问题,比如给你随机给你五个整数 3,1,5,2,4 。让你从小到大进行排序,那我们该怎样才是实现对这些整数的排序呢 ? 答案是多种多样的&#x…...
济南网站推广效果/新疆疫情最新情况
1、外链的对于优化发生了转移。(1)8月22日百度更新的外链识别算法。(2)百度开放了一款外链的识别工具。对于垃圾链接的识别 倒闭资源站点的价格提升第一个影响 提升了网站优化的门槛第二个影响 外链对优化转移 营销的成本提升…...
wordpress用旧的编辑器/seo实战密码电子书
电信物联网开放平台NB-IoT商业项目已投产一、NB-IoT模组硬件设备 BC28模组二、物联平台开发SSH集成电信物联SDK三、微信小程序前端四、NB-IoT商业项目已投产http://www.qchcloud.cn/tn/article/26转载于:https://blog.51cto.com/14042154/2391299...
中小企业建立网站最经济的方式/查关键词排名软件
最近在弄linux系统的环境,搭建vue环境,由于是第一次接触vue以前也没使用过,所以才搭建环境的时候还是挺闷逼的。记录一下,免得以后忘记了。 安装cnpm 由于不知道vue和npm的关系,所以自己想先安装npm并设置成阿里的cnpm…...
企业网站怎样做外链方法/google推广
题目描述: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 示例: 给定 nums …...