在qt地图中使用tileserver-gl host
Use tileserver-gl host in qt map
我已经设置了一个本地切片服务器来与我的应用程序一起使用,但是当我创建我的 QML 地图对象并指定插件使用自定义主机时,该应用程序不使用本地切片。循环 supportedMapTypes
并在地图对象上设置 activeMapType
属性 将显示一些图块,但它们似乎是一组默认图块,而不是来自我本地图块服务器的图块。
Map
{
id: map
objectName: "basemap"
anchors.fill: parent
plugin: Plugin
{
name: "osm"
PluginParameter
{
name: "osm.mapping.custom.host"
value: "http://localhost:8080/data/openmaptiles_satellite_lowres/"
}
}
zoomLevel: 1
activeMapType: // varies depending on selection from another object in application
center: QtPositioning.coordinate(0, 0)
}
我知道图块服务器运行正常,因为我可以通过导航到 localhost:8080
在浏览器中访问它,并且我可以使用 http://localhost:8080/data/openmaptiles_satellite_lowres/{z}/{y}/{x}.jpg
访问任意图块
更新
我正在尝试按照 TomasL 下面的建议覆盖默认提供程序存储库文件,但应用程序似乎没有使用指定的插件参数。
Mapper.qml
中的地图组件
Map {
id: basemap
objectName: "basemap"
anchors.fill: parent
plugin: ProvidersPlugin {}
activeMapType: supportedMapTypes[1] // To use the satellite file in providers repository
center: QtPositioning.coordinate(0, 0)
zoomLevel: 2
minimumZoomLevel: 0
maximumZoomLevel: 5
}
ProvidersPlugin.qml
import QtLocation 5.5
import QtPositioning 5.5
Plugin {
id: mapPlugin
name: "osm"
PluginParameter {
name: "osm.mapping.providersrepository.address"
value: Qt.resolvedUrl('./providers')
}
}
./providers/satellite
{
"Enabled" : true,
"UrlTemplate" : "http://localhost:8080/data/openmaptiles_satellite_lowres/%z/%x/%y.jpg",
"ImageFormat" : "jpg",
"QImageFormat" : "Indexed8",
"MapCopyRight" : "Test",
"DataCopyRight" : "Hello World",
"MinimumZoomLevel" : 0,
"MaximumZoomLevel" : 5,
}
使用上面的代码,我的应用程序仍会尝试连接到默认服务器 otile1.mqcdn.com
问题是您使用的媒体提供jpg图像,但Qt OSM插件只支持png格式。一种解决方案是克隆Qt Location模块,修改源代码,以便可以设置、编译和安装图像格式。
为了简化该任务,我为 Qt 5.15.1 创建了一个补丁:
tile_image_format.patch
diff --git a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp
index 22c32342..d4747a0a 100644
--- a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp
+++ b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp
@@ -217,11 +217,16 @@ QGeoTiledMappingManagerEngineOsm::QGeoTiledMappingManagerEngineOsm(const QVarian
if (parameters.contains(QStringLiteral("osm.mapping.copyright")))
m_customCopyright = parameters.value(QStringLiteral("osm.mapping.copyright")).toString();
+ QString format = "png";
+ if(parameters.contains(QStringLiteral("osm.mapping.custom.format"))){
+ format = parameters.value(QStringLiteral("osm.mapping.custom.format")).toString();
+ }
+
m_providers.push_back(
new QGeoTileProviderOsm( nmCached,
QGeoMapType(QGeoMapType::CustomMap, tr("Custom URL Map"), tr("Custom url map view set via urlprefix parameter"), false, false, 8, pluginName, cameraCaps),
- { new TileProvider(tmsServer + QStringLiteral("%z/%x/%y.png"),
- QStringLiteral("png"),
+ { new TileProvider(tmsServer + QStringLiteral("%z/%x/%y.") + format,
+ format,
mapCopyright,
dataCopyright) }, cameraCaps
));
上述步骤可以概括为:
git clone -b 5.15.1 https://github.com/qt/qtlocation.git
cd qtlocation/src/plugins/geoservices/osm
wget https://raw.githubusercontent.com/eyllanesc/Whosebug/master/questions/64391146/tile_image_format.patch
git apply tile_image_format.patch
qmake
make
make install
另一方面,您必须将 activeMapType 指向 MapType.CustomMap:
Map
{
id: map
anchors.fill: parent
plugin: Plugin
{
name: "osm"
PluginParameter
{
name: "osm.mapping.custom.host"
value: "http://localhost:8080/data/openmaptiles_satellite_lowres/"
}
PluginParameter
{
name: "osm.mapping.custom.format"
value: "jpg"
}
}
zoomLevel: 1
center: QtPositioning.coordinate(0, 0)
activeMapType: MapType.CustomMap
}
一种不需要 Qt 补丁的简单方法是按原样使用 OpenStreetMap 插件,但为该插件设置另一个提供商存储库地址。
import QtLocation 5.12
Plugin {
id: pluginN
property string projectname: ""
name: "osm"
PluginParameter {
name: "osm.mapping.providersrepository.address"
value: "qrc:/Common/Engine/Source/Plugins/N/NRedirect/" //or wherever you place your redirect files
}
PluginParameter { name: "osm.mapping.copyright"; value: "(c) N /OpenStreetMap" }
}
然后您可以将所有名为 cycle、hiking、night-transit、satellite、street、terrain、transit 的地图层重定向文件放入 qrc:/Common/Engine/Source/Plugins/N/NRedirect 文件夹中。如果你愿意,例如只使用卫星层,然后跳过所有其他文件。卫星文件可能看起来像这样(这才是真正的魔法所在!)
{
"UrlTemplate" : "http://localhost:8080/data/openmaptiles_satellite_lowres/%z/%x/%y.jpg",
"ImageFormat" : "jpg",
"QImageFormat" : "Indexed8",
"MapCopyRight" : "OpenStreetMap",
"DataCopyRight" : "OpenStreetMap",
"Timestamp" : "2019-02-01"
}
请注意,在您的示例中 url,http://localhost:8080/data/openmaptiles_satellite_lowres/{z}/{y}/{x}.jpg
, z/x/y 的顺序与大多数示例中的顺序不同。如果服务器是这样设置的,您将需要更改上面的 UrlTemplate。
有关此的更多详细信息,请参阅 osm 插件的源代码:
https://github.com/qt/qtlocation/blob/dev/src/plugins/geoservices/osm/qgeotileproviderosm.cpp#L392-L568
我已经设置了一个本地切片服务器来与我的应用程序一起使用,但是当我创建我的 QML 地图对象并指定插件使用自定义主机时,该应用程序不使用本地切片。循环 supportedMapTypes
并在地图对象上设置 activeMapType
属性 将显示一些图块,但它们似乎是一组默认图块,而不是来自我本地图块服务器的图块。
Map
{
id: map
objectName: "basemap"
anchors.fill: parent
plugin: Plugin
{
name: "osm"
PluginParameter
{
name: "osm.mapping.custom.host"
value: "http://localhost:8080/data/openmaptiles_satellite_lowres/"
}
}
zoomLevel: 1
activeMapType: // varies depending on selection from another object in application
center: QtPositioning.coordinate(0, 0)
}
我知道图块服务器运行正常,因为我可以通过导航到 localhost:8080
在浏览器中访问它,并且我可以使用 http://localhost:8080/data/openmaptiles_satellite_lowres/{z}/{y}/{x}.jpg
更新
我正在尝试按照 TomasL 下面的建议覆盖默认提供程序存储库文件,但应用程序似乎没有使用指定的插件参数。
Mapper.qml
中的地图组件Map {
id: basemap
objectName: "basemap"
anchors.fill: parent
plugin: ProvidersPlugin {}
activeMapType: supportedMapTypes[1] // To use the satellite file in providers repository
center: QtPositioning.coordinate(0, 0)
zoomLevel: 2
minimumZoomLevel: 0
maximumZoomLevel: 5
}
ProvidersPlugin.qml
import QtLocation 5.5
import QtPositioning 5.5
Plugin {
id: mapPlugin
name: "osm"
PluginParameter {
name: "osm.mapping.providersrepository.address"
value: Qt.resolvedUrl('./providers')
}
}
./providers/satellite
{
"Enabled" : true,
"UrlTemplate" : "http://localhost:8080/data/openmaptiles_satellite_lowres/%z/%x/%y.jpg",
"ImageFormat" : "jpg",
"QImageFormat" : "Indexed8",
"MapCopyRight" : "Test",
"DataCopyRight" : "Hello World",
"MinimumZoomLevel" : 0,
"MaximumZoomLevel" : 5,
}
使用上面的代码,我的应用程序仍会尝试连接到默认服务器 otile1.mqcdn.com
问题是您使用的媒体提供jpg图像,但Qt OSM插件只支持png格式。一种解决方案是克隆Qt Location模块,修改源代码,以便可以设置、编译和安装图像格式。
为了简化该任务,我为 Qt 5.15.1 创建了一个补丁:
tile_image_format.patch
diff --git a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp
index 22c32342..d4747a0a 100644
--- a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp
+++ b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp
@@ -217,11 +217,16 @@ QGeoTiledMappingManagerEngineOsm::QGeoTiledMappingManagerEngineOsm(const QVarian
if (parameters.contains(QStringLiteral("osm.mapping.copyright")))
m_customCopyright = parameters.value(QStringLiteral("osm.mapping.copyright")).toString();
+ QString format = "png";
+ if(parameters.contains(QStringLiteral("osm.mapping.custom.format"))){
+ format = parameters.value(QStringLiteral("osm.mapping.custom.format")).toString();
+ }
+
m_providers.push_back(
new QGeoTileProviderOsm( nmCached,
QGeoMapType(QGeoMapType::CustomMap, tr("Custom URL Map"), tr("Custom url map view set via urlprefix parameter"), false, false, 8, pluginName, cameraCaps),
- { new TileProvider(tmsServer + QStringLiteral("%z/%x/%y.png"),
- QStringLiteral("png"),
+ { new TileProvider(tmsServer + QStringLiteral("%z/%x/%y.") + format,
+ format,
mapCopyright,
dataCopyright) }, cameraCaps
));
上述步骤可以概括为:
git clone -b 5.15.1 https://github.com/qt/qtlocation.git
cd qtlocation/src/plugins/geoservices/osm
wget https://raw.githubusercontent.com/eyllanesc/Whosebug/master/questions/64391146/tile_image_format.patch
git apply tile_image_format.patch
qmake
make
make install
另一方面,您必须将 activeMapType 指向 MapType.CustomMap:
Map
{
id: map
anchors.fill: parent
plugin: Plugin
{
name: "osm"
PluginParameter
{
name: "osm.mapping.custom.host"
value: "http://localhost:8080/data/openmaptiles_satellite_lowres/"
}
PluginParameter
{
name: "osm.mapping.custom.format"
value: "jpg"
}
}
zoomLevel: 1
center: QtPositioning.coordinate(0, 0)
activeMapType: MapType.CustomMap
}
一种不需要 Qt 补丁的简单方法是按原样使用 OpenStreetMap 插件,但为该插件设置另一个提供商存储库地址。
import QtLocation 5.12
Plugin {
id: pluginN
property string projectname: ""
name: "osm"
PluginParameter {
name: "osm.mapping.providersrepository.address"
value: "qrc:/Common/Engine/Source/Plugins/N/NRedirect/" //or wherever you place your redirect files
}
PluginParameter { name: "osm.mapping.copyright"; value: "(c) N /OpenStreetMap" }
}
然后您可以将所有名为 cycle、hiking、night-transit、satellite、street、terrain、transit 的地图层重定向文件放入 qrc:/Common/Engine/Source/Plugins/N/NRedirect 文件夹中。如果你愿意,例如只使用卫星层,然后跳过所有其他文件。卫星文件可能看起来像这样(这才是真正的魔法所在!)
{
"UrlTemplate" : "http://localhost:8080/data/openmaptiles_satellite_lowres/%z/%x/%y.jpg",
"ImageFormat" : "jpg",
"QImageFormat" : "Indexed8",
"MapCopyRight" : "OpenStreetMap",
"DataCopyRight" : "OpenStreetMap",
"Timestamp" : "2019-02-01"
}
请注意,在您的示例中 url,http://localhost:8080/data/openmaptiles_satellite_lowres/{z}/{y}/{x}.jpg , z/x/y 的顺序与大多数示例中的顺序不同。如果服务器是这样设置的,您将需要更改上面的 UrlTemplate。
有关此的更多详细信息,请参阅 osm 插件的源代码: https://github.com/qt/qtlocation/blob/dev/src/plugins/geoservices/osm/qgeotileproviderosm.cpp#L392-L568