这里只实现一个地图映射引擎
1.编译插件
pro文件:

TARGET = GD
QT += location-private positioning-private networkPLUGIN_TYPE = geoservices
PLUGIN_CLASS_NAME = GDProviderFactory
load(qt_plugin)HEADERS += \gdproviderfactory.h \gdqgeotiledmap.h \gdqgeotiledmappingmanagerengine.h \gdqgeotiledmapreply.h \gdqgeotilefetcher.hSOURCES += \gdproviderfactory.cpp \gdqgeotiledmap.cpp \gdqgeotiledmappingmanagerengine.cpp \gdqgeotiledmapreply.cpp \gdqgeotilefetcher.cppDISTFILES += \README.md \gd_plugin.json

插件类(也是qml调用的入口):

#ifndef GDPROVIDERFACTORY_H
#define GDPROVIDERFACTORY_H#include <QObject>
#include <QtCore/QObject>
#include <QtLocation/QGeoServiceProviderFactory>class GDProviderFactory : public QObject,public QGeoServiceProviderFactory
{Q_OBJECTQ_INTERFACES(QGeoServiceProviderFactory)Q_PLUGIN_METADATA(IID "org.qt-project.qt.geoservice.serviceproviderfactory/5.0"FILE "gd_plugin.json")
public://只实现一个插件QGeoMappingManagerEngine *createMappingManagerEngine(const QVariantMap &parameters,QGeoServiceProvider::Error *error,QString *errorString) const;
signals:};#endif // GDPROVIDERFACTORY_H
#include "gdproviderfactory.h"
#include "gdqgeotiledmappingmanagerengine.h"
QGeoMappingManagerEngine *GDProviderFactory::createMappingManagerEngine(const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString) const
{return new GDQGeoTiledMappingManagerEngine(parameters, error, errorString);}

地图瓦片管理类、设置地图一些属性

#ifndef GDQGEOTILEDMAPPINGMANAGERENGINE_H
#define GDQGEOTILEDMAPPINGMANAGERENGINE_H#include <QtLocation/QGeoServiceProvider>
#include <QtLocation/private/qgeotiledmappingmanagerengine_p.h>class GDQGeoTiledMappingManagerEngine : public QGeoTiledMappingManagerEngine
{Q_OBJECTpublic:GDQGeoTiledMappingManagerEngine(const QVariantMap &parameters,QGeoServiceProvider::Error *error,QString *errorString);QGeoMap *createMap() override;private:QString m_cacheDirectory;};#endif // GDQGEOTILEDMAPPINGMANAGERENGINE_H
#include "gdqgeotiledmappingmanagerengine.h"
#include "gdqgeotilefetcher.h"
#include "QtLocation/private/qgeotilespec_p.h"
#include "QtLocation/private/qgeofiletilecache_p.h"
#include "QtLocation/private/qgeocameracapabilities_p.h"
#include "gdqgeotiledmap.h"GDQGeoTiledMappingManagerEngine::GDQGeoTiledMappingManagerEngine(const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString):QGeoTiledMappingManagerEngine()
{Q_UNUSED(error);Q_UNUSED(errorString);//地图视角相关设置,对应到 QML Map 类型的属性QGeoCameraCapabilities capabilities;capabilities.setMinimumZoomLevel(1.96);capabilities.setMaximumZoomLevel(20.88);capabilities.setSupportsBearing(true);capabilities.setSupportsTilting(true);capabilities.setMinimumTilt(0);capabilities.setMaximumTilt(80);capabilities.setMinimumFieldOfView(20.0);capabilities.setMaximumFieldOfView(120.0);capabilities.setOverzoomEnabled(true);setCameraCapabilities(capabilities);//瓦片大小int tile = parameters.value(QStringLiteral("amap.amap.tilesize"), 256).toInt();setTileSize(QSize(tile, tile));//支持地图样式QList<QGeoMapType> types;//QGeoCameraCapabilities cameraCapabilities;types << QGeoMapType(QGeoMapType::StreetMap, tr("Road Map"), tr("Normal map view in daylight mode"), false,false, 1, "amap", capabilities);types << QGeoMapType(QGeoMapType::TerrainMap, tr("Terrain"), tr("Terrain map view in daylight mode"), false, false, 2, "amap", capabilities);types << QGeoMapType(QGeoMapType::SatelliteMapDay, tr("Satellite"), tr("Satellite map view in daylight mode"), false, false, 3, "amap", capabilities);types << QGeoMapType(QGeoMapType::HybridMap, tr("Hybrid"), tr("Satellite map view with streets in daylight mode"), false, false, 4, "amap", capabilities);setSupportedMapTypes(types);//瓦片获取,默认接口是通过网络请求获取GDQGeoTileFetcher *fetcher = new GDQGeoTileFetcher(parameters, this, tileSize());setTileFetcher(fetcher);if (parameters.contains(QStringLiteral("amap.cachefolder")))m_cacheDirectory = parameters.value(QStringLiteral("amap.cachefolder")).toString().toLatin1();elsem_cacheDirectory = QAbstractGeoTileCache::baseCacheDirectory() + QLatin1String("amap");QAbstractGeoTileCache *tileCache = new QGeoFileTileCache(m_cacheDirectory);tileCache->setMaxDiskUsage(100 * 1024 * 1024);setTileCache(tileCache);*error = QGeoServiceProvider::NoError;errorString->clear();
}QGeoMap *GDQGeoTiledMappingManagerEngine::createMap()
{return new GDQGeoTiledMap(this);
}

瓦片获取类:

#ifndef GDQGEOTILEFETCHER_H
#define GDQGEOTILEFETCHER_H#include <QtLocation/private/qgeotilefetcher_p.h>
#include "gdqgeotiledmappingmanagerengine.h"
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QMutex>class GDQGeoTileFetcher : public QGeoTileFetcher
{Q_OBJECT
public:GDQGeoTileFetcher(const QVariantMap &parameters, GDQGeoTiledMappingManagerEngine *engine, const QSize &tileSize);QGeoTiledMapReply *getTileImage(const QGeoTileSpec &spec);private:QString _getURL(int type, int x, int y, int zoom);void _getSecAmapWords(int x, int y, QString &sec1, QString &sec2);void _getSessionToken();void _tryCorrectAmapVersions(QNetworkAccessManager *networkManager);private slots:void _networkReplyError(QNetworkReply::NetworkError error);void _replyDestroyed();void _amapVersionCompleted();private:QString m_apiKey;QString m_signature;QString m_client;QString m_baseUri;bool            _amapVersionRetrieved;QNetworkReply*  _amapReply;QMutex          _amapVersionMutex;QByteArray      _userAgent;QString         _language;// Amap version stringsQString         _versionAmapMap;QString         _versionAmapSatellite;QString         _versionAmapLabels;QString         _versionAmapTerrain;QString         _secAmapWord;QNetworkRequest netRequest;QNetworkAccessManager *m_networkManager;};#endif // GDQGEOTILEFETCHER_H
#include "gdqgeotilefetcher.h"
#include "gdqgeotiledmapreply.h"
#include <QNetworkProxy>
#include <QDebug>
#include <QSize>
#include <QDir>
#include <QUrl>
#include <QUrlQuery>
#include <QTime>
#include <QtCore/QJsonDocument>
#include <math.h>
#include <map>
#include <QJsonObject>GDQGeoTileFetcher::GDQGeoTileFetcher(const QVariantMap &parameters, GDQGeoTiledMappingManagerEngine *engine, const QSize &tileSize):QGeoTileFetcher(engine)
{if(parameters.contains(QStringLiteral("amap.maps.apikey")))m_apiKey = parameters.value(QStringLiteral("amap.maps.apikey")).toString();elsem_apiKey = parameters.value(QStringLiteral("amap.apikey")).toString();m_signature = parameters.value(QStringLiteral("amap.maps.signature")).toString();m_client = parameters.value(QStringLiteral("amap.maps.client")).toString();m_baseUri = QStringLiteral("http://maps.amap.com/maps/api/staticmap");if (parameters.contains(QStringLiteral("amap.useragent")))_userAgent = parameters.value(QStringLiteral("amap.useragent")).toString().toLatin1();else_userAgent = "";QStringList langs = QLocale::system().uiLanguages();if (langs.length() > 0) {_language = langs[0];}// Amap version strings_versionAmapMap            = "m@338000000";_versionAmapSatellite      = "198";_versionAmapLabels         = "h@336";_versionAmapTerrain        = "t@132,r@338000000";_secAmapWord               = "Galileo";//    _tryCorrectAmapVersions(m_networkManager);//    netRequest.setRawHeader("Referrer", "https://www.amap.com/maps/preview");//    netRequest.setRawHeader("Accept", "*/*");//    netRequest.setRawHeader("User-Agent", _userAgent);/*  2017: support new Amap Maps Tile API (yet under development)You have to be whitelisted to use the Tile API. I can't tell how to get whitelisted.see https://developers.amap.com/maps/documentation/tile/To use the new feature getUrl() and parsing the response has to be adapted. Maybe more than that...*///    _getSessionToken();
}QGeoTiledMapReply *GDQGeoTileFetcher::getTileImage(const QGeoTileSpec &spec)
{QString surl = _getURL(spec.mapId(), spec.x(), spec.y(), spec.zoom());// qDebug()<<"_getURL:" << surl;QUrl url(surl);netRequest.setUrl(url);QNetworkReply *netReply = m_networkManager->get(netRequest);QGeoTiledMapReply *mapReply = new GDQGeoTiledMapReply(netReply, spec);return mapReply;
}QString GDQGeoTileFetcher::_getURL(int type, int x, int y, int zoom)
{// qDebug() << "Type:" << type;switch (type) {case 0:case 1: //Road Map{QString sec1    = ""; // after &x=...QString sec2    = ""; // after &zoom=..._getSecAmapWords(x, y, sec1, sec2);return QString("http://wprd03.is.autonavi.com/appmaptile?style=7&x=%1&y=%2&z=%3").arg(x).arg(y).arg(zoom);}break;case 2: //Satallite Map{QString sec1    = ""; // after &x=...QString sec2    = ""; // after &zoom=..._getSecAmapWords(x, y, sec1, sec2);return QString("http://wprd03.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x=%1&y=%2&z=%3").arg(x).arg(y).arg(zoom);}break;case 3: //Terrain Map{QString sec1    = ""; // after &x=...QString sec2    = ""; // after &zoom=..._getSecAmapWords(x, y, sec1, sec2);return QString("http://wprd03.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=6&x=%1&y=%2&z=%3").arg(x).arg(y).arg(zoom);}break;case 4: //Hybrid Map{QString sec1    = ""; // after &x=...QString sec2    = ""; // after &zoom=..._getSecAmapWords(x, y, sec1, sec2);return QString("http://wprd03.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=8&x=%1&y=%2&z=%3").arg(x).arg(y).arg(zoom);}break;}return "";
}void GDQGeoTileFetcher::_getSecAmapWords(int x, int y, QString &sec1, QString &sec2)
{sec1 = ""; // after &x=...sec2 = ""; // after &zoom=...int seclen = ((x * 3) + y) % 8;sec2 = _secAmapWord.left(seclen);if (y >= 10000 && y < 100000) {sec1 = "&s=";}
}void GDQGeoTileFetcher::_getSessionToken()
{QUrl sessionUrl("https://www.amap.com/tile/v1/createSession");QUrlQuery queryItems;queryItems.addQueryItem("key", m_apiKey);queryItems.addQueryItem("mapType", "roadmap");queryItems.addQueryItem("language", _language);queryItems.addQueryItem("region", "de");sessionUrl.setQuery(queryItems);netRequest.setUrl(sessionUrl);QNetworkReply *sessionReply = m_networkManager->get(netRequest);if (sessionReply->error() != QNetworkReply::NoError)return;QJsonDocument document = QJsonDocument::fromJson(sessionReply->readAll());if (!document.isObject())return;QJsonObject object = document.object();QJsonValue status = object.value(QStringLiteral("session"));printf(status.toString().toLatin1().data());
}void GDQGeoTileFetcher::_tryCorrectAmapVersions(QNetworkAccessManager *networkManager)
{QMutexLocker locker(&_amapVersionMutex);if (_amapVersionRetrieved) {return;}_amapVersionRetrieved = true;if(networkManager){QNetworkRequest qheader;QNetworkProxy proxy = networkManager->proxy();QNetworkProxy tProxy;tProxy.setType(QNetworkProxy::DefaultProxy);networkManager->setProxy(tProxy);QSslConfiguration conf = qheader.sslConfiguration();conf.setPeerVerifyMode(QSslSocket::VerifyNone);qheader.setSslConfiguration(conf);QString url = "http://maps.amap.com/maps/api/js?v=3.2&sensor=false";qheader.setUrl(QUrl(url));qheader.setRawHeader("User-Agent", _userAgent);_amapReply = networkManager->get(qheader);connect(_amapReply, &QNetworkReply::finished, this, &GDQGeoTileFetcher::_amapVersionCompleted);connect(_amapReply, &QNetworkReply::destroyed, this, &GDQGeoTileFetcher::_replyDestroyed);connect(_amapReply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),this, &GDQGeoTileFetcher::_networkReplyError);networkManager->setProxy(proxy);}
}void GDQGeoTileFetcher::_networkReplyError(QNetworkReply::NetworkError error)
{qWarning() << "Could not connect to amap maps. Error:" << error;if(_amapReply){_amapReply->deleteLater();_amapReply = NULL;}
}void GDQGeoTileFetcher::_replyDestroyed()
{_amapReply = NULL;
}void GDQGeoTileFetcher::_amapVersionCompleted()
{if (!_amapReply || (_amapReply->error() != QNetworkReply::NoError)) {qDebug() << "Error collecting Amap maps version info";return;}QString html = QString(_amapReply->readAll());QRegExp reg("\"*https?://mt\\D?\\d..*/vt\\?lyrs=m@(\\d*)", Qt::CaseInsensitive);if (reg.indexIn(html) != -1) {QStringList gc = reg.capturedTexts();_versionAmapMap = QString("m@%1").arg(gc[1]);}reg = QRegExp("\"*https?://khm\\D?\\d.amap.com/kh\\?v=(\\d*)", Qt::CaseInsensitive);if (reg.indexIn(html) != -1) {QStringList gc = reg.capturedTexts();_versionAmapSatellite = gc[1];}reg = QRegExp("\"*https?://mt\\D?\\d..*/vt\\?lyrs=t@(\\d*),r@(\\d*)", Qt::CaseInsensitive);if (reg.indexIn(html) != -1) {QStringList gc = reg.capturedTexts();_versionAmapTerrain = QString("t@%1,r@%2").arg(gc[1]).arg(gc[2]);}_amapReply->deleteLater();_amapReply = NULL;
}

瓦片请求网络

#ifndef GDQGEOTILEDMAPREPLY_H
#define GDQGEOTILEDMAPREPLY_H#include <QtNetwork/QNetworkReply>
#include <QtLocation/private/qgeotilespec_p.h>
#include <QtLocation/private/qgeotiledmapreply_p.h>
#include <QtCore/QPointer>class GDQGeoTiledMapReply : public QGeoTiledMapReply
{Q_OBJECT
public:GDQGeoTiledMapReply(QNetworkReply *reply, const QGeoTileSpec &spec, QObject *parent = 0);void abort();QNetworkReply *networkReply() const;private Q_SLOTS:void networkFinished();void networkError(QNetworkReply::NetworkError error);private:QPointer<QNetworkReply> m_reply;
};#endif // GDQGEOTILEDMAPREPLY_H
#include "gdqgeotiledmapreply.h"GDQGeoTiledMapReply::GDQGeoTiledMapReply(QNetworkReply *reply, const QGeoTileSpec &spec, QObject *parent):QGeoTiledMapReply(spec,parent),m_reply(reply)
{connect(m_reply,SIGNAL(finished()),this,SLOT(networkFinished()));connect(m_reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(networkError(QNetworkReply::NetworkError)));
}void GDQGeoTiledMapReply::abort()
{if (!m_reply)return;m_reply->abort();
}QNetworkReply *GDQGeoTiledMapReply::networkReply() const
{return m_reply;}void GDQGeoTiledMapReply::networkFinished()
{if (!m_reply)return;if (m_reply->error() != QNetworkReply::NoError)return;setMapImageData(m_reply->readAll());const int _mid = tileSpec().mapId();if (_mid == 2)setMapImageFormat("jpeg");elsesetMapImageFormat("png");setFinished(true);m_reply->deleteLater();m_reply = 0;
}void GDQGeoTiledMapReply::networkError(QNetworkReply::NetworkError error)
{Q_UNUSED(error);if (!m_reply)return;setFinished(true);setCached(false);m_reply->deleteLater();m_reply = 0;
}

创造地图:

#ifndef GDQGEOTILEDMAP_H
#define GDQGEOTILEDMAP_H#include "QtLocation/private/qgeotiledmap_p.h"
#include <QtGui/QImage>
#include <QtCore/QPointer>
#include "gdqgeotiledmappingmanagerengine.h"class GDQGeoTiledMap : public QGeoTiledMap
{public:explicit GDQGeoTiledMap(GDQGeoTiledMappingManagerEngine *engine,QObject *parent = nullptr);//QString getViewCopyright();// void evaluateCopyrights(const QSet<QGeoTileSpec> &visibleTiles);private:QImage m_copyrightsSlab;QString m_lastCopyrightsString;QPointer<GDQGeoTiledMappingManagerEngine> m_engine;
};#endif // GDQGEOTILEDMAP_H
#include "gdqgeotiledmap.h"GDQGeoTiledMap::GDQGeoTiledMap(GDQGeoTiledMappingManagerEngine *engine, QObject *parent):QGeoTiledMap(engine, parent),m_engine(engine)
{}

二、qml调用插件
将生成的插件动态库放到C:\Qt5.15.2\5.15.2\msvc2019_64\plugins\geoservices目录下,qml直接调用。

import QtQuick 2.12
import QtQuick.Window 2.12
import QtPositioning 5.12
import QtLocation 5.12Window {visible: truewidth: 640height: 480title: qsTr("Hello World")Map{anchors.fill:parentplugin: Plugin{name: "amap"}}
}

插件json文件:

{"Keys": ["amap"],"Provider": "amap","Version": 200,"Experimental": false,"Features": ["OnlineGeocodingFeature","ReverseGeocodingFeature","OnlineRoutingFeature","AlternativeRoutesFeature","OnlineMappingFeature","SearchSuggestionsFeature"]
}

qml实现高德地图(2)相关推荐

  1. qt qml 高德地图--WebAPI 获取静态地图

    高德地图提供了很多Web API,本文展示如何使用Qt + qml 获取静态地图 静态地图Web API https://lbs.amap.com/api/webservice/guide/api/s ...

  2. qt quick-qml高德地图实现V1版本(跨平台支持、无需浏览器内核,运行迅速,下个版本实现位置搜索)

    1.效果图展示  gif如下所示(文件有点大,已压缩) 2.demo介绍 支持跨平台linux/windows等,qt插件方式,非浏览器加载 支持缓存保存离线地图实现 支持地图转向.旋转.方位调整等 ...

  3. js如何同时打开多个信息窗口 高德地图_高德地图-展示多个信息窗口

    1.问题背景 高德地图,设置小图标,并点击图标显示信息 2.实现源码 高德地图展示多个信息窗口 //初始化地图对象,加载地图 var map = new AMap.Map("containe ...

  4. 高德地图markevents_GitHub - mingxuWang/Map: 高德地图API二次封装

    Map组件设计文档 组件设计目的 分析当前各业务方向(销售端.商城.数据可视化.TMS)内地图相关应用的地图功能使用情况,封装Map组件供给各业务向进行使用. 将高德地图API进行二次封装,降低地图相 ...

  5. html 高德地图坐标,百度地图,高德地图,HTML5经纬度比较

    对于一个地点的经纬度,是确定的?这个问题,我想很多人都会回答,肯定了,可实际上呢?我只能呵呵了. 在使用百度地图的过程中,发现一个很奇怪的现象,有时候调用百度地图js API时,后得到一个错的离谱的地 ...

  6. 安卓开发 高德地图 marker 点击移动位置_高德手机AR导航再升级,有惊喜

    高德地图发布V10.70新版本啦AR驾车导航服务再次升级 支持连接车内行车记录仪! 由行车记录仪的摄像头充当"眼睛",实时捕捉现实道路画面,再通过手机地图呈现直观的3D导航指引,为 ...

  7. Swift基础 - - 高德地图实践

    高德地图开发需要自己到官网http://lbs.amap.com/console/ 注册一个ak,新建一个swift工程,然后在Info.plist中添加一个NSLocationAlwaysUsage ...

  8. 如何实现在H5里调起高德地图APP?(下)

    这一篇文章将告诉您,如果直接打开高德地图APP,并展示路线规划.适合有定位的移动设备,可以查询到从"我的位置"到目的地的路径规划,并直接导航. 场景二.调起高德地图的路线规划功能 ...

  9. 高德地图小蓝点_一会晴天一会下雨?夏日想要顺利出行 高德地图这些小功能最实用...

    不同于其他三个季节,夏天总是有很多种烦恼,变化不定的天气就是其中最为影响出行的一项因素.而面对忽晴忽雨的天气,如何才能在夏日顺利出行呢?看看高德地图的这些实用小功能吧. ·实时天气预报 高德地图可以实 ...

  10. 高德地图2020最新版下载导航wince_导航定位错误致青城山严重拥堵,高德地图回应:已优化...

    钛媒体 TMTPost.com|科技引领新经济| ▎景区官方表示,错误导航问题已存在多年,景区多次与高德地图方联系,要求对青城前山景区导航路线进行修改优化,但均未果. 钛媒体编辑丨石万佳 钛媒体App ...

最新文章

  1. sap linux下配置文件,Linux下配置sapjco3
  2. 携程CEO称成功来自传统营销 B2C已经过时
  3. php session redis 配置
  4. 【Linux】一步一步学Linux——ip命令(183)
  5. python-23 xml.etree.ElementTree模块
  6. datapumpdir oracle_oracle_datapump创建外部表案例
  7. 【拨云见日】全面云化时代,如何选择适合自己的“云”?
  8. 2012禁用ip隧道 win_Windows 7下关闭IPV6隧道的技巧方法
  9. (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  10. TensorFlow2实现空间自适应归一化(Spatial Adaptive Normalization, SPADE)
  11. transform子元素,绝对定位失效
  12. Android 常用开发工具收藏
  13. JAVA-初步认识-第十四章-线程间通信-多生产者多消费者问题-JDK1.5新特性解决办法-范例...
  14. Win11快捷键大全
  15. 如何快速选购腾讯云DNS解析服务?
  16. CC2652RB硬件I2C读取FXOS8700CQ加速度传感器
  17. 切!原来进入500强就那么简单啊——前IBM,HP,Dell员工揭开外企的招聘内幕
  18. 51nod 1213 二维曼哈顿距离最小生成树
  19. MATLAB 复杂网络蓄意攻击代码
  20. modbustcp测试工具怎么用_【转】年轻人不讲武德不仅白piao接口测试知识还白piao接口测试工具会员...

热门文章

  1. Unity 基础知识参考
  2. 计算机毕业论文性能测试怎么写,计算机毕业论文撰写技巧
  3. 系统架构变迁——个人成长路线
  4. jQuery EasyUI快速入门01
  5. 如何用python做前端_python 适合做什么开发 python是用于前端还是后端开发
  6. eclipse 改java版本_修改eclipse工程jdk版本
  7. 下载蓝盒插件_chrome迅雷下载插件-迅雷下载支持插件下载 v3.1官方版--pc6下载站...
  8. BAD SYSTEM CONFIG INFO 修复办法
  9. protues软件仿真-LCD1602
  10. 解决笔记本没有COM端口导致无法用SecureCRT或者超级终端配置交换机