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

2023-05-16

       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: mapPlugin
        name: "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,其他版本可根据上述方法自行编译!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 关于单应性矩阵的理解:Homography matrix for dummies

    尽量写的通俗一点 xff0c 因为从某种程度上讲 xff0c 本人也是dummy 1 先说homogeneous coordinate xff0c 齐次坐标 一幅2D图像上的非齐次坐标为 x y xff0c 而齐次坐标为 x y 1 xff
  • 关于RANSAC的理解

    先说最小二乘 ok xff0c 你手头有一堆数据 xff0c 比如这些蓝点 xff1a 那么我们假设它符合一个直线模型 xff1a y 61 ax 43 b xff0c 用最小二乘就可以很容易求解出未知参数a和b 最小二乘大法确实好哇 xf
  • Visual Studio中监视数组

    比如有一个double h 9 xff0c 如果选择监视 xff0c 那么就只会监视h 0 xff0c 如果想监视其他元素 xff0c 难道只能h 1 h 2 一个个的添加吗 xff1f 当然不需要 xff0c 在监视中输入h 9就可以了
  • 在编译PX4之前,你需要知道的几件事

    1 在git上clone代码 xff0c 必须是clone xff0c 因为编译时需要有 git文件夹 如果你看Makefile就会发现有这么一行 xff1a Enforce the presence of the GIT reposito
  • 马氏距离与卡方分布

    最近在看 Fundamentals of object tracking xff0c 看到最近邻滤波时 xff0c 碰到了题中的两个概念 以下内容基本来自wiki xff0c 读者有不懂的地方看wiki更清晰明了 1 马氏距离 Mahala
  • PX4中的mavlink

    简介 px4与地面站的通信协议是mavlink xff0c 对于其消息格式的介绍看这里和这里 需要注意几点 xff1a 不光是px4与qgroundcontrol通信通过mavlink xff0c 有一些sensor也支持mavlink m
  • STM32F1Debug,定时器时基初始化参数

    STM32F1 xff0c 定时器时基初始化参数 错误代码 xff1a 在初始化时基时 xff0c 没有给TIM ClockDivision和TIM RepetitionCounter赋值 错误代码 xff1a span class tok
  • dockerfile详解

    前言 各位想必应该记得 xff0c 我们此前如果安装一个nginx的话 xff0c 安装完以后 xff0c 我们说过很多次了 xff0c 通常不会运行在默认配置下 xff0c 那因此 xff0c 我们通常需要去改一改它的配置文件或者定义模块
  • docker hub + github action x持续集成CI/CD

    docker 43 github 持续集成CI CD docker 持续集成 参考官网 xff1a https docs docker com ci cd best practices 的大部分内容 2020 Jetbrains devel
  • 利用爬虫获取免费IP代理

    项目目标 通过爬虫获取 西拉代理 xff08 http www xiladaili com xff09 上的高匿代理 xff0c 并储存至一个列表 项目分析 首先对网页进行观察 xff0c 主体内容如下图所示 不但指明了代理IP 协议类型
  • DOCKER windows 7 详细安装教程

    Edit DOCKER windows安装 编者 xff1a xiaym 日期 xff1a 2015年1月20日 排版工具 xff1a 马克飞象 QQ 252536711 DOCKER windows安装 1 下载程序包2 设置环境变量3
  • 职场里不能与之结为团队的十种人

    俗话说 xff1a 女怕嫁错郎 xff0c 男怕入错行 同样 xff0c 一个人进入职场最怕的就是遇上了自己无法与其默契的某些团队成员 xff0c 这会影响到自己的事业进取 xff0c 影响到自己努力奋斗的成果收获 xff0c 影响到自己做
  • python读取大疆P1相机POS

    大疆P1相机读取POS xff0c 算法不是很好 xff0c 但是可以用 未来有好的算法再贡献 import os import os path import exifread workspace 61 r 39 G 20210727 39
  • Java数据结构之Lambda表达式

    目录 1 背景1 1 Lambda表达式的语法1 2 函数式接口 2 Lambda表达式的基本使用3 变量捕获3 1 匿名内部类的变量捕获3 2 Lambda的变量捕获 4 Lambda在集合当中的使用4 1 Collection接口4 2
  • docker学习笔记

    一 docker简介 xff1a 1 是什么 xff1a xff08 1 xff09 为什么会有docker出现 xff0c 将解决什么样的问题 xff1a 当我们在开发一个项目的时候 xff0c 假如您自己的电脑有您自己的开发环境 xff
  • iserver配置https加密通信

    1 升级iserver为https访问 xff1a iserver是部署在tomcat中 xff0c 所以只要配置tomcat的相关配置就可以 xff1a xff08 1 xff09 https访问需要用到证书 xff0c 因此需要准备相关
  • ZeroMQ发布订阅模式之多进程实现

    ZeroMQ的发布订阅模式是单向的数据发布 xff0c 服务器 xff08 即消息发布方 xff09 将更新的消息 事件推送到一组客户端 xff08 即订阅方 xff09 消息发布者创建ZMQ PUB类型的socket并将消息发送到消息队列
  • java面试清单和书籍推荐 五颗星五颗星

    前言 面试必备技能清单 xff0c 这里不会详细论述 xff0c 更多的是清单列举 xff0c 罗列一些关键字和链接注释 数据结构与算法 排序算法 选择排序冒泡排序插入排序快速排序快速排序 xff08 普通 xff0c 二路 xff0c 三
  • ssh Key exchange was not finished sshd

    报错 xff1a ssh Key exchange was not finished 则需修改sshd文件 链接 xff1a Key exchange was not finished connection is closed近期遇到这个错
  • C++类成员冒号初始化以及构造函数内赋值

    通常我们对类成员进行 初始化 有两种方式 xff1a 1 构造函数后面跟冒号 xff1b 2 构造函数里面对成员进行赋值 有些人不太注意这个小细节 xff0c 或者根本不知道他们的区别 xff0c 认为两种方式是一样的 这个误解有时可能会对

随机推荐