基于Qt實(shí)現(xiàn)離線瓦片地圖下載器
一、前言
寫(xiě)這個(gè)離線地圖下載器的初衷,就是為了方便自己的幾個(gè)需要離線地圖的程序,客戶(hù)需求,既然地圖程序已經(jīng)可以支持離線地圖,那如何獲取到這些離線瓦片地圖文件是個(gè)關(guān)鍵,而且這是這個(gè)功能的關(guān)鍵,拿到這些一張張的瓦片圖片文件,才能根據(jù)js函數(shù)繪制組合成離線地圖。
網(wǎng)上其實(shí)有很多各種各樣的離線地圖下載器,大部分都是要收費(fèi)的,免費(fèi)的要么是限制了下載的瓦片數(shù)量或者級(jí)別,要么是下載的瓦片圖打上了水印,看起來(lái)很難看,由于經(jīng)常需要用到離線地圖,擺脫這個(gè)限制,特意花了點(diǎn)時(shí)間重新研究了瓦片地圖的原理,做了個(gè)離線地圖下載器,其實(shí)瓦片地圖下載沒(méi)有那么復(fù)雜,其實(shí)就是從開(kāi)放的幾個(gè)服務(wù)器地址組建要請(qǐng)求的瓦片地圖的地址,發(fā)送請(qǐng)求以后會(huì)自動(dòng)將圖片返回給你,你只需要拿到圖片數(shù)據(jù)保存成圖片即可。
瓦片地圖下載流程步驟如下:
- 獲取可視區(qū)域或者行政區(qū)域的范圍。
- 拿到區(qū)域的左下角右上角經(jīng)緯度坐標(biāo)。
- 根據(jù)層級(jí)數(shù)計(jì)算對(duì)應(yīng)層級(jí)的瓦片數(shù)。
- 自動(dòng)生成下載瓦片地圖的地址并發(fā)出請(qǐng)求。
- 解析收到的數(shù)據(jù)保存成圖片。
- 更新對(duì)應(yīng)界面的下載數(shù)量和進(jìn)度。
- 可選擇對(duì)應(yīng)保存的目錄、全選層級(jí)、中途停止下載等。
- 可選擇是下載街道圖還是衛(wèi)星圖等。
二、功能特點(diǎn)
多線程同步下載多級(jí)別瓦片地圖,不卡界面。
內(nèi)置多個(gè)離線地圖下載請(qǐng)求地址,自動(dòng)隨機(jī)選擇一個(gè)發(fā)送請(qǐng)求。
下載地圖類(lèi)型同時(shí)支持街道圖和衛(wèi)星圖。
自動(dòng)計(jì)算可視區(qū)域或者行政區(qū)域的下載瓦片數(shù)量。
下載的級(jí)別可以自定義范圍和選擇。
每個(gè)瓦片下載完成都發(fā)送信號(hào)通知,參數(shù)包括下載用時(shí)。
可設(shè)置下載最大超時(shí)時(shí)間,超過(guò)了則丟棄跳到下一個(gè)下載任務(wù)。
實(shí)時(shí)顯示下載進(jìn)度,以及當(dāng)前級(jí)別已經(jīng)下載的瓦片數(shù)和總瓦片數(shù)。
下載過(guò)程中可以停止下載,下載完成自動(dòng)統(tǒng)計(jì)總用時(shí)。
內(nèi)置經(jīng)緯度和屏幕坐標(biāo)互相轉(zhuǎn)換函數(shù)。
目前支持百度地圖,其他地圖比如谷歌地圖、騰訊地圖、高德地圖可以定制。
函數(shù)接口友好和統(tǒng)一,使用簡(jiǎn)單方便,就一個(gè)類(lèi)。
支持任意Qt版本、任意系統(tǒng)、任意編譯器。
三、體驗(yàn)地址
體驗(yàn)地址:https://pan.baidu.com/s/15ZKAlptW-rDcNq8zlzdYLg 提取碼:uyes 文件名:bin_map.zip
國(guó)內(nèi)站點(diǎn):https://gitee.com/feiyangqingyun
國(guó)際站點(diǎn):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;
}
//啟動(dòng)計(jì)時(shí)
QElapsedTimer time;
time.start();
//先判斷文件夾是否存在,不存在則新建
QDir dir(dirName);
if (!dir.exists()) {
dir.mkpath(dirName);
}
//局部的事件循環(huán),不卡主界面
QEventLoop eventLoop;
//設(shè)置超時(shí) 5.15開(kāi)始自帶了超時(shí)時(shí)間函數(shù) 默認(rèn)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)計(jì)
error = true;
qDebug() << TIMEMS << "下載出錯(cuò)" << reply->errorString();
}
reply->deleteLater();
int useTime = time.elapsed();
emit finsh(url, fileName, zoom, useTime, error);
}
到此這篇關(guān)于基于Qt實(shí)現(xiàn)離線瓦片地圖下載器的文章就介紹到這了,更多相關(guān)Qt離線瓦片地圖下載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
VSCode Linux的C++代碼格式化配置的實(shí)現(xiàn)
動(dòng)格式化代碼容易出現(xiàn)錯(cuò)誤,特別是當(dāng)代碼量較大時(shí),使用自動(dòng)格式化可以減少這種錯(cuò)誤的風(fēng)險(xiǎn),本文主要介紹了VSCode Linux的C++代碼格式化配置的實(shí)現(xiàn),感興趣的可以了解一下2023-10-10
C++算法學(xué)習(xí)之貪心算法的應(yīng)用
貪心算法是指,在對(duì)問(wèn)題求解時(shí),總是做出在當(dāng)前看來(lái)是最好的選擇。本文為大家準(zhǔn)備了幾個(gè)示例,從而能深入了解貪心算法的應(yīng)用,需要的可以參考一下2022-05-05
詳解C語(yǔ)言如何執(zhí)行HTTP GET請(qǐng)求
在現(xiàn)代互聯(lián)網(wǎng)時(shí)代,網(wǎng)絡(luò)數(shù)據(jù)的獲取和分析變得越來(lái)越重要,本文我們將使用C語(yǔ)言和libcurl庫(kù)來(lái)編寫(xiě)一個(gè)簡(jiǎn)單的網(wǎng)絡(luò)爬蟲(chóng),以執(zhí)行HTTP GET請(qǐng)求并獲取淘寶網(wǎng)頁(yè)的內(nèi)容,感興趣的可以了解下2023-11-11
c++ 形狀類(lèi)Shape(派生出圓類(lèi)Circle和矩形類(lèi)Rectangle)
通過(guò)C++方式,建立一個(gè)形狀類(lèi)Shape作為基類(lèi),派生出圓類(lèi)Circle和矩形類(lèi)Rectangle 求出面積并獲取相關(guān)信息2020-11-11
C++實(shí)現(xiàn)簡(jiǎn)易圖書(shū)館管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)易圖書(shū)館管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
基于malloc與free函數(shù)的實(shí)現(xiàn)代碼及分析
本篇文章介紹了malloc與free函數(shù)的實(shí)現(xiàn)代碼及分析。需要的朋友參考下2013-05-05

