精华内容
下载资源
问答
  • QT离线地图
    2022-04-24 16:14:52
    更多相关内容
  • 描述了基于瓦片的离线地图的实现原理及在Qt应用程序开发框架下的实现方案。
  • 更新webkit离线地图离线地图API包含v1.0和v1.3,嵌入式Qt实现百度在线地图与离线地图,利用QWebKit实现。功能包含:离线与在线切换,街道与卫星地图切换,坐标查找,添加坐标。其它功能后续更新,适合嵌入式Qt地图...
  • QT调用百度离线地图

    2019-01-23 22:35:36
    次代码精简充分,绝对能跑,实现了加载离线地图,并与地图进行交互,适合如初学者。(最简单的地图调用)
  • Qt加载百度离线地图

    2018-12-01 12:08:37
    Qt4.8.6加载百度离线地图,实现了街道图和卫星图的切换,实现了地图中标签的移动,实现了获取地图坐标并在Qt界面显示。绝对原创,保证可用
  • 嵌入式Qt实现百度在线地图与离线地图,利用QWebEngine实现,其中包含Qt与js通信技术,如需使用QWebKit实现,方法逻辑类似。功能包含:离线与在线切换,街道与卫星地图切换,坐标查找,添加坐标。其它功能后续更新,...
  • 地图学习
  • qt'实现百度离线地图,完成最短路径规划
  • QT5.1.1里加载离线地图,在html文件里做坐标转换总是实现不了,又不能调试,索性在QT里做,直接在地图上画出来,资源里包含qt坐标转换的代码及html文件
  • Qt加载百度离线地图 1.下载百度地图离线API 1.3 下载链接:http://download.csdn.net/detail/caoshangpa/9476608,网上虽然出现了2.0版本离线API,但是经试用,存在很多问题。该1.3版本离线API也是由高人制作,我...
  • 百度离线地图2.0版本,完全脱离外网,有瓦片图,并且在百度地图上显示星星图标
  • 离线地图加载依赖一堆的js文件,整个文件夹可以自定义放置的位置,在网页代码引入的时候指定位置就行,一般建议就放在可执行文件下新建一个目录专门存放,这样管理方便,离线地图对应的图片文件目录也是可配置的,也...

    一、前言

    离线地图的加载其实和在线地图的加载方法几乎一样,唯一的最大区别就是,之前可能一个js文件引入即可,现在需要多个本地的js文件引入,而且网上流传的js文件的版本比较旧,意味着现在新版的支持opengl形式的地图无法支持,后期再去网上搜索找找看能不能搞到最新的版本。

    离线地图加载依赖一堆的js文件,整个文件夹可以自定义放置的位置,在网页代码引入的时候指定位置就行,一般建议就放在可执行文件下新建一个目录专门存放,这样管理方便,离线地图对应的图片文件目录也是可配置的,也建议放在这个目录下。

    二、功能特点

    1. 多线程同步下载多级别瓦片地图,不卡界面。
    2. 内置多个离线地图下载请求地址,自动随机选择一个发送请求。
    3. 下载地图类型同时支持街道图和卫星图。
    4. 自动计算可视区域或者行政区域的下载瓦片数量。
    5. 下载的级别可以自定义范围和选择。
    6. 每个瓦片下载完成都发送信号通知,参数包括下载用时。
    7. 可设置下载最大超时时间,超过了则丢弃跳到下一个下载任务。
    8. 实时显示下载进度,以及当前级别已经下载的瓦片数和总瓦片数。
    9. 下载过程中可以停止下载,下载完成自动统计总用时。
    10. 内置经纬度和屏幕坐标互相转换函数。
    11. 目前支持百度地图,其他地图比如谷歌地图、腾讯地图、高德地图可以定制。
    12. 函数接口友好和统一,使用简单方便,就一个类。
    13. 支持任意Qt版本、任意系统、任意编译器。

    三、体验地址

    1. 体验地址:https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A 提取码:o05q 文件名: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/

    四、效果图

    在这里插入图片描述

    五、相关代码

    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);
        }
    }
    
    展开全文
  • QT加载地图百度地图离线加载
  • [QtQuick]实现离线地图

    千次阅读 热门讨论 2020-12-06 10:43:39
    [QtQuick]实现离线地图 Qt版本:5.12.8 1 需求分析 使用Qt实现离线地图,大多数软件是通过GraphicsView框架,结合瓦片地图相关算法来实现的。但这些绝大多数都不太讨喜。从项目时间、成本和质量的角度考虑,我们...

    [QtQuick]实现离线地图

    • Qt版本:5.12.8

    1 需求分析

    使用Qt实现离线地图,大多数软件是通过GraphicsView框架,结合瓦片地图相关算法来实现的。但这些绝大多数都不太讨喜。从项目时间、成本和质量的角度考虑,我们需要一个开发周期短、人力成本低、软件质量有保障的方案。

    自QtLocation 5.0开始,Qt推出了Map QML Type,这意味着我们可以使用Qt自带的地图,而不用自己再去实现非常底层的算法了。

    The Map type is used to display a map or image of the Earth, with the capability to also display interactive objects tied to the map’s surface.

    2 方案设计

    从Qt文档可以看出,Qt通过Map类型作为地图显示介质,通过六种地图插件提供数据驱动。地图插件见下表:

    插件名称描述
    Qt Location Esri PluginUses Esri for location services.
    Qt Location HERE PluginUses the relevant services provided by HERE.
    Qt Location Items Overlay PluginProvides an empty map intended to be used as background for an overlay layers for map items.
    Qt Location Mapbox GL PluginUses Mapbox GL for location services.
    Qt Location Mapbox PluginUses Mapbox for location services.
    Qt Location Open Street Map PluginUses Open Street Map and related services.

    最后一个Qt Location Open Street Map Plugin,这个插件默认就支持离线地图。先罗列OSM支持的几种地图加载模式:

    1. 网络地图

      通过TMS瓦片服务器获取瓦片地图。

      OSM默认提供TMS服务器配置地址,在本机搭建一个TMS瓦片服务器,就能实现加载本地瓦片地图。这个方案不够高效,放弃该方案

    2. 离线地图

      加载本机存储介质上的瓦片地图。

      按照固定格式命名瓦片地图文件,就可以实现加载本地瓦片地图。这个方案可行,但有优化的地方

    3. 缓存地图

      读取网络地图后,存放在本机的缓存瓦片地图。这属于Qt内部的缓存机制,暂时不考虑入手

    从实现离线的地图的目的来说,前两种方式都可行。但为了简单可靠,我们还是从它离线地图的功能开始研究。离线地图需要按照的固定命名格式,但我们下载的资源碰巧不符合;换个方向从源码入手,修改其读取文件名称的规则又有了新的解决方案。方案总结如下:

    • 按照官方的命名规则使用离线地图。
    • 修改官方源码,定义我们自己的瓦片命名规则。

    2.1 固定瓦片规则

    按照官方的规定,瓦片地图需要按照osm_100-<l|h>-<map_id>-<z>-<x>-<y>.<extension>的命名方式存放在同一个文件夹。

    市面上常见地图下载软件是按照z/x/y的形式保存的瓦片地图,所以下载完瓦片地图后,需要批量修改文件名称以适应OSM的要求,命名规则详见QtLocation: using offline map tiles with the OpenStreetMap plugin

    通过该方案,每一次下载新地图都需要重新命名。

    2.2 自定义瓦片规则

    修改OSM的源码,再固定瓦片命名规则的基础上,增加主流的文件命名规则。以Arcgis地图为例,在本地是以z/x/y.png(jpg)的方式存放,其中z代表层级,x代表x轴瓦片编号,y代表瓦片编号。找到源码里面关于读取离线地图的代码,然后修改其加载我们自定义规则的瓦片数据。设计其加载规则首先是官方规则,如果没有找到文件,那么在加载我们的自定义规则。我们定义瓦片文件层次结构如下:

    1. 第一层:瓦片根路径;
    2. 第二层:地图类型(street, satellite, cycle, transit, night-transit, terrain, hiking);
    3. 第三层:地图层级(z);
    4. 第四层:水平瓦片编号(x);
    5. 第五层:竖直瓦片编号(y)。

    例如:googlemap/satellite/10/258/346.png

    通过该方案,一劳永逸。

    3 实现

    3.1 批量命名

    通过Python、C++等都可以实现批量命名。具体实现略。

    3.2 源码定制

    我们目的是将官方的osm插件修改为mud(或其他名称)插件。修改源码分三步:1. 安装源码 2. 修改源码 3. 编译运行

    3.2.1 源码

    安装源码有三种办法:

    1. 安装Qt的时候,勾选上Sources(另外建议勾选MinGW,比MSVC能够调试更多源码);
    2. 下载完整源码包解压,或者单独下载 QtLocation源码包解压 (链接以Qt5.12.8为例);
    3. 从Github克隆 https://github.com/qt/qt5

    接下来为修改源码做准备:

    1. QtCreator添加子目录项目命名为MudMap(或其他名称),再添加Qt Quick Application - Empty项目命名为MudViewer(或其他名称,后面用于显示地图);

    2. 打开qtlocation\src\plugins\geoservices文件夹,拷贝osm文件夹到MudMap目录并重命名为MudPlugin(或其他名称),再重命名MudPlugin种的osm.proMudPlugin.pro,再重命名MudPlugin种的osm_plugin.promud_plugin.pro以作为后面修改源码的基础;

    3. 打开qtlocation文件夹,拷贝.qmake.conf文件到MudMap的同目录(可以略过该步以观察报错信息);

    4. 修改MudMap.pro文件内容为

      TEMPLATE = subdirs
      
      SUBDIRS += \
          MudPlugin \
          MudViewer
      

    准备好后的工程目录如下:

    MudMap

    MudPlugin

    MudPlugin.pro

    *.* h/cpp/json

    MudViewer

    MudViewer.pro

    *.* cpp/qrc/qml

    .qmake.conf

    MudMap.pro

    最后对MudMap工程执行qmake

    3.2.2 编码

    • 工程修改

      1. 修改mud_plugin.json第2-3行内容:

         "Keys": ["mud"],
         "Provider": "mud",
        
      2. 修改MudPlugin.pro第1行内容:

         TARGET = qtgeoservices_mud
        
      3. 修改MudPlugin.pro第41-42行内容

        OTHER_FILES += \
         mud_plugin.json
        
    • 源码修改

      1. 修改qgeoserviceproviderpluginosm.h第52-53行(这里修改后,就能够编译过了,如果编译不过,那么前面的步骤有误):

            Q_PLUGIN_METADATA(IID "org.qt-project.qt.geoservice.serviceproviderfactory/5.0"
                              FILE "mud_plugin.json")
        
      2. 修改qgeotiledmappingmanagerengineosm.cpp第72行:

            const QByteArray pluginName = "mud";
        
      3. 全局替换代码osm.mappingmud.mapping(共36处)

        值得注意的是,Qt内部实现会对输入给地图插件的参数进行过滤。以osm插件为例,如果传递给mud插件的参数包含一个"osm.mapping.offline.directory"参数,而正好Qt发现有一个叫做osm的插件,"osm."开头的参数就不会传递给mud插件。反之,如果把qtgeoservices_osm.dll文件删掉之后,mud就能收到“osm."开头的参数。

      4. qgeofiletilecacheosm.h/cpp添加函数:

        /*!
         * \return 返回自定义规则的文件绝对路径
         */
        QString QGeoFileTileCacheOsm::tileSpecToAbsFilename(const QGeoTileSpec &spec)
        {
            QString subDir;
            QString absFileName;
        
            // mapID地图类型,范围1-7 (文件夹)
            switch (spec.mapId()) {
            case 1:
                subDir += "/street"; break;
            case 2:
                subDir += "/satellite"; break;
            case 3:
                subDir += "/cycle"; break;
            case 4:
                subDir += "/transit"; break;
            case 5:
                subDir += "/night-transit"; break;
            case 6:
                subDir += "/terrain"; break;
            case 7:
                subDir += "/hiking"; break;
            default:
                break;
            }
        
            // 地图层级 (文件夹)
            subDir += "/";
            subDir += QString::number(spec.zoom());
        
            // 水平编号 (文件夹)
            subDir += "/";
            subDir += QString::number(spec.x());
        
            // 竖直编号 (文件)
            QString fileNameFilter = QString::number(spec.y()) + ".*";
        
            // 文件过滤,找到第一个可用的瓦片文件
            QDir fileDir = m_offlineDirectory.path() + subDir;
            QStringList validTiles = fileDir.entryList({fileNameFilter});
            if (validTiles.size()) {
                absFileName = fileDir.absoluteFilePath(validTiles.first());
            }
        
            return absFileName;
        }
        
      5. qgeofiletilecacheosm.h/cpp修改函数QGeoFileTileCacheOsm::getFromOfflineStorage的实现:

        QSharedPointer<QGeoTileTexture> QGeoFileTileCacheOsm::getFromOfflineStorage(const QGeoTileSpec &spec)
        {
            if (!m_offlineData)
                return QSharedPointer<QGeoTileTexture>();
        
            int providerId = spec.mapId() - 1;
            if (providerId < 0 || providerId >= m_providers.size())
                return QSharedPointer<QGeoTileTexture>();
        
            QString fileName;
            const QString fileNameFilter = tileSpecToFilename(spec, QStringLiteral("*"), providerId);
            QStringList validTiles = m_offlineDirectory.entryList({fileNameFilter});
        
            // 使用osm默认的命名规则
            if (validTiles.size()) {
                fileName = m_offlineDirectory.absoluteFilePath(validTiles.first());
            }
            // 如果osm的规则没有找到瓦片文件,那么就使用自定义规则
            else {
                fileName = tileSpecToAbsFilename(spec);
            }
        
            QFile file(fileName);
            if (!file.open(QIODevice::ReadOnly))
                return QSharedPointer<QGeoTileTexture>();
            QByteArray bytes = file.readAll();
            file.close();
        
            QImage image;
            if (!image.loadFromData(bytes)) {
                handleError(spec, QLatin1String("Problem with tile image"));
                return QSharedPointer<QGeoTileTexture>(0);
            }
        
            addToMemoryCache(spec, bytes, QString());
            return addToTextureCache(spec, image);
        }
        

    3.2.3 编译运行

    • 编译

      1. 执行qmake;
      2. 构建;
      3. 在构建路径下将plugins\geoservicesgeoservices文件夹拷贝到构建路径MudViewer\debug(或者MudViewer\release)下。
    • 运行

      1. 拷贝测试代码到main.qml执行qmake,注意修改地图中心和根路径:

        import QtQuick 2.12
        import QtQuick.Window 2.12
        import QtLocation 5.12
        import QtPositioning 5.11
        
        Window {
            id: win
            objectName: "window"
            visible: true
            width: 512
            height: 512
        
            Map {
                id: map
                anchors.fill: parent
                activeMapType: map.supportedMapTypes[1]  // 1代表卫星地图
                center: QtPositioning.coordinate(40.39, 99.79)  // 这里写地图显示中心
                opacity: 0.999	// 防止透明度引起的Bug(这是Qt的Bug)
        
                plugin: Plugin {
                    name: 'mud';
                    PluginParameter {
                        name: "mud.mapping.offline.directory"
                        value: 'D:/googlemaps'  // 这里写地图根路径
                    }
                }
            }
        }
        
      2. 运行效果

        脑补画面---
        
      3. 发布

        编译生成的geoservices文件夹就可以作为插件使用了,当其他项目使用时,需要geoservices文件夹和exe执行文件在用一个目录(windows平台)。

    4. 总结

    经过修改源码的osm,不仅保持了原有的功能,还有一点小升级。

    除了离线功能外,osm还提供了20多项的参数设置,"osm.mapping.offline.directory"只是其中一项,更多参数参见:Qt Location Open Street Map Plugin-Parameters。因此,mud插件同样支持这些参数设置,只需要将“osm."开头的参数全部以”mud."开头,就能让mud和osm有一样的功能了。

    源代码:

    https://github.com/Mud-Player/MudMap

    展开全文
  • QT百度离线地图(一)

    千次阅读 2018-11-23 17:35:25
    离线地图的实现方式基本就瓦片图了,找了很多瓦片图下载的工具,要么有水印要么就收费。。。 最后找到了太乐地图5.0.5的一个破解版可以用,具体怎么破解压缩包里边都有了,使用时先拔掉网线(不然会自动更新,如果...

    离线地图的实现方式基本就瓦片图了,找了很多瓦片图下载的工具,要么有水印要么就收费。。。
    最后找到了太乐地图5.0.5的一个破解版可以用,具体怎么破解压缩包里边都有了,使用时先拔掉网线(不然会自动更新,如果自动更新了就重新安装破解),然后打开软件,等到真正进入软件界面之后,再插入网线即可。
    下载瓦片图后储存为库,然后再导出瓦片图:
    在这里插入图片描述
    选择完成后离线浏览就能看到导出的离线瓦片图,具体的自己看看就好了,太乐地图这个软件会生成一个浏览的例子,实现了一些常用的功能。
    结合一些参考别人做的离线地图:
    http://www.cnblogs.com/Joanna-Yan/p/5822231.html
    https://www.cnblogs.com/wmcnblogs/p/5398724.html
    https://my.oschina.net/smzd/blog/548538?p=9
    https://www.cnblogs.com/jiqing9006/p/5002855.html
    http://api.map.baidu.com/lbsapi/creatmap/
    制作离线地图的步骤也就那几步,但是我的目标平台是一个linux的触屏设备,在触屏设备上试了百度API1.4,2.0的版本,都有一个问题,地图能够正常显示,但是地图无法拖动,但是在pc上是正常的,调试了好久都没搞定。
    之前做在线地图时,在这linux触屏设备上,百度API1.1以上的都无法拖动,但是将API降低为1.0时能够正常拖动,原因未知;但是高德地图时正常的,于是之前的在线地图换成了高德地图实现,但是高德地图的离线地图没多少资料参考。。。
    于是决定自己离线化百度地图API1.0去加载瓦片图。

    代码:https://github.com/yangyang0312/QtTestCode/tree/master/BaiduOfflineMap
    百度地图API1.0离线化(二):https://blog.csdn.net/yangyang031213/article/details/84401199
    百度地图API1.0离线化(三):https://blog.csdn.net/yangyang031213/article/details/84401251

    展开全文
  • 相信很多使用Qt做界面开发的相关的人员都会想在自己得交互界面中使用地图,虽然百度、高德地图得功能都非常完善,但是使用Qt调用起来却有些不方便,并且离线地图更是需要一系列瓦片才能实现。这时就可以用到Qt中得...
  • QT5 QWebEngineView实现离线百度地图APIV2_0,QWebChannel实现qt与js交互
  • 使用Qt5.9.2实现百度离线地图,可以用于离线地图的项目开发中。代码中给出了Qt给js发送数据和js给Qt发送数据的双向传递
  • [Qt]Graphics View实现简单离线地图

    千次阅读 热门讨论 2021-03-09 21:21:24
    [Qt]Graphics View实现简单离线地图 1. 瓦片地图概述 地图资源本身是图片资源,多张256×256分辨率的图片拼接起来,给用户显示的将是一个完整的地图效果。这些256×256的图片被称作瓦片地图。瓦片地图有着典型的...
  • qt实现的百度地图,瓦片地图。实现了街道图。卫星图。
  • 感谢小郭软件提供的离线地图下载工具,这个失效了,文章末尾会附上下载链接,使用方式参见链接 一、下载离线地图相关文件 确保文件夹baiduLX_JS-master\bmap-offline\下的tiles、tiles_hybird、tiles_satellite中是...
  • Qt5加载百度地图,这个是根据网上搜到的另个TestMap.rar文件修改而来,适用于Qt5版本,还修复了,编译无法通过的内容,添加了编译说明,如果有什么问题,欢迎在下方评论,随时沟通
  • 本文介绍如何加载地图包tpk和mmpk
  • 使用Qt5.9.2实现百度离线地图,可以用于离线地图的项目开发中。代码中给出了Qt给js发送数据和js给Qt发送数据的双向传递

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,010
精华内容 404
关键字:

QT离线地图