QML中的地图(以OSM为例)在使用过程中会发现当地图层数很多时,特别是如果使用离线地图且地图层级较多时地图会变得很卡(在线地图加载的层级数多且不清除缓存时也会卡),原因在于QML地图插件对地图瓦片的加载插件采用了从单一瓦片目录文件夹中筛选瓦片文件的方式。具体流程为:当程序需要展示地图时,插件根据当前Map的缩放比例和显示范围计算当前需要加载的瓦片名,然后插件在存放地图的目录中筛选同名的瓦片进行显示,每显示一个瓦片就需要对整个目录中文件筛选一次,而需要显示的地图层数高,相应的显示范围内要加载的瓦片数量也就多,不卡才怪了。

解决办法是对地图瓦片目录进行分层,按照存放路径作为索引,即每个地图层的瓦片存放入一个文件夹中,插件根据地图类型和缩放比例进行查找,这样能大大的提高效率。该示例中只是按照地图层数分文件夹,如果更追求效率可按照我的方法在每一个层内再经行细分。示例中的mapType为自定义的地图类型(Map在Plugin中设置加载地图类型https://blog.csdn.net/zjgo007/article/details/122715773),如不需要在插件中设置地图类型,删除示例中的mapType相关部分即可。地图瓦片层次图:

修改插件源码方法如下(以5.11.2为例):

1、使用QtCreator打开OSM地图插件工程源码位置:F:\Qt\5.11.2\Src\qtlocation\src\plugins\geoservices\osm

2、在"qgeofiletilecacheosm.h"添加变量bool m_offlineMapTileDir,在构造函数中添加参数mapTileDir并对m_offlineMapTileDir初始化,该变量标识是否根据目录作为索引查找瓦片,代码:

qgeofiletilecacheosm.h:

/*添加地图类型标识,只需要分目录时可删除相关部分*/
int m_offlineMapType;/*添加地图瓦片分目录查找*/
bool m_offlineMapTileDir;QGeoFileTileCacheOsm(const QVector<QGeoTileProviderOsm *> &providers,const QString &offlineDirectory = QString(),const QString &directory = QString(),const int &mapType = 0,const bool &mapTileDir = false,QObject *parent = 0);

qgeofiletilecacheosm.cpp 

//对m_offlineMapTileDir初始化QGeoFileTileCacheOsm::QGeoFileTileCacheOsm(const QVector<QGeoTileProviderOsm *> &providers,const QString &offlineDirectory,const QString &directory,const int &mapType,const bool &mapTileDir,QObject *parent)
:   QGeoFileTileCache(directory, parent), m_offlineDirectory(offlineDirectory), m_offlineData(false),m_offlineMapType(mapType),m_offlineMapTileDir(mapTileDir), m_providers(providers)

3、在"qgeotiledmappingmanagerengineosm.cpp"文件中添加自定义参数设置,可以搜索已有的参数属性例如:"osm.mapping.offline.directory"便于定位到文件中位置,其后添加自定义参数代码:

/*在插件中定义地图类型,只需要分目录时可删除相关部分*/int m_offlineMapType=0;if(parameters.contains(QStringLiteral("osm.mapping.offline.maptype")))m_offlineMapType = parameters.value(QStringLiteral("osm.mapping.offline.maptype")).toInt();/*在插件中定义地图是否启动分目录查找*/bool m_offlineMapTileDir=false;if(parameters.contains(QStringLiteral("osm.mapping.offline.maptiledir")))m_offlineMapTileDir = parameters.value(QStringLiteral("osm.mapping.offline.maptiledir")).toBool();QGeoFileTileCacheOsm *tileCache = new QGeoFileTileCacheOsm(m_providers, m_offlineDirectory, m_cacheDirectory,m_offlineMapType,m_offlineMapTileDir);/*此为原地图瓦片初始化构造函数*/
//    QGeoFileTileCacheOsm *tileCache = new QGeoFileTileCacheOsm(m_providers, m_offlineDirectory, m_cacheDirectory,m_offlineMapType);

4、在"qgeofiletilecacheosm.cpp"中跳转到函数QSharedPointer<QGeoTileTexture> getFromOfflineStorage(const QGeoTileSpec &spec);

该函数为筛选瓦片图片并加载到UI中,函数修改代码:

/*原生成瓦片名和查找瓦片位置代码*/
//    const QString fileName = tileSpecToFilename(spec, QStringLiteral("*"), providerId);
//    QStringList validTiles m_offlineDirectory.entryList({fileName});/*修改后的代码,当在插件中设置了地图瓦片根据分目录查找,如果没有设置则按照原地图整个目录进行查找*/const QString fileName = tileSpecToFilename(spec, QStringLiteral("*"), providerId);QStringList validTiles;QDir c_offlineMapTileDir = m_offlineDirectory;if(m_offlineMapTileDir){QStringList pathList = fileName.split("-");QString mapType = pathList.at(2);QString zoom = pathList.at(3);if(!c_offlineMapTileDir.cd(mapType))//如果没有该地图类型则返回,不继续筛选return QSharedPointer<QGeoTileTexture>();if(!c_offlineMapTileDir.cd(zoom))//如果没有该地图比例瓦片目录则返回,不继续筛选return QSharedPointer<QGeoTileTexture>();validTiles = c_offlineMapTileDir.entryList({fileName});}else{validTiles = c_offlineMapTileDir.entryList({fileName});}
//以上是新增if (!validTiles.size())return QSharedPointer<QGeoTileTexture>();QFile file(c_offlineMapTileDir.absoluteFilePath(validTiles.first()));//此处m_offlineDirectory改为c_offlineMapTileDir

 5、重新编译该osm工程,编译好的插件位于Qt安装盘符根目录下的plugins\geoservices路径下,将生成的插件文件复制到Qt安装目录中的插件目录(F:\Qt\5.11.2\msvc2015\plugins\geoservices\)替换原插件即可。

6、在QML的插件Plugin中传递自定义参数"osm.mapping.offline.maptiledir",其中该参数的值为布尔型,当需要目录做索引时传入true,如果不设置该参数或者传入false,QML地图采用默认地图瓦片查询方法,代码:

 Plugin {id: mapPluginname: "osm" // "mapboxgl", "esri", ...PluginParameter{name:"osm.mapping.offline.directory"value:Analyze.getAppPath()+"/Map"}PluginParameter{name:"osm.mapping.offline.maptype"value:5}PluginParameter{name:"osm.mapping.offline.maptiledir"value:true}}

7、实测通过该修改插件的方法后,QML地图非常顺滑,该示例使用Qt版本为5.11.2,其他版本可根据上述方法自行编译!

QML 地图修改插件源码(四),Map根据目录作为索引加载地图瓦片相关推荐

  1. QML 地图修改插件源码(三),Map在Plugin中设置加载地图类型

    常用的地图种类分为交通图,地形图,卫星图等等,在QML的Map(以OSM地图为例)中提供activeMapType属性用于读取当前显示的地图类型(注意:该属性为只读属性,不能用于赋值),QML中地图的 ...

  2. QML 地图修改插件源码(一)解决Map使用Open Street Map(OSM)无法加载在线地图的解决办法

    最近在使用Qml地图中发现,osm地图在线加载地图失败,通过查看osm插件源代码,找到了osm瓦片地图的源地址为:http://c.tile.openstreetmap.org/%z/%x/%y.pn ...

  3. 基于webpack修改插件源码,使用自定义文件替换node_modules里面的源码文件

    基于webpack修改插件源码,使用自定义文件替换node_modules里面的源码文件 需求:插件不满足要求,需要修改源码,但又想永远保留自己修改的这份,不想被重新下载的覆盖 方法:在运行时执行你替 ...

  4. Cesium源码解析一(terrain文件的加载、解析与渲染全过程梳理)

    快速导航(持续更新中-) Cesium源码解析一(terrain文件的加载.解析与渲染全过程梳理) Cesium源码解析二(metadataAvailability的含义) Cesium源码解析三(m ...

  5. 【GStreamer源码分析】playbin播放test.wav加载插件过程分析

    playbin播放test.wav加载插件过程分析 一.前言 二.playbin 播放 .wav 音频插件加载一览 三.测试代码 3.1 gst_init 3.2 gst_element_set_st ...

  6. wemall app商城源码中基于JAVA的Android异步加载图片管理器代码

    wemall doraemon是Android客户端程序,服务端采用wemall微信商城,不对原商城做任何修改,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可随意定制修改.本文分享其中 ...

  7. Spring Ioc 源码分析(一)--Spring Ioc容器的加载

    1.目标:熟练使用spring,并分析其源码,了解其中的思想.这篇主要介绍spring ioc 容器的加载 2.前提条件:会使用debug 3.源码分析方法:Intellj idea debug 模式 ...

  8. php源码自动识别文本中的链接,自动加载识别文件Auto.php

    用于本应用的控制器自动加载类设置,用法如同\CodeIgniter\Config\AutoloadConfig 自动加载识别文件:dayrui/App/应用目录/Config/Auto.php 语法格 ...

  9. HTML卡片式布局源码,html5自适应卡片式设计动态加载整站源码_

    html5自适应卡片式设计动态加载整站源码 该模板是非常容易存活的,这样的程序很容易吸引访客点击,提升ip流量和pv是非常有利的,随意挂点联盟广告都能养活程序. 本套整站源码采使用现在非常流行的全屏自 ...

最新文章

  1. sqlite3自增key设定(创建自增字段)
  2. linux panic 构造_Linux Wireless架构总结
  3. .NET Core使用NLog通过Kafka实现日志收集
  4. mysql必须的组件_mysql innodb的重要组件
  5. 请列举出html中两个单标签,HTML基础有哪些单标签
  6. Oracle收购Talari,第一家SD-WAN公有云提供商出现
  7. unable to bind to locking port 7054 within 45000 ms
  8. Java中 LocalDate、LocalTime、LocalDateTime三个时间工具类的使用介绍
  9. JavaScript的语句可以不用分号结尾么?
  10. local variable referenced before assignment 原因及解决办法
  11. 微信小程序开发:腾讯地图集成步骤(旧题新说)
  12. 荣耀play5t活力版和荣耀畅玩20哪个好 哪个更值得入手
  13. UGUI ContentSizeFitter 嵌套 适配
  14. java发送会议邀请邮件模板_使用java发送每封电子邮件的日历邀请
  15. 三菱服务器显示d1d2,三菱PLC指令SMOV D2 K2 K2 D1 K3详解
  16. 00 Mybatis之简介与入门
  17. Java人力外包是什么意思?有什么优点
  18. 安装配置群晖 DS918+ NAS及常用技巧
  19. Java读取MARC元数据 代码
  20. 百度清风算法2.0——严厉打击欺骗下载 !

热门文章

  1. Web应用的SSL优化处理 ,ssL加速器
  2. 美国公司里的同事关系
  3. 2021-10-24全球10米土地覆盖数据任意下载
  4. 区块链新一代共识算法:VRF分布式可验证随机函数
  5. yii框架路由解析(一)
  6. jsch连接mysql_使用jsch连接数据库
  7. OpenI入门-自己动手new一个Project
  8. 【云原生 • Kubernetes】一文掌握 k8s 包管理工具 Helm
  9. java 端口扫描_java端口扫描(原创)
  10. C语言学习系列-->【函数的递归】