一、前言
離線地圖的加載其實和在線地圖的加載方法幾乎一樣,唯一的最大區別就是,之前可能一個js文件引入即可,現在需要多個本地的js文件引入,而且網上流傳的js文件的版本比較舊,意味着現在新版的支持opengl形式的地圖無法支持,后期再去網上搜索找找看能不能搞到最新的版本。
離線地圖加載依賴一堆的js文件,整個文件夾可以自定義放置的位置,在網頁代碼引入的時候指定位置就行,一般建議就放在可執行文件下新建一個目錄專門存放,這樣管理方便,離線地圖對應的圖片文件目錄也是可配置的,也建議放在這個目錄下。
二、功能特點
- 多線程同步下載多級別瓦片地圖,不卡界面。
- 內置多個離線地圖下載請求地址,自動隨機選擇一個發送請求。
- 下載地圖類型同時支持街道圖和衛星圖。
- 自動計算可視區域或者行政區域的下載瓦片數量。
- 下載的級別可以自定義范圍和選擇。
- 每個瓦片下載完成都發送信號通知,參數包括下載用時。
- 可設置下載最大超時時間,超過了則丟棄跳到下一個下載任務。
- 實時顯示下載進度,以及當前級別已經下載的瓦片數和總瓦片數。
- 下載過程中可以停止下載,下載完成自動統計總用時。
- 內置經緯度和屏幕坐標互相轉換函數。
- 目前支持百度地圖,其他地圖比如谷歌地圖、騰訊地圖、高德地圖可以定制。
- 函數接口友好和統一,使用簡單方便,就一個類。
- 支持任意Qt版本、任意系統、任意編譯器。
三、體驗地址
- 體驗地址:https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A 提取碼:o05q 文件名:bin_map.zip
- 國內站點:https://gitee.com/feiyangqingyun
- 國際站點:https://github.com/feiyangqingyun
- 個人主頁:https://blog.csdn.net/feiyangqingyun
- 知乎主頁:https://www.zhihu.com/people/feiyangqingyun/
四、效果圖
五、相關代碼
void frmMapDownload::getCount()
{
//計算瓦片數
QString pointLeftBottom = ui->txtPointLeftBottom->text();
QString pointRightTop = ui->txtPointRightTop->text();
QStringList listLeftBottom = pointLeftBottom.split(",");
QStringList listRightTop = pointRightTop.split(",");
double lngLeftBottom = listLeftBottom.at(0).toDouble();
double latLeftBottom = listLeftBottom.at(1).toDouble();
double lngRightTop = listRightTop.at(0).toDouble();
double latRightTop = listRightTop.at(1).toDouble();
//mapType=0表示百度地圖 =4表示谷歌地圖
int mapType = ui->cboxMapType->currentIndex();
for (int zoom = indexMin; zoom <= indexMax; zoom++) {
int index = zoom - indexMin;
//不同的地圖計算的坐標不一樣
QPoint pt1, pt2;
if (mapType == 3) {
pt1 = WebHelper::lngLatToTileTian(lngLeftBottom, latLeftBottom, zoom);
pt2 = WebHelper::lngLatToTileTian(lngRightTop, latRightTop, zoom);
} else if (mapType == 4) {
pt1 = WebHelper::lngLatToTileGoogle(lngLeftBottom, latLeftBottom, zoom);
pt2 = WebHelper::lngLatToTileGoogle(lngRightTop, latRightTop, zoom);
} else {
pt1 = WebHelper::lngLatToTileBaiDu(lngLeftBottom, latLeftBottom, zoom);
pt2 = WebHelper::lngLatToTileBaiDu(lngRightTop, latRightTop, zoom);
}
//計算XY坐標最大值最小值
int xmin = qMin(pt1.x(), pt2.x());
int xmax = qMax(pt1.x(), pt2.x());
int ymin = qMin(pt1.y(), pt2.y());
int ymax = qMax(pt1.y(), pt2.y());
pt1 = QPoint(xmin, ymin);
pt2 = QPoint(xmax, ymax);
//方便打印查看計算的結果
if (zoom == 20) {
qDebug() << lngLeftBottom << latLeftBottom << lngRightTop << latRightTop << pt1 << pt2;
}
//當前級別的瓦片數
int count = 0;
for (int j = xmin; j <= xmax; j++) {
for (int k = ymin; k <= ymax; k++) {
count++;
}
}
//顯示對應的瓦片總數,設置進度條參數,並更新對應的值
if (count > 0) {
bars.at(index)->setRange(0, count);
}
bars.at(index)->setValue(0);
labs.at(index)->setText(QString::number(count));
pointLeftBottoms[index] = pt1;
pointRightTops[index] = pt2;
}
}
void frmMapDownload::clear()
{
//先進度條全部置為0
currentCount = 0;
foreach (QProgressBar *bar, bars) {
bar->setValue(0);
}
}
void frmMapDownload::receiveDataFromJs(const QString &type, const QVariant &data)
{
if (data.isNull()) {
return;
}
//qDebug() << "frmMapDownload" << type << data;
QString result = data.toString();
if (type == "zoom") {
float zoom = result.toFloat();
QString strZoom = QString::number(zoom, 'f', 3);
ui->txtZoom->setText(strZoom);
} else if (type == "bounds") {
QStringList list = result.split(",");
if (list.count() == 7) {
QString lat, lng, point;
lng = WebHelper::getLngLat1(list.at(0));
lat = WebHelper::getLngLat1(list.at(1));
point = QString("%1,%2").arg(lng).arg(lat);
ui->txtPointLeftBottom->setText(point);
lng = WebHelper::getLngLat1(list.at(2));
lat = WebHelper::getLngLat1(list.at(3));
point = QString("%1,%2").arg(lng).arg(lat);
ui->txtPointRightTop->setText(point);
lng = WebHelper::getLngLat1(list.at(4));
lat = WebHelper::getLngLat1(list.at(5));
point = QString("%1,%2").arg(lng).arg(lat);
ui->txtPointCenter->setText(point);
float zoom = list.at(6).toFloat();
QString strZoom = QString::number(zoom, 'f', 3);
ui->txtZoom->setText(strZoom);
//自動統計瓦片數
this->getCount();
//滾動條滾到最下面,一般都是需要下載級別大的
ui->tableWidget->scrollToBottom();
}
} else if (type == "point") {
QString point = WebHelper::getLngLat2(result);
ui->txtPointCenter->setText(point);
}
}