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