Qt編寫地圖之實(shí)現(xiàn)跨平臺功能
一、前言
跨平臺著實(shí)花了不少的精力,為了從Qt4.7兼容到Qt6.2及后續(xù)版本,頭發(fā)掉了不少,僅有的幾根毛所剩無幾,哎,可能這就是程序員的命,本人寫Qt程序這么多年,比較喜歡支持多個(gè)Qt版本,尤其是鐘情于支持任意Qt版本+任意系統(tǒng)+任意編譯器,這句話說起來簡單其實(shí)實(shí)現(xiàn)起來就不容易了,首先你得有個(gè)很多版本的測試環(huán)境,起碼十幾個(gè)Qt環(huán)境要的吧,四五種操作系統(tǒng)要的吧,還要安裝各種VS版本免不了的,畢竟win上除了默認(rèn)的mingw編譯器還有很多人用的是msvc編譯器,這么一大堆環(huán)境折騰下來,沒有個(gè)1T硬盤是不夠的,而且官網(wǎng)發(fā)布Qt版本的速度相當(dāng)快,最慢半年肯定來一個(gè)版本,又得測試了,每次發(fā)布一個(gè)大的版本,除了常用的windows以外,linux要測試吧,而且現(xiàn)在還多出來一些國產(chǎn)linux系統(tǒng)比如deepin new start UOS之類的,也要試試吧,哎呀好累。
二、功能特點(diǎn)
1 省市區(qū)域地圖封裝類功能特點(diǎn)
- 同時(shí)支持閃爍點(diǎn)圖、遷徙圖、區(qū)域地圖、世界地圖、儀表盤等。
- 可以設(shè)置標(biāo)題、提示信息、背景顏色、文字顏色、線條顏色、區(qū)域顏色等各種顏色。
- 可設(shè)置城市的名稱、值、經(jīng)緯度 集合。
- 可設(shè)置地圖的放大倍數(shù)、是否允許鼠標(biāo)滾輪縮放。
- 內(nèi)置世界地圖、全國地圖、省份地圖、地區(qū)地圖,可以精確到縣,所有地圖全部離線使用。
- 內(nèi)置了各省市json數(shù)據(jù)文件轉(zhuǎn)js文件功能,如有數(shù)據(jù)更新自行轉(zhuǎn)換即可,支持單個(gè)文件轉(zhuǎn)換和一鍵轉(zhuǎn)換所有文件。
- 內(nèi)置了從json文件或者js文件獲取該區(qū)域的所有名稱和經(jīng)緯度信息集合的功能,可以通過該方法獲取到信息用來顯示。
- 依賴瀏覽器組件顯示地圖,提供的demo支持webkit/webengine/miniblink/ie 多種方式加載網(wǎng)頁。
- 采用miniblink瀏覽器內(nèi)核打通了Qt5.6及后續(xù)版本+mingw編譯器缺少瀏覽器模塊的遺憾,使得整個(gè)項(xiàng)目支持所有Qt版本,親測4.7到6.2等任意版本。
- 閃爍點(diǎn)遷徙圖等設(shè)置的點(diǎn)支持單獨(dú)設(shè)置顏色。
- 提供接口直接獲取點(diǎn)擊的點(diǎn)相關(guān)信息,方便程序聯(lián)動(dòng)處理。
- 拓展性極強(qiáng),可以依葫蘆畫瓢自行增加各種精美的echarts組件,做出牛逼的效果。
- 內(nèi)置的儀表盤組件提供交互功能,demo演示中包含了對應(yīng)的代碼。
- 函數(shù)接口友好和統(tǒng)一,使用簡單方便,就一個(gè)類。
- 支持任意Qt版本、任意系統(tǒng)、任意編譯器。
2 百度地圖封裝類功能特點(diǎn)
- 同時(shí)支持在線地圖和離線地圖兩種模式。
- 同時(shí)支持webkit內(nèi)核、webengine內(nèi)核、miniblink內(nèi)核、IE內(nèi)核。
- 支持設(shè)置多個(gè)標(biāo)注點(diǎn),信息包括名稱、地址、經(jīng)緯度。
- 可設(shè)置地圖是否可單擊、拖動(dòng)、鼠標(biāo)滾輪縮放。
- 可設(shè)置協(xié)議版本、秘鑰、主題樣式、中心坐標(biāo)、中心城市、地理編碼位置等。
- 可設(shè)置地圖縮放比例和級別,縮略圖、比例尺、路況信息等控件的可見。
- 支持地圖交互,比如鼠標(biāo)按下獲取對應(yīng)位置的經(jīng)緯度。
- 支持查詢路線,可設(shè)置起點(diǎn)位置、終點(diǎn)位置、路線模式、路線方式、路線方案(最少時(shí)間、最少換乘、最少步行、不乘地鐵、最短距離、避開高速)。
- 可顯示點(diǎn)線面工具,可直接在地圖上劃線、點(diǎn)、矩形、圓形等。
- 可設(shè)置行政區(qū)劃,指定某個(gè)城市區(qū)域繪制圖層,在線地圖自動(dòng)輸出行政區(qū)劃邊界點(diǎn)集合到j(luò)s文件給離線地圖使用。
- 可靜態(tài)或者動(dòng)態(tài)添加多個(gè)覆蓋物。支持點(diǎn)、折線、多邊形、矩形、圓形、弧線、點(diǎn)聚合等。
- 提供函數(shù)接口處理經(jīng)緯度解析成地址和地址解析成經(jīng)緯度坐標(biāo)。
- 提供的demo直接可以單獨(dú)選點(diǎn)執(zhí)行對應(yīng)的處理比如路線查詢。
- 可以拿到路線查詢到的點(diǎn)坐標(biāo)信息集合,比如用于機(jī)器人坐標(biāo)導(dǎo)航等。
- 封裝了豐富的函數(shù)比如刪除指定點(diǎn)和所有點(diǎn),刪除指定覆蓋物和所有覆蓋物等。
- 標(biāo)注點(diǎn)彈框信息可以自定義內(nèi)容,標(biāo)準(zhǔn)html格式。
- 標(biāo)注點(diǎn)單擊事件可選 0-不處理 1-自己彈框 2-發(fā)送信號。
- 標(biāo)注點(diǎn)可設(shè)置動(dòng)畫效果 0-不處理 1-跳動(dòng) 2-墜落
- 標(biāo)注點(diǎn)可設(shè)置本地圖片文件等。
- 函數(shù)接口友好和統(tǒng)一,使用簡單方便,就一個(gè)類。
- 支持js動(dòng)態(tài)交互添加點(diǎn)、刪除點(diǎn)、清空點(diǎn)、重置點(diǎn),不需要刷新頁面。
- 支持任意Qt版本、任意系統(tǒng)、任意編譯器。
3 離線地圖下載類功能特點(diǎn)
- 多線程同步下載多級別瓦片地圖,不卡界面。
- 內(nèi)置多個(gè)離線地圖下載請求地址,自動(dòng)隨機(jī)選擇一個(gè)發(fā)送請求。
- 下載地圖類型同時(shí)支持街道圖和衛(wèi)星圖。
- 自動(dòng)計(jì)算可視區(qū)域或者行政區(qū)域的下載瓦片數(shù)量。
- 下載的級別可以自定義范圍和選擇。
- 每個(gè)瓦片下載完成都發(fā)送信號通知,參數(shù)包括下載用時(shí)。
- 可設(shè)置下載最大超時(shí)時(shí)間,超過了則丟棄跳到下一個(gè)下載任務(wù)。
- 實(shí)時(shí)顯示下載進(jìn)度,以及當(dāng)前級別已經(jīng)下載的瓦片數(shù)和總瓦片數(shù)。
- 下載過程中可以停止下載,下載完成自動(dòng)統(tǒng)計(jì)總用時(shí)。
- 內(nèi)置經(jīng)緯度和屏幕坐標(biāo)互相轉(zhuǎn)換函數(shù)。
- 目前支持百度地圖,其他地圖比如谷歌地圖、騰訊地圖、高德地圖可以定制。
- 函數(shù)接口友好和統(tǒng)一,使用簡單方便,就一個(gè)類。
- 支持任意Qt版本、任意系統(tǒng)、任意編譯器。
4 省市輪廓下載類功能特點(diǎn)
- 定時(shí)器排隊(duì)下載省市輪廓圖點(diǎn)坐標(biāo)集合存儲(chǔ)到JS文件。
- 支持一個(gè)行政區(qū)域多個(gè)不規(guī)則區(qū)域下載。
- 自動(dòng)計(jì)算行政區(qū)域的下載輪廓數(shù)量。
- 可精確選擇省份、市區(qū)、縣城,也可直接輸入行政區(qū)域的名稱。
- 可以設(shè)置下載間隔、隨時(shí)開始下載和停止下載。
- 提供編輯邊界功能,可以直接在地圖上編輯好不規(guī)則區(qū)域的點(diǎn)集合,然后獲取邊界點(diǎn)集合數(shù)據(jù),這個(gè)可以用來自己繪制區(qū)域拿到數(shù)據(jù),比如某個(gè)鄉(xiāng)鎮(zhèn)甚至某個(gè)小區(qū)的行政區(qū)域數(shù)據(jù),很牛逼。
三、體驗(yàn)地址
體驗(yàn)地址:https://pan.baidu.com/s/15ZKAlptW-rDcNq8zlzdYLg 提取碼:uyes 文件名:bin_map.zip
國內(nèi)站點(diǎn):https://gitee.com/feiyangqingyun
國際站點(diǎn):https://github.com/feiyangqingyun
四、效果圖
五、相關(guān)代碼
#include "webview.h" #include "qevent.h" #include "qdatetime.h" #include "qdebug.h" #ifdef webkit #include <QtWebKit> #if (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) #include <QtWebKitWidgets> #endif #elif webengine #include <QtWebEngineWidgets> #elif webie #include <QAxWidget> #elif webminiblink #include "miniblink.h" #endif #define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz")) WebView::WebView(QWidget *parent) : QObject(parent) { //初始化web控件配置信息 WebView::initWebSetting(); //初始化通用地圖數(shù)據(jù) WebHelper::initMapData(); //數(shù)據(jù)交互類 webJsData = new WebJsData(this); connect(webJsData, SIGNAL(receiveDataFromJs(QString, QVariant)), this, SIGNAL(receiveDataFromJs(QString, QVariant))); #ifdef webkit webView = new QWebView(parent); #elif webengine webView = new QWebEngineView(parent); //設(shè)置對應(yīng)的通信通道 QWebChannel *channel = new QWebChannel(this); channel->registerObject("objName", webJsData); webView->page()->setWebChannel(channel); #elif webie webView = new QAxWidget(parent); //注冊瀏覽器控件 webView->setControl("{8856F961-340A-11D0-A96B-00C04FD705A2}"); //不顯示警告信息 webView->setProperty("DisplayAlerts", false); //不顯示滾動(dòng)條 webView->setProperty("DisplayScrollBars", true); #elif webminiblink webView = new miniblink(parent); #endif //關(guān)聯(lián)加載完成信號 #if (defined webkit) || (defined webengine) connect(webView->page(), SIGNAL(loadFinished(bool)), this, SLOT(loadFinished())); connect(webView->page(), SIGNAL(loadFinished(bool)), this, SIGNAL(loadFinished(bool))); #elif webminiblink connect(webView, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished())); connect(webView, SIGNAL(loadFinished(bool)), this, SIGNAL(loadFinished(bool))); connect(webView, SIGNAL(receiveDataFromJs(QString, QVariant)), this, SIGNAL(receiveDataFromJs(QString, QVariant))); #endif //設(shè)置沒有右鍵菜單 #if (defined webkit) || (defined webengine) || (defined webie) || (defined webminiblink) webView->setContextMenuPolicy(Qt::NoContextMenu); #endif //安裝事件過濾器 #ifdef webminiblink webView->installEventFilter(this); #endif } void WebView::initWebSetting() { //全局配置只需要設(shè)置一次就行 static bool isInit = false; if (!isInit) { isInit = true; QString webcore = "other"; #ifdef webkit webcore = "webkit"; QWebSettings *webSetting = QWebSettings::globalSettings(); webSetting->setAttribute(QWebSettings::JavascriptEnabled, true); webSetting->setAttribute(QWebSettings::PluginsEnabled, true); webSetting->setAttribute(QWebSettings::JavascriptCanOpenWindows, true); #elif webengine webcore = "webengine"; QWebEngineSettings *webSetting = QWebEngineProfile::defaultProfile()->settings(); webSetting->setAttribute(QWebEngineSettings::JavascriptEnabled, true); webSetting->setAttribute(QWebEngineSettings::PluginsEnabled, true); webSetting->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true); #elif webie webcore = "ie"; #elif webminiblink webcore = "miniblink"; #endif qDebug() << TIMEMS << QString("init webview ok, core: %1").arg(webcore); } } bool WebView::eventFilter(QObject *watched, QEvent *event) { //測試發(fā)現(xiàn)miniblink內(nèi)核(其他內(nèi)核正常),網(wǎng)頁中的右鍵有消息會(huì)傳給父類 if (event->type() == QEvent::MouseButtonPress) { return true; } return QObject::eventFilter(watched, event); } void WebView::setLayout(QLayout *layout) { //把控件加入到布局 #if (defined webkit) || (defined webengine) || (defined webie) || (defined webminiblink) layout->addWidget(webView); #endif } void WebView::setVisible(bool visible) { #if (defined webkit) || (defined webengine) || (defined webie) || (defined webminiblink) webView->setVisible(visible); #endif } void WebView::setBgColor(const QColor &color) { #if (defined webkit) || (defined webie) webView->setStyleSheet(QString("background:%1;").arg(color.name())); #elif (defined webengine) webView->page()->setBackgroundColor(color); #elif (defined webminiblink) webView->setBgColor(color); #endif } void WebView::loadFinished() { #ifdef webkit webView->page()->mainFrame()->addToJavaScriptWindowObject("objName", webJsData); #endif } void WebView::load(const QString &url, const QString &html, const QString &baseUrl) { //如果存在網(wǎng)址則優(yōu)先直接加載網(wǎng)址 if (!url.isEmpty()) { #if (defined webkit) || (defined webengine) webView->load(QUrl(url)); #elif webie webView->dynamicCall("Navigate(const QString&)", url); #elif webminiblink webView->load(url); #endif } else { #if (defined webkit) || (defined webengine) webView->setHtml(html, QUrl(baseUrl)); #elif webminiblink webView->setHtml(html, baseUrl); #endif } } void WebView::runJs(const QString &js) { if (js.isEmpty()) { return; } #ifdef webkit webView->page()->mainFrame()->evaluateJavaScript(js); #elif webengine webView->page()->runJavaScript(js); #elif webminiblink webView->runJs(js); #endif }
以上就是Qt編寫地圖之實(shí)現(xiàn)跨平臺功能的詳細(xì)內(nèi)容,更多關(guān)于Qt地圖 跨平臺的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Ubuntu 20.04 下安裝配置 VScode 的 C/C++ 開發(fā)環(huán)境(圖文教程)
這篇文章主要介紹了Ubuntu 20.04 下安裝配置 VScode 的 C/C++ 開發(fā)環(huán)境,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05C++實(shí)現(xiàn)選擇性排序(SelectionSort)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)選擇性排序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04C++中volatile和mutable關(guān)鍵字用法詳解
這篇文章主要介紹了C++中volatile和mutable關(guān)鍵字用法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02vector list map 遍歷刪除制定元素 防止迭代器失效的實(shí)例
下面小編就為大家?guī)硪黄獀ector list map 遍歷刪除制定元素 防止迭代器失效的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-12-12