基于Qt實現(xiàn)離線瓦片地圖下載器
一、前言
寫這個離線地圖下載器的初衷,就是為了方便自己的幾個需要離線地圖的程序,客戶需求,既然地圖程序已經(jīng)可以支持離線地圖,那如何獲取到這些離線瓦片地圖文件是個關(guān)鍵,而且這是這個功能的關(guān)鍵,拿到這些一張張的瓦片圖片文件,才能根據(jù)js函數(shù)繪制組合成離線地圖。
網(wǎng)上其實有很多各種各樣的離線地圖下載器,大部分都是要收費的,免費的要么是限制了下載的瓦片數(shù)量或者級別,要么是下載的瓦片圖打上了水印,看起來很難看,由于經(jīng)常需要用到離線地圖,擺脫這個限制,特意花了點時間重新研究了瓦片地圖的原理,做了個離線地圖下載器,其實瓦片地圖下載沒有那么復雜,其實就是從開放的幾個服務器地址組建要請求的瓦片地圖的地址,發(fā)送請求以后會自動將圖片返回給你,你只需要拿到圖片數(shù)據(jù)保存成圖片即可。
瓦片地圖下載流程步驟如下:
- 獲取可視區(qū)域或者行政區(qū)域的范圍。
- 拿到區(qū)域的左下角右上角經(jīng)緯度坐標。
- 根據(jù)層級數(shù)計算對應層級的瓦片數(shù)。
- 自動生成下載瓦片地圖的地址并發(fā)出請求。
- 解析收到的數(shù)據(jù)保存成圖片。
- 更新對應界面的下載數(shù)量和進度。
- 可選擇對應保存的目錄、全選層級、中途停止下載等。
- 可選擇是下載街道圖還是衛(wèi)星圖等。
二、功能特點
多線程同步下載多級別瓦片地圖,不卡界面。
內(nèi)置多個離線地圖下載請求地址,自動隨機選擇一個發(fā)送請求。
下載地圖類型同時支持街道圖和衛(wèi)星圖。
自動計算可視區(qū)域或者行政區(qū)域的下載瓦片數(shù)量。
下載的級別可以自定義范圍和選擇。
每個瓦片下載完成都發(fā)送信號通知,參數(shù)包括下載用時。
可設(shè)置下載最大超時時間,超過了則丟棄跳到下一個下載任務。
實時顯示下載進度,以及當前級別已經(jīng)下載的瓦片數(shù)和總瓦片數(shù)。
下載過程中可以停止下載,下載完成自動統(tǒng)計總用時。
內(nèi)置經(jīng)緯度和屏幕坐標互相轉(zhuǎn)換函數(shù)。
目前支持百度地圖,其他地圖比如谷歌地圖、騰訊地圖、高德地圖可以定制。
函數(shù)接口友好和統(tǒng)一,使用簡單方便,就一個類。
支持任意Qt版本、任意系統(tǒng)、任意編譯器。
三、體驗地址
體驗地址:https://pan.baidu.com/s/15ZKAlptW-rDcNq8zlzdYLg 提取碼:uyes 文件名:bin_map.zip
國內(nèi)站點:https://gitee.com/feiyangqingyun
國際站點:https://github.com/feiyangqingyun
四、效果圖
五、相關(guān)代碼
void MapDownload::download(const QString &path, int mapType, int downType, int xmin, int xmax, int ymin, int ymax, int zoom) { for (int x = xmin; x <= xmax; x++) { for (int y = ymin; y <= ymax; y++) { if (stopped) { return; } QString url = getUrl(mapType, downType, x, y, zoom); QString dirName = QString("%1/%2/%3/").arg(path).arg(zoom).arg(x); QString fileName = QString("%1.jpg").arg(y); downloadImage(url, dirName, fileName, zoom); } } } void MapDownload::downloadBaiDu(const QString &path, int downType, int xmin, int xmax, int ymin, int ymax, int zoom) { download(path, 0, downType, xmin, xmax, ymin, ymax, zoom); } void MapDownload::downloadTian(const QString &path, int downType, int xmin, int xmax, int ymin, int ymax, int zoom) { download(path, 3, downType, xmin, xmax, ymin, ymax, zoom); } void MapDownload::downloadGoogle(const QString &path, int downType, int xmin, int xmax, int ymin, int ymax, int zoom) { download(path, 4, downType, xmin, xmax, ymin, ymax, zoom); } void MapDownload::downloadImage(const QString &url, const QString &dirName, const QString &fileName, int zoom) { if (url.isEmpty()) { return; } //啟動計時 QElapsedTimer time; time.start(); //先判斷文件夾是否存在,不存在則新建 QDir dir(dirName); if (!dir.exists()) { dir.mkpath(dirName); } //局部的事件循環(huán),不卡主界面 QEventLoop eventLoop; //設(shè)置超時 5.15開始自帶了超時時間函數(shù) 默認30秒 #if (QT_VERSION >= QT_VERSION_CHECK(5,15,0)) manager->setTransferTimeout(timeout); #else QTimer timer; connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit())); timer.setSingleShot(true); timer.start(timeout); #endif QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url))); connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit())); eventLoop.exec(); bool error = false; if (reply->bytesAvailable() > 0 && reply->error() == QNetworkReply::NoError) { //讀取所有數(shù)據(jù)保存成文件 QByteArray data = reply->readAll(); QFile file(dirName + fileName); if (file.open(QFile::WriteOnly | QFile::Truncate)) { file.write(data); file.close(); } } else { //可以自行增加下載失敗的統(tǒng)計 error = true; qDebug() << TIMEMS << "下載出錯" << reply->errorString(); } reply->deleteLater(); int useTime = time.elapsed(); emit finsh(url, fileName, zoom, useTime, error); }
到此這篇關(guān)于基于Qt實現(xiàn)離線瓦片地圖下載器的文章就介紹到這了,更多相關(guān)Qt離線瓦片地圖下載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
VSCode Linux的C++代碼格式化配置的實現(xiàn)
動格式化代碼容易出現(xiàn)錯誤,特別是當代碼量較大時,使用自動格式化可以減少這種錯誤的風險,本文主要介紹了VSCode Linux的C++代碼格式化配置的實現(xiàn),感興趣的可以了解一下2023-10-10c++ 形狀類Shape(派生出圓類Circle和矩形類Rectangle)
通過C++方式,建立一個形狀類Shape作為基類,派生出圓類Circle和矩形類Rectangle 求出面積并獲取相關(guān)信息2020-11-11基于malloc與free函數(shù)的實現(xiàn)代碼及分析
本篇文章介紹了malloc與free函數(shù)的實現(xiàn)代碼及分析。需要的朋友參考下2013-05-05