天天看點

Qt編寫地圖綜合應用14-離線地圖下載下傳

一、前言

網上其實有很多各種各樣的離線地圖下載下傳器,大部分都是要收費的,免費的要麼是限制了下載下傳的瓦片數量或者級别,要麼是下載下傳的瓦片圖打上了水印,看起來很難看,由于經常需要用到離線地圖,擺脫這個限制,特意花了點時間重新研究了瓦片地圖的原理,做了個離線地圖下載下傳器,其實瓦片地圖下載下傳沒有那麼複雜,其實就是從開放的幾個伺服器位址組建要請求的瓦片地圖的位址,發送請求以後會自動将圖檔傳回給你,你隻需要拿到圖檔資料儲存成圖檔即可。

瓦片地圖下載下傳流程步驟如下:

  1. 擷取可視區域或者行政區域的範圍
  2. 拿到區域的左下角右上角經緯度坐标
  3. 根據層級數計算對應層級的瓦片數
  4. 自動生成下載下傳瓦片地圖的位址并送出請求
  5. 解析收到的資料儲存成圖檔
  6. 更新對應界面的下載下傳數量和進度
  7. 可選擇對應儲存的目錄、全選層級、中途停止下載下傳等
  8. 可選擇是下載下傳街道圖還是衛星圖等

二、功能特點

  1. 同時支援線上地圖和離線地圖兩種模式。
  2. 同時支援webkit核心、webengine核心、IE核心。
  3. 支援設定多個标注點,資訊包括名稱、位址、經緯度。
  4. 可設定地圖是否可單擊、拖動、滑鼠滾輪縮放。
  5. 可設定協定版本、秘鑰、主題樣式、中心坐标、中心城市、地理編碼位置等。
  6. 可設定地圖縮放比例和級别,縮略圖、比例尺、路況資訊等控件的可見。
  7. 支援地圖互動,比如滑鼠按下擷取對應位置的經緯度。
  8. 支援查詢路線,可設定起點位置、終點位置、路線模式、路線方式、路線方案(最少時間、最少換乘、最少步行、不乘地鐵、最短距離、避開高速)。
  9. 可顯示點線面工具,可直接在地圖上劃線、點、矩形、圓形等。
  10. 可設定行政區劃,指定某個城市區域繪制圖層,線上地圖自動輸出行政區劃邊界點集合到js檔案給離線地圖使用。
  11. 可靜态或者動态添加多個覆寫物。支援點、折線、多邊形、矩形、圓形、弧線、點聚合等。
  12. 函數接口友好和統一,使用簡單友善,就一個類。
  13. 支援js動态互動添加點、删除點、清空點、重置點,不需要重新整理頁面。
  14. 支援任意Qt版本、任意系統、任意編譯器。

三、體驗位址

  1. 體驗位址: https://pan.baidu.com/s/1uQsDQO5E5crUBN2J-nPeLQ 提取碼:1jkp 檔案名:bin_map.zip
  2. 國内站點: https://gitee.com/feiyangqingyun
  3. 國際站點: https://github.com/feiyangqingyun
  4. 個人首頁: https://blog.csdn.net/feiyangqingyun
  5. 知乎首頁: https://www.zhihu.com/people/feiyangqingyun/

四、效果圖

Qt編寫地圖綜合應用14-離線地圖下載下傳

五、相關代碼

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);
}           

繼續閱讀