做電影網(wǎng)站考什么電商平臺(tái)推廣費(fèi)用大概要多少
QT--使用百度地圖API顯示地圖并繪制路線
- 前言
- 準(zhǔn)備工作
- 申請(qǐng)百度地圖密鑰(AK)
- 安裝開發(fā)環(huán)境
- 開發(fā)過程
- 新建項(xiàng)目
- ui界面
- GPSManager類
- 主窗口
- Map
- 效果展示
前言
先吐槽一下下,本身qt學(xué)的就不咋滴,誰(shuí)想到第一件事就是讓寫一個(gè)上位機(jī)工具,根據(jù)CAN總線傳來的位置信息,在地圖上去繪制路線,并獲取當(dāng)前路段的限速信息等。當(dāng)聽到這個(gè)需求的時(shí)候,第一時(shí)間是有點(diǎn)懵逼的。自己原本是沒接觸過這方面的知識(shí),而且qt學(xué)的也特別的垃圾,但是以我的性格還是答應(yīng)了下來。最終也是花了幾天的時(shí)間做了出來。通過做這個(gè)簡(jiǎn)單的小工具,自己也學(xué)到了還能多。接下來我就簡(jiǎn)單說一說如何使用百度地圖API來顯示地圖并根據(jù)位置信息繪制路線這一功能。其他的就不方便說了。
準(zhǔn)備工作
申請(qǐng)百度地圖密鑰(AK)
在使用百度地圖之前,我們需要擁有一個(gè)自己的百度賬號(hào),申請(qǐng)注冊(cè)成為百度開發(fā)者,然后我們需要?jiǎng)?chuàng)建一個(gè)瀏覽器端應(yīng)用,就可以獲取到一個(gè)唯一的服務(wù)秘鑰(AK)
具體的步驟小伙伴們可以去看一些其他博主的文章,這里我就不詳細(xì)的去說了。
安裝開發(fā)環(huán)境
說到開發(fā)環(huán)境,這里我踩了很多的坑啊,這里我來強(qiáng)調(diào)一下。
首先我的qt版本是5.14.2,在安裝QT的時(shí)候一定把MSVC2017給選上!!!不然后面寫代碼導(dǎo)入模塊時(shí)會(huì)出錯(cuò)的。
還有就是一定要安裝一個(gè)Visual Studio 2017,因?yàn)槲襋T上是MSVC2017,所以這里我安裝的是Visual Studio 2017。
如果環(huán)境搞得差不多了,就可以進(jìn)行下面的開發(fā)了。
開發(fā)過程
新建項(xiàng)目
打開QT新建一個(gè)Application,在Kits頁(yè)面將MSVC2017勾選上,如下圖:
新建完成后,打開.pro文件添加如下代碼:
QT +=webenginewidgets
重新構(gòu)建一下項(xiàng)目,如果出現(xiàn)錯(cuò)誤,請(qǐng)檢查前面的開發(fā)環(huán)境。
ui界面
其中包括三個(gè)QLabel用來顯示信息,分別是GPS信息,Speed信息,和繪制情況信息,一個(gè)按鈕,來觸發(fā)繪制,還有一個(gè)webEngineView,這個(gè)需要在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
這個(gè)類旨在處理Qt應(yīng)用程序中與GPS相關(guān)的功能。它發(fā)射信號(hào)以通知應(yīng)用程序其他部分有關(guān)路線繪制、速度限制更新和GPS坐標(biāo)更改的信息,并提供槽和函數(shù)來執(zhí)行這些操作。
二、gpsmanager.cpp
構(gòu)造函數(shù):
GPSManager::GPSManager(QObject *parent) : QObject(parent)
{currentLatitude = 0.0;currentLongitude = 0.0;
}
這是 GPSManager 類的構(gòu)造函數(shù)。它初始化了 currentLatitude 和 currentLongitude 兩個(gè)成員變量為0.0。
drawRoute 函數(shù):
void GPSManager::drawRoute(QWebEnginePage *webPage)
{// 在這里觸發(fā)在 HTML 頁(yè)面中編寫的 JavaScript 代碼來繪制路線QString javascriptCode = QString("drawNewPoint(%1, %2);").arg(currentLatitude).arg(currentLongitude);if (webPage) {// 執(zhí)行 JavaScript 代碼webPage->runJavaScript(javascriptCode);qDebug() << javascriptCode << endl;}// 獲取限速信息并觸發(fā)信號(hào)int speedLimit = getSpeedLimit(currentLatitude, currentLongitude);emit speedLimitReceived(speedLimit);// 觸發(fā)路線繪制完成的信號(hào)emit routeDrawn();
}
這個(gè)函數(shù)用于繪制路線。它構(gòu)建一個(gè)包含緯度和經(jīng)度信息的 JavaScript 代碼字符串,然后通過 QWebEnginePage 對(duì)象的 runJavaScript 方法在 HTML 頁(yè)面中執(zhí)行該代碼。接著,它調(diào)用 getSpeedLimit 函數(shù)獲取速度限制信息,并通過 emit 發(fā)射 speedLimitReceived 信號(hào),以及發(fā)射 routeDrawn 信號(hào)表示路線繪制完成。
setGPSLocation 函數(shù)
void GPSManager::setGPSLocation(double latitude, double longitude)
{// 設(shè)置 GPS 位置currentLatitude = latitude;currentLongitude = longitude;emit gpsUpdated(currentLatitude, currentLongitude);qDebug("setGPSLocation");
}
這個(gè)函數(shù)用于設(shè)置 GPS 的位置信息。它接受緯度和經(jīng)度作為參數(shù),并將這些值存儲(chǔ)在 currentLatitude 和 currentLongitude 成員變量中。然后,它通過 emit 發(fā)射 gpsUpdated 信號(hào)表示 GPS 位置已更新。
getSpeedLimit 函數(shù):
int GPSManager::getSpeedLimit(double latitude, double longitude)
{// 在這里查詢限速信息,這是一個(gè)示例// 實(shí)際上,你需要與地圖數(shù)據(jù)提供商的API進(jìn)行交互來獲取限速信息// 這里我們模擬返回一個(gè)隨機(jī)的限速值作為示例int randomSpeedLimit = QRandomGenerator::global()->bounded(30, 110); // 生成30到109之間的隨機(jī)數(shù)return randomSpeedLimit;
}
這個(gè)函數(shù)用于獲取速度限制信息。它是一個(gè)示例函數(shù),實(shí)際中你需要與地圖數(shù)據(jù)提供商的API進(jìn)行交互來獲取真實(shí)的速度限制信息。在示例中,它返回一個(gè)隨機(jī)的速度限制值,范圍在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
這個(gè)頭文件定義了 MainWindow 類,該類是 Qt C++ 應(yīng)用程序的主窗口。它包含了一些成員變量,包括用戶界面對(duì)象、GPS 管理器和定時(shí)器,以及一些用于處理信號(hào)和事件的槽函數(shù)。這些槽函數(shù)用于響應(yīng)與 GPS 更新、路線繪制、速度限制等相關(guān)的事件。
二、mainwindow.cpp
構(gòu)造函數(shù):
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 創(chuàng)建GPSManager對(duì)象gpsManager = new GPSManager(this);// 連接GPSManager的信號(hào)與MainWindow的槽函數(shù)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 類的構(gòu)造函數(shù)。在其中,進(jìn)行了如下操作:
初始化用戶界面 (ui->setupUi(this))。
創(chuàng)建 GPSManager 對(duì)象,用于處理 GPS 相關(guān)的操作。
連接 GPSManager 的信號(hào)與 MainWindow 的槽函數(shù),以便在 GPS 更新、路線繪制和速度限制接收時(shí)執(zhí)行相應(yīng)操作。
設(shè)置 QWebEngineView 顯示的網(wǎng)頁(yè) URL。
創(chuàng)建一個(gè)定時(shí)器 timer,并設(shè)置其定時(shí)間隔為 5000 毫秒(5秒)。
析構(gòu)函數(shù):
MainWindow::~MainWindow()
{delete ui;delete gpsManager;delete timer; // 釋放定時(shí)器對(duì)象
}
這是 MainWindow 類的析構(gòu)函數(shù),用于釋放動(dòng)態(tài)分配的對(duì)象,包括用戶界面對(duì)象 (ui)、GPSManager 對(duì)象和定時(shí)器對(duì)象。
槽函數(shù) onGpsUpdated:
void MainWindow::onGpsUpdated(double longitude, double latitude)
{// 在這里可以更新UI以顯示當(dāng)前GPS坐標(biāo)// 例如,更新UI的標(biāo)簽或其他元素qDebug("onGpsUpdated");ui->gps->setText(QString::number(longitude, 'f', 10) + " " + QString::number(latitude, 'f', 10));
}
這個(gè)槽函數(shù)用于處理 GPS 更新事件,更新用戶界面上顯示的 GPS 坐標(biāo)信息。
槽函數(shù) onRouteDrawn:
void MainWindow::onRouteDrawn()
{// 在這里可以執(zhí)行與路線繪制相關(guān)的操作// 例如,顯示路線的標(biāo)簽或其他元素ui->route->setText("正在繪制路線...");
}
這個(gè)槽函數(shù)用于處理路線繪制完成事件,更新用戶界面上顯示的信息。
槽函數(shù) onSpeedLimitReceived:
void MainWindow::onSpeedLimitReceived(int limit)
{// 在這里可以更新UI以顯示限速信息// 例如,顯示限速信息的標(biāo)簽或其他元素ui->speed->setText("Speed Limit:" + QString::number(limit));
}
這個(gè)槽函數(shù)用于處理速度限制接收事件,更新用戶界面上顯示的限速信息。
槽函數(shù) 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("");}
}
這個(gè)槽函數(shù)用于處理按鈕點(diǎn)擊事件。如果按鈕上的文本是 “繪制”,則連接定時(shí)器的超時(shí)信號(hào)到 onTimerTimeout 槽函數(shù),并啟動(dòng)定時(shí)器以觸發(fā)路線繪制。如果按鈕上的文本是 “取消繪制”,則停止定時(shí)器并重置界面上顯示的路線信息。
槽函數(shù) onTimerTimeout:
void MainWindow::onTimerTimeout()
{// 在定時(shí)器槽函數(shù)中調(diào)用gpsManager的函數(shù)lng = lng - 0.0003;lat = lat - 0.0003;gpsManager->setGPSLocation(lng, lat);gpsManager->drawRoute(ui->webEngineView->page());qDebug("%.10f %.10f", lng, lat);
}
這個(gè)槽函數(shù)用于處理定時(shí)器超時(shí)事件。在超時(shí)時(shí),它調(diào)用 gpsManager 的函數(shù)來模擬 GPS 位置的變化,并觸發(fā)路線繪制。在示例中,lng 和 lat 分別減小了0.0003,表示模擬GPS位置的移動(dòng)。
Map
map.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>運(yùn)輸軌跡圖</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; // 保存地圖對(duì)象var polyline; // 保存繪制的路線var points = []; // 保存所有點(diǎn)坐標(biāo)// 創(chuàng)建地圖函數(shù)function createMap() {// 如果地圖對(duì)象不存在,創(chuàng)建地圖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();// 監(jiān)聽窗口大小變化事件,以動(dòng)態(tài)調(diào)整地圖大小window.addEventListener("resize", resizeMap);}// 初始化地圖createMap();// 定義繪制路線的函數(shù)function drawRoute() {// 生成坐標(biāo)點(diǎn)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);//}// 創(chuàng)建路線polyline = new BMap.Polyline(trackPoint, {strokeColor:"green", strokeWeight:6, strokeOpacity:1});map.addOverlay(polyline);}// 定義繪制新點(diǎn)的函數(shù)function drawNewPoint(lng, lat) {// 添加新的點(diǎn)坐標(biāo)到 points 數(shù)組中var newPoint = { lng: lng, lat: lat };points.push(newPoint);// 如果超過最大長(zhǎng)度,刪除最早的點(diǎn)坐標(biāo)if (points.length > 10) {points.splice(0, points.length - 10);}// 調(diào)用繪制路線函數(shù)以繪制新的路線drawRoute();// 獲取最后一個(gè)點(diǎn)的坐標(biāo)var lastPoint = new BMap.Point(lng, lat);// 計(jì)算地圖視野以包含整個(gè)路線var view = map.getViewport(points);// 調(diào)整視野以確保最后一個(gè)點(diǎn)在地圖中央var centerPoint = view.center;map.centerAndZoom(centerPoint, view.zoom);map.setCenter(lastPoint);}// 自適應(yīng)地圖大小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>