前言
本章节讲如何制作自己的地图插件,我们以制作天地图插件为例,做一个简单的天地图插件,当然也可以做google,bing,高德,百度等,思路都一样
另外说明一点,截止今日(2021-07-25)Qt6.2版本,Qt 6 暂时不支持QtLocation 模块,原因好像是因为Qtlocation 是基于opengl做的,具体可在官方找资料…Qt官方可能会在后期加上Qtlocation 模块,有使用Qtlocation的同学可以关注一下这块的更新…目前在Qt5是完全可以正常使用的…
一、分析Qt location 源码中 esri模块源码
看geoserviceproviderfactory_esri.h
文件,QtLocation 入口为此文件
QT_BEGIN_NAMESPACE
class GeoServiceProviderFactoryEsri: public QObject, public QGeoServiceProviderFactory
{
Q_OBJECT
Q_INTERFACES(QGeoServiceProviderFactory)
Q_PLUGIN_METADATA(IID "org.qt-project.qt.geoservice.serviceproviderfactory/5.0"
FILE "esri_plugin.json")
public:
QGeoCodingManagerEngine *createGeocodingManagerEngine(const QVariantMap ¶meters,
QGeoServiceProvider::Error *error,
QString *errorString) const override;
QGeoMappingManagerEngine *createMappingManagerEngine(const QVariantMap ¶meters,
QGeoServiceProvider::Error *error,
QString *errorString) const override;
QGeoRoutingManagerEngine *createRoutingManagerEngine(const QVariantMap ¶meters,
QGeoServiceProvider::Error *error,
QString *errorString) const override;
QPlaceManagerEngine *createPlaceManagerEngine(const QVariantMap ¶meters,
QGeoServiceProvider::Error *error,
QString *errorString) const override;
};
QT_END_NAMESPACE
#endif // GEOSERVICEPROVIDERFACTORYESRI_H
#include "geoserviceproviderfactory_esri.h"
#include "geotiledmappingmanagerengine_esri.h"
#include "geocodingmanagerengine_esri.h"
#include "georoutingmanagerengine_esri.h"
#include "placemanagerengine_esri.h"
#include <QtLocation/private/qgeotiledmappingmanagerengine_p.h>
QT_BEGIN_NAMESPACE
QGeoCodingManagerEngine *GeoServiceProviderFactoryEsri::createGeocodingManagerEngine(
const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const
{
return new GeoCodingManagerEngineEsri(parameters, error, errorString);
}
QGeoMappingManagerEngine *GeoServiceProviderFactoryEsri::createMappingManagerEngine(
const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const
{
return new GeoTiledMappingManagerEngineEsri(parameters, error, errorString);
}
QGeoRoutingManagerEngine *GeoServiceProviderFactoryEsri::createRoutingManagerEngine(
const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const
{
const QString token = parameters.value(QStringLiteral("esri.token")).toString();
if (!token.isEmpty()) {
return new GeoRoutingManagerEngineEsri(parameters, error, errorString);
} else {
*error = QGeoServiceProvider::MissingRequiredParameterError;
*errorString = tr("Esri plugin requires a 'esri.token' parameter.\n"
"Please visit https://developers.arcgis.com/authentication/accessing-arcgis-online-services/");
return 0;
}
}
QPlaceManagerEngine *GeoServiceProviderFactoryEsri::createPlaceManagerEngine(
const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const
{
return new PlaceManagerEngineEsri(parameters, error, errorString);
}
QT_END_NAMESPACE
此类是重写 QGeoServiceProviderFactory 工厂类,以实现地图创建,地理信息编码,路由等4个功能,我这里只关注地图创建createMappingManagerEngine
,如有需要其它的,可依源码自己行创建
二、创建自己的插件,显示天地图
这里不再贴代码了,源码中关键位置有注释,说下调用关系
TiQeoServiceProviderFactory —> TiQGeoTiledMappingManagerEngine ->> TiGeoTileFetcher
------------------------------------------------------------------------------------------------->>TiQGeoFileTileCache
- TiQeoServiceProviderFactory :为插件类,入口
- TiQGeoTiledMappingManagerEngine :地图tile 瓦片的管理类
- TiGeoTileFetcher : 从网络获取tile的类
- TiQGeoFileTileCache: 缓冲到本地文件的类,官方默认的是 QGeoFileTileCache,此会tile以png的形式写入到本地磁盘,默认在C盘目录,我重载重写里面的 insert() 和 get() 函数,写入到数据库
另外有个类TiMapEngine 为单例类,里面有各地图服务的url获取方式,getUrlEngine()及数据库线程getSqlThread()
其中TiMapUrlEngine 类可添加新地图服务,用于支持其它地图,注意现在天地图里面的key是我自己申请的key,每天只有1W张图,自己拿到工作请到天地图官方申请帐号,更换key 位置: titianditumapprovider.cpp
- 支持天地图影像图和影像标注信息,且二者是可以叠加的,叠加方式参见:https://doc.qt.io/qt-5/location-plugin-itemsoverlay.html
- 支持sql数据库存储
- 只实现了地图的显示,未做地图的搜索,路径等功能
- Qt5.15.0版本上运行,理论上5.12版本后都可以运行,印象中从5.11后,Qtlocation里就没功能变动?Qt 6目前不支持,主要是官方说Qt6不支持Qtlocation,看后续6.3版本后会不会添加进来
如果要实现更多功能,参考本系列文章的第一章节里的参考项目
github链接:
https://github.com/tianxiaofan/QtLocationTianditu
总结
遇到问题需要多查官方文档和官方案例,当然github也不错,哈哈