引言:技术使用qt的qml自带Map组件,没必要像网上那样用纯qt编写各种复杂的代码,直接部署一个自己的地图瓦片源,像调库一般,用几行代码就能简单的实现类似高德的离线地图效果,支持旋转、倾斜,缩放各种基本地图操作,本人的arm板为正点原子的stm32mp157,文件系统用的也是正点的出厂文件系统,同时十分推荐想学习mpu的朋友用正点的板子
1.准备瓦片地图
使用java编写的开源地图下载器下载瓦片地图,感谢大佬开源,链接如下
地图下载器: 使用Java开发的地图瓦片图下载工具,支持OpenStreetMap、天地图、谷歌地图、高德地图、腾讯地图、必应地图的XYZ瓦片图下载与合并。https://gitee.com/CrimsonHu/java_map_download#https://gitee.com/link?target=https%3A%2F%2Fpan.baidu.com%2Fs%2F1CA7sdH6zL4OjJxVydKwrWQ在软件中选择想要的图层和地图区域,地图区域也可以自己绘制图形选取
下载地图,注意选择/{z}/{x}/{y}.[image],因为qml的组件Map默认支持这种格式显示
得到地图瓦片后可以将其部署到arm板能访问到的nginx服务器或者apache服务器上(相关操作可自行搜索下nginx部署图片),以便qml的map组件可以通过此在线地址访问到地图瓦片,其有一个缓存机制,第一次访问到这些在线瓦片后可以保存这些瓦片到本地,第二次如果连接不到在线的地图源就会去加载本地的缓存地图,这样可以用来实现离线地图,还有一种方式就是在你的arm板上移植部署nginx服务器,直接访问本地的网址地图源也可以,正点的mp157默认帮忙移植好了nginx
如下就是我本地缓存的地图瓦片,也是从我的云服务器上获取到的地图瓦片自动加载到本地缓存了
2.编写qml代码
代码很简单,qt官方提供了一个基于qml的mapviewer的示例,大家可以看看如何实现的
qtlocation提供了相关显示和处理地图瓦片的组件Map,我们只需要修改下插件配置,qml的map默认是去在线的openstreetmap官方地图源获取瓦片,我们改为向我们自己的瓦片源获取瓦片即可,同时开启缓存,这样第一次加载完地图后,第二次就能实现离线地图的功能了,以下是我的代码
import QtQuick 2.0
import QtQuick.Window 2.0
import QtLocation 5.12
import QtPositioning 5.6Window {width: Screen.desktopAvailableWidthheight: Screen.desktopAvailableHeightvisible: true// 地图插件配置Plugin {id: mapPluginname: "osm"PluginParameter {name: "osm.mapping.custom.host"value: "http://你自己的地图瓦片源/"}PluginParameter {name: "osm.mapping.providersrepository.disabled"value: true}//设置地图瓦片的缓存目录PluginParameter {name: "osm.mapping.cache.directory"value: "/home/shanghai/tmp"}}// 地图组件Map {id: mapwidth: Screen.desktopAvailableWidthheight: Screen.desktopAvailableHeightactiveMapType: supportedMapTypes[6]plugin: mapPlugincenter: QtPositioning.coordinate(26.835462782119,110.36449842665)zoomLevel: 17 //在16-18之间// 用户交互时限制缩放级别onZoomLevelChanged: {map.zoomLevel = Math.max(16, Math.min(18, map.zoomLevel))}}
}
3.实现效果