一、前言
網上其實有很多各種各樣的離線地圖下載下傳器,大部分都是要收費的,免費的要麼是限制了下載下傳的瓦片數量或者級别,要麼是下載下傳的瓦片圖打上了水印,看起來很難看,由于經常需要用到離線地圖,擺脫這個限制,特意花了點時間重新研究了瓦片地圖的原理,做了個離線地圖下載下傳器,其實瓦片地圖下載下傳沒有那麼複雜,其實就是從開放的幾個伺服器位址組建要請求的瓦片地圖的位址,發送請求以後會自動将圖檔傳回給你,你隻需要拿到圖檔資料儲存成圖檔即可。
瓦片地圖下載下傳流程步驟如下:
- 擷取可視區域或者行政區域的範圍
- 拿到區域的左下角右上角經緯度坐标
- 根據層級數計算對應層級的瓦片數
- 自動生成下載下傳瓦片地圖的位址并送出請求
- 解析收到的資料儲存成圖檔
- 更新對應界面的下載下傳數量和進度
- 可選擇對應儲存的目錄、全選層級、中途停止下載下傳等
- 可選擇是下載下傳街道圖還是衛星圖等
二、功能特點
- 同時支援線上地圖和離線地圖兩種模式。
- 同時支援webkit核心、webengine核心、IE核心。
- 支援設定多個标注點,資訊包括名稱、位址、經緯度。
- 可設定地圖是否可單擊、拖動、滑鼠滾輪縮放。
- 可設定協定版本、秘鑰、主題樣式、中心坐标、中心城市、地理編碼位置等。
- 可設定地圖縮放比例和級别,縮略圖、比例尺、路況資訊等控件的可見。
- 支援地圖互動,比如滑鼠按下擷取對應位置的經緯度。
- 支援查詢路線,可設定起點位置、終點位置、路線模式、路線方式、路線方案(最少時間、最少換乘、最少步行、不乘地鐵、最短距離、避開高速)。
- 可顯示點線面工具,可直接在地圖上劃線、點、矩形、圓形等。
- 可設定行政區劃,指定某個城市區域繪制圖層,線上地圖自動輸出行政區劃邊界點集合到js檔案給離線地圖使用。
- 可靜态或者動态添加多個覆寫物。支援點、折線、多邊形、矩形、圓形、弧線、點聚合等。
- 函數接口友好和統一,使用簡單友善,就一個類。
- 支援js動态互動添加點、删除點、清空點、重置點,不需要重新整理頁面。
- 支援任意Qt版本、任意系統、任意編譯器。
三、體驗位址
- 體驗位址: https://pan.baidu.com/s/1uQsDQO5E5crUBN2J-nPeLQ 提取碼:1jkp 檔案名:bin_map.zip
- 國内站點: https://gitee.com/feiyangqingyun
- 國際站點: https://github.com/feiyangqingyun
- 個人首頁: https://blog.csdn.net/feiyangqingyun
- 知乎首頁: https://www.zhihu.com/people/feiyangqingyun/
四、效果圖
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLwEWN4cjNkJDZwQDZ5EWOwUWZmFDZ3kzMmJDN3IGMjFDN2IGZlZWNj9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.gif)
五、相關代碼
void MapDownload::download(const QString &url, const QString &dirName, const QString &fileName, int zoom)
{
if (url.isEmpty()) {
return;
}
//啟動計時
QTime time;
time.start();
//先判斷檔案夾是否存在,不存在則建立
QDir dir(dirName);
if (!dir.exists()) {
dir.mkpath(dirName);
}
//局部的事件循環,不卡主界面
QEventLoop eventLoop;
QNetworkReply *reply = manager->get(QNetworkRequest(QUrl(url)));
connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
//設定下載下傳逾時
QTimer timer;
connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
timer.setSingleShot(true);
timer.start(timeout);
eventLoop.exec();
bool error = false;
if (reply->bytesAvailable() > 0 && reply->error() == QNetworkReply::NoError) {
//讀取所有資料儲存成檔案
QByteArray data = reply->readAll();
QFile file(dirName + fileName);
if (file.open(QFile::WriteOnly | QFile::Truncate)) {
file.write(data);
file.close();
}
} else {
//可以自行增加下載下傳失敗的統計
error = true;
qDebug() << TIMEMS << "下載下傳出錯" << reply->errorString();
}
int useTime = time.elapsed();
emit finsh(url, fileName, zoom, useTime, error);
}