QGC的地图在国内某些地方,只有bing可用,其他都不能使用。而且bing卫星图也没有道路和标签信息,还死慢死慢的。据说bing其实就没有国内的卫星地图版权,在网页上查看bing地图,是没有卫星图的,只有切换到en-US上才有卫星图。
国内的地图百度、高德、腾讯、搜狗、天地图,有标签、速度快,看上去不错,但只是看上去。两个问题(其实是3个):地图更新太慢、最大到18级就没有了效果不好。
谷歌地图本来在QGC上就有,奈何QGC上集成的是www.google.com/maps
所以上不了,但是谷歌在国内是有地图服务许可的,卫星图效果非常好,可以支持到24级(再大没有试),远大于QGC默认编译的20级,速度也非常快。对比了一下Google地图至少在我上班这个地方卫星图是最新的。
百度谷歌地图(http://www.google.cn/maps)
菜单选卫星图像
浏览器 F12 看网络
找到卫星切片地址(西安钟楼)
http://www.google.cn/maps/vt?lyrs=s@847&gl=cn&x=52601&y=26122&z=16
解释下参数
找到无偏移瓦片URL
把参数lyrs替换一下发现都能用(xyz,就不要手动改了,不知道切片规则的话就是404)
坑点:国内地图都是带偏移的,谷歌为了拿到地图服务许可,也必须入乡随俗,本来当个地图看没问题,但真要用到飞行上就偏得太远,你用这个瓦片地址到QGC上定位就知道了。而且这种“火星坐标”最大得问题是每个地方偏移量还不一样,需要专门做数据库,还要改大量代码,不值当。那么google.cn有没有无偏移得地图呢?还真有,上面url去掉gl=cn这个参数就ok,手贱试出来的,注意只对卫星图有效,也就是lyrs=s有效,另外lyrs=y在卫星图上无偏移,标签道路上有偏移,这个也算比较理想的地图了吧,你可以自己改参数试试。
能用的url
http://www.google.cn/maps/vt?lyrs=s&x=52601&y=26122&z=16
http://www.google.cn/maps/vt?lyrs=y&x=52601&y=26122&z=16
http://www.google.cn/maps/vt?lyrs=y&gl=cn&x=52601&y=26122&z=16
http://www.google.cn/maps/vt?lyrs=p&gl=cn&x=6051&y=2997&z=13
http://www.google.cn/maps/vt?lyrs=m&gl=cn&x=52601&y=26122&z=16
其他地图瓦片
ArcGis(esri)已被集成在QGC中,因为没有Token,所以不显示,但是下面两个瓦片是不需要token的支持到19级,需要把判断esri token的地方注释掉
#下载
git clone https://github.com/mavlink/qgroundcontrol.git --recursive
#查看tag
git tag
#查看分支
git branch
#以v3.5.3稳定版为蓝本创建分支,随便取个名字叫cunstom353
git checkout -b cunstom353 v3.5.3
要搭建编译环境,打开QT Creator,把工程编译一遍,这一步过不去后面的就呵呵了,这也是一个比较坑爹的地方,QGC官方给的说明不太对,请参考下面的文档:
1. https://dev.qgroundcontrol.com/en/getting_started/
2. 工程目录/.travis.yml
对于qt版本和安卓ndk版本在第二个文档内是肯定正确的,毕竟人家拿这个去自动生成Daily build
/src/Settings/FlightMap.SettingsGroup.json
用于显示[
{
"name": "mapProvider",
"shortDescription": "Currently selected map provider for flight maps",
"type": "uint32",
"enumStrings": "Google.cn,Esri",
"enumValues": "0,1",
"defaultValue": 0
},
{
"name": "mapType",
"shortDescription": "Currently selected map type for flight maps,* means can't use to feight",
"type": "uint32",
"enumStrings": "卫星,卫星混合(仅标签偏移),*卫星混合(全偏移),街道,*街道(偏移),地形,*地形(偏移)",
"enumValues": "0,1,2,3,4,5,6",
"defaultValue": 0
}
]
/src/Settings/FlightMapSettings.h
定义地图提供商和地图类型...
// 必须和上json的数据个数顺序对应
typedef enum {
mapProviderGoogle,
mapProviderEsri
} MapProvider_t;
// 必须和上json的数据个数顺序对应
typedef enum {
mapTypeSatellite,
mapTypeSatelliteMix,
maptypeSatelliteMixOffset,
mapTypeStreet,
mapTypeStreetOffset,
mapTypeTerrain,
mapTypeTerrainOffset
} MapType_t;
...
/src/Settings/FlightMapSettings.cc
/* 33:这两处注释掉 不然esri地图显示不出来
if(qgcApp()->toolbox()->settingsManager()->appSettings()->mapboxToken()->rawValue().toString().isEmpty()) {
_excludeProvider(mapProviderMapbox);
}
if(qgcApp()->toolbox()->settingsManager()->appSettings()->esriToken()->rawValue().toString().isEmpty()) {
_excludeProvider(mapProviderEsri);
}
*/
//80:地图提供商没有的地图类型
void FlightMapSettings::_newMapProvider(QVariant value)
{
FactMetaData* metaData = _nameToMetaDataMap[mapTypeName];
QStringList enumStrings = _savedMapTypeStrings;
QVariantList enumValues = _savedMapTypeValues;
switch (value.toInt()) {
case mapProviderGoogle:
_removeEnumValue(mapTypeStreet,enumStrings,enumValues);
_removeEnumValue(mapTypeStreetOffset,enumStrings,enumValues);
_removeEnumValue(mapTypeTerrain,enumStrings,enumValues);
break;
case mapProviderEsri:
_removeEnumValue(mapTypeSatelliteMix,enumStrings,enumValues);
_removeEnumValue(maptypeSatelliteMixOffset,enumStrings,enumValues);
_removeEnumValue(mapTypeStreetOffset,enumStrings,enumValues);
_removeEnumValue(mapTypeTerrain,enumStrings,enumValues);
_removeEnumValue(mapTypeTerrainOffset,enumStrings,enumValues);
break;
...
/src/QtLocationPlugin/QGCMapUrlEngine.h
原来没有的地图类型加到URL库中 ...
//41:卫星混合(全偏移)
GoogleStatelliteWithLable = 21,
//卫星混合(标签偏移)
GoogleStatelliteWithLableNofix = 22,
...
/src/QtLocationPlugin/QGCMapUrlEngine.cpp
定义瓦片URL ...
//230
case GoogleMap:
return QString("http://www.google.cn/maps/vt?lyrs=m&gl=cn&x=%1&y=%2&z=%3").arg(x).arg(y).arg(zoom);
case GoogleSatellite:
return QString("http://www.google.cn/maps/vt?lyrs=s&x=%1&y=%2&z=%3").arg(x).arg(y).arg(zoom);
case GoogleLabels:
return QString("http://www.google.cn/maps/vt?lyrs=h&gl=cn&x=%1&y=%2&z=%3").arg(x).arg(y).arg(zoom);
case GoogleTerrain:
return QString("http://www.google.cn/maps/vt?lyrs=p&gl=cn&x=%1&y=%2&z=%3").arg(x).arg(y).arg(zoom);
case GoogleStatelliteWithLable:
//卫星混合(全偏移)
return QString("http://www.google.cn/maps/vt?lyrs=y&gl=cn&x=%1&y=%2&z=%3").arg(x).arg(y).arg(zoom);
case GoogleStatelliteWithLableNofix:
//卫星混合(标签偏移)
return QString("http://www.google.cn/maps/vt?lyrs=y&x=%1&y=%2&z=%3").arg(x).arg(y).arg(zoom);
...
case EsriWorldStreet:
return QString("http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/%1/%2/%3").arg(zoom).arg(y).arg(x);
case EsriWorldSatellite:
return QString("http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/%1/%2/%3").arg(zoom).arg(y).arg(x);
...
/src/QtLocationPlugin/QGeoTiledMappingManagerEngineQGC.cpp
将前台地图类型和后台URL连接,第一个字符串是 供应商名+一个空格+地图类型,第二个字符串是简介,随便写
//108:卫星(无偏移)
mapTypes << QGCGEOMAPTYPE(QGeoMapType::SatelliteMapDay, "Google.cn 卫星", "Google.cn 卫星", false, false, UrlFactory::GoogleSatellite);
mapTypes << QGCGEOMAPTYPE(QGeoMapType::TerrainMap, "Google.cn *地形(偏移)", "Google.cn *地形(偏移)", false, false, UrlFactory::GoogleTerrain);
//卫星混合(全偏移)
mapTypes << QGCGEOMAPTYPE(QGeoMapType::SatelliteMapDay, "Google.cn *卫星混合(全偏移)", "Google.cn *卫星混合(全偏移)",false, false, UrlFactory::GoogleStatelliteWithLable);
//卫星混合(标签偏移)
mapTypes << QGCGEOMAPTYPE(QGeoMapType::SatelliteMapDay, "Google.cn 卫星混合(仅标签偏移)","Google.cn 卫星混合(仅标签偏移)", false, false, UrlFactory::GoogleStatelliteWithLableNofix);
// Esri
mapTypes << QGCGEOMAPTYPE(QGeoMapType::StreetMap, "Esri 街道", "ArcGIS Online World 街道", true, false, UrlFactory::EsriWorldStreet);
mapTypes << QGCGEOMAPTYPE(QGeoMapType::SatelliteMapDay, "Esri 卫星", "ArcGIS Online World 卫星", true, false, UrlFactory::EsriWorldSatellite);
...
/src/QtLocationPlugin/QGCMapEngine.cpp
修改离线地图//48:字符串要求同上节
stQGeoTileCacheQGCMapTypes kMapTypes[] = {
{"Google.cn 卫星", UrlFactory::GoogleSatellite},
{"Google.cn 卫星混合(仅标签偏移)", UrlFactory::GoogleStatelliteWithLableNofix},
{"Google.cn *卫星混合(全偏移)", UrlFactory::GoogleStatelliteWithLable},
{"Google.cn *地形(偏移)", UrlFactory::GoogleTerrain},
{"Esri 卫星", UrlFactory::EsriWorldSatellite},
{"Esri 街道", UrlFactory::EsriWorldStreet},
};
//380:注释掉下面这两处,好像不注释也没问题
QStringList
QGCMapEngine::getMapNameList()
{
QStringList mapList;
for(size_t i = 0; i < NUM_MAPS; i++) {
mapList << kMapTypes[i].name;
}
/*
if(!qgcApp()->toolbox()->settingsManager()->appSettings()->mapboxToken()->rawValue().toString().isEmpty()) {
for(size_t i = 0; i < NUM_MAPBOXMAPS; i++) {
mapList << kMapboxTypes[i].name;
}
}
if(!qgcApp()->toolbox()->settingsManager()->appSettings()->esriToken()->rawValue().toString().isEmpty()) {
for(size_t i = 0; i < NUM_ESRIMAPS; i++) {
mapList << kEsriTypes[i].name;
}
}*/
return mapList;
}
可以按照设计正常显示地图,本来还想加OpenStreet,在浏览器上没问题,但在QGC上死活不出来,应该是OpenStreet没有许可只能在浏览器上使用。