前言
在QGC自带的地图里,能使用且好用的地图不多,很多地图只有影像图没有注记图层,混合图层能用的好像只有Bing的Hybrid。现在有一个项目要求使用国内的地图,在高德百度腾讯天地图之中最后采用了天地图,因为天地图基本不存在坐标系兼容的问题,前几者要么采用火星坐标系,要么自己自定义的坐标系,只有天地图是采用类似于WGS84的坐标系(误差和偏移只有毫米级别,基本可以忽略)。下面记录下实现过程。但是天地图官网是没有混合图层的瓦片地址的(至少我没找到直接可用的混合图层),需要自己把影像图和注记图层结合起来。
一、天地图密钥的申请
这个不难,不详细说明,自行百度。Tips:记得申请浏览器端密钥,不要选择服务器端密钥。
二、QGC前后端注册天地图并添加瓦片地址
1.本文使用的QGC版本4.0.11,在GenericMapProvider.h文件末尾添加两个Class。
class TianDiTextSatMapProvider : public MapProvider {
Q_OBJECT
public:
TianDiTextSatMapProvider(QObject* parent = nullptr)
: MapProvider(QStringLiteral("www.tiandi.com"), QStringLiteral("jpg"),
AVERAGE_TILE_SIZE, QGeoMapType::SatelliteMapDay, parent) {}
QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override;
private:
const QString _versionBingMaps = QStringLiteral("563");
};
class TianDiImgSatMapProvider : public MapProvider {
Q_OBJECT
public:
TianDiImgSatMapProvider(QObject* parent = nullptr)
: MapProvider(QStringLiteral("www.tiandi.com"), QStringLiteral("jpg"),
AVERAGE_TILE_SIZE, QGeoMapType::SatelliteMapDay, parent) {}
QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override;
private:
const QString _versionBingMaps = QStringLiteral("563");
};
2.在GenericMapProvider.cpp里实现_getURL函数
QString TianDiTextSatMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) {
Q_UNUSED(networkManager)
return QStringLiteral("http://t1.tianditu.gov.cn/cia_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cia&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX=%1&TILEROW=%2&TILECOL=%3&tk=%4").arg(zoom).arg(y).arg(x).arg(QStringLiteral("0586ae92d14ee8a98ec4443d7f13fb7a"));
}
QString TianDiImgSatMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) {
Q_UNUSED(networkManager)
return QStringLiteral("http://t1.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX=%1&TILEROW=%2&TILECOL=%3&tk=%4").arg(zoom).arg(y).arg(x).arg(QStringLiteral("0586ae92d14ee8a98ec4443d7f13fb7a"));
}
在QGCMapUrlEngine.cpp里注册影像图层和注记图层
_providersTable["TianDiTu Satellite Map"] = new TianDiImgSatMapProvider(this);
_providersTable["TianDiTu Text"] = new TianDiTextSatMapProvider(this);
做到这里,天地图的影像图层和注记图层是已经添加进QGC里了,但是并没有把影像图层和注记图层结合起来,只能显示单一图层。Qt在QtLocation模块可以将两个Map贴在一起使用,即可将两个单一图层合并成混合图层,实际上可以理解为加载了两个地图。单一图层效果如下: 这是加载了天地图的注记图层,只有道路和文字标记,没有房屋建筑。 在FlightMap.qml里找到 MapQuickItem模块,并在其后添加一个Map标记图层
MapQuickItem {
anchorPoint.x: sourceItem.width / 2
anchorPoint.y: sourceItem.height / 2
visible: gcsPosition.isValid
coordinate: gcsPosition
sourceItem: Image {
id: mapItemImage
source: isNaN(gcsHeading) ? "/res/QGCLogoFull" : "/res/QGCLogoArrow"
mipmap: true
antialiasing: true
fillMode: Image.PreserveAspectFit
height: ScreenTools.defaultFontPixelHeight * (isNaN(gcsHeading) ? 1.75 : 2.5 )
sourceSize.height: height
transform: Rotation {
origin.x: mapItemImage.width / 2
origin.y: mapItemImage.height / 2
angle: isNaN(gcsHeading) ? 0 : gcsHeading
}
}
}
Map {
anchors.fill: parent
plugin: Plugin {
name: "QGroundControl"
}
gesture.enabled: false
center: parent.center
color: 'transparent'
minimumFieldOfView: parent.minimumFieldOfView
maximumFieldOfView: parent.maximumFieldOfView
minimumTilt: parent.minimumTilt
maximumTilt: parent.maximumTilt
minimumZoomLevel: parent.minimumZoomLevel
maximumZoomLevel: parent.maximumZoomLevel
zoomLevel: parent.zoomLevel
tilt: parent.tilt;
bearing: parent.bearing
fieldOfView: parent.fieldOfView
z: parent.z + 1;
Component.onCompleted: {
updateActiveMapTypeText(this,"TianDiTu Text");
}
}
在FlightMap.qml里添加updateActiveMapTypeText 函数
function updateActiveMapType() {
var settings = QGroundControl.settingsManager.flightMapSettings
var fullMapName = settings.mapProvider.value + " " + settings.mapType.value
for (var i = 0; i < _map.supportedMapTypes.length; i++) {
if (fullMapName === _map.supportedMapTypes[i].name) {
_map.activeMapType = _map.supportedMapTypes[i]
return
}
}
}
function updateActiveMapTypeText(control,para) {
for (var i = 0; i < control.supportedMapTypes.length; i++) {
if (para === control.supportedMapTypes[i].name) {
control.activeMapType = control.supportedMapTypes[i]
return
}
}
}
至此,QGC地图修改为国内天地图,并将影像图和注记图层结合起来工作完成, 在常规界面中地图提供商:TianDitu;地图类型:Satellite Map
最后实现的效果如下: 若想实现更换其它地图商和地图类型(坐标系必须兼容,若不兼容,必须将坐标系转换成WGS84),只需按照上述流程做对应更改即可。楼主第一次写博客,文档格式可能有些不对之处,或者内容若有错误,请各位勿喷。
|