Use tileserver-gl host in qt map

1.4k views Asked by At

I've setup a local tile server to use with my application but when I create my QML Map object and specify the plugin to use a custom host, the application does not use the local tiles. Cycling through supportedMapTypes and setting the activeMapType property on the map object will display some tiles, but they appear to be some set of default tiles and not the tiles from my local tile server.

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)
}

I know the tile server is functioning properly as I can reach it in the browser by navigating to localhost:8080 and I can access arbitrary tiles using http://localhost:8080/data/openmaptiles_satellite_lowres/{z}/{y}/{x}.jpg

UPDATE

I'm trying to override the default provider repository files as suggested below by TomasL but the application doesn't seem to be using the plugin parameters specified.

Map component in 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,
}

With the code above, my application still tries to reach out to the default server otile1.mqcdn.com

3

There are 3 answers

1
eyllanesc On BEST ANSWER

The problem is that the media you are using provides jpg images but the Qt OSM plugin only supports png formats. One solution is to clone the Qt Location module, modify the source code so that the image format can be set, compiled and installed.

To simplify that task I have created a patch for 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
                 ));

The steps outlined above can be summarized as:

git clone -b 5.15.1 https://github.com/qt/qtlocation.git
cd qtlocation/src/plugins/geoservices/osm
wget https://raw.githubusercontent.com/eyllanesc/stackoverflow/master/questions/64391146/tile_image_format.patch
git apply tile_image_format.patch
qmake
make
make install

On the other hand you must point activeMapType in 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
}

enter image description here

7
TomasL On

A simple way to do this with no Qt patch needed, is use the OpenStreetMap plugin as it is, but set another providers repository address to the plugin.

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" }
}

You may then put all map layer redirect files named cycle, hiking, night-transit, satellite, street, terrain, transit in the qrc:/Common/Engine/Source/Plugins/N/NRedirect folder. If you will e.g. only use satellite layer, then skip all the other files. The satellite file could then look like this (this is where the real magic is!)

    {
        "UrlTemplate" : "http://localhost:8080/data/openmaptiles_satellite_lowres/%z/%x/%y.jpg",
        "ImageFormat" : "jpg",
        "QImageFormat" : "Indexed8",
        "MapCopyRight" : "OpenStreetMap",
        "DataCopyRight" : "OpenStreetMap",
        "Timestamp" : "2019-02-01"
    }

Please note that in your example url, http://localhost:8080/data/openmaptiles_satellite_lowres/{z}/{y}/{x}.jpg , the order of z/x/y is different than in most examples. If the server is set up this way, you would need to change the UrlTemplate above.

More details on this are found in the source code for the osm plugin: https://github.com/qt/qtlocation/blob/dev/src/plugins/geoservices/osm/qgeotileproviderosm.cpp#L392-L568

0
Mertcan Özdemir On

One easy solution is just rename your .jpg files to .png(Don't convert them just rename). You can write a script that batch renames all jpg files in your provider folder. QImage doesn't care about extension so if you rename your jpg files they will work just fine.