qtqmlqtlocation

QtLocation OSM API Key required


I am using OSM and here map plugins for QML app. I use map.activeMapType = map.supportedMapTypes[currentIndex] in ComboBox to display supported map types from map providers on the map area. Here map plugin works with "here.app_id" and "here.token" parameters. But for OSM plugin, Terrain, transit and other tiles except Street map tile display "API Key Required". I got API key from thunderforest.com. When using the parameter, it still shows "API Key Required" :

   ComboBox {
            id: selectmap
            width: parent.width
            model:map.supportedMapTypes
            textRole:"description"
            onCurrentIndexChanged:{
                map.activeMapType = map.supportedMapTypes[currentIndex]
            }
        }
    Plugin {
            id: pluginOSM
            name: "osm"
            PluginParameter { 
                name: "osm.mapping.providersrepository.address"; 
                // name: "osm.geocoding.host"; (also didn't work)
                value: "https://tile.thunderforest.com/transport/{z}/{x}/{y}.png?apikey=<my_api_key>" }
        }

Screenshot

I also downloaded terrain file parameter from http://maps-redirect.qt.io/osm/5.8/ site to use with qrc like this:

import QtQuick 2.6
import QtQuick.Controls 2.0
import QtLocation 5.12
import QtPositioning 5.12
ApplicationWindow{
    id: root
    width: 500
    height: 700
    visible: true
    Flickable {
        height: parent.height
        width: parent.width
        clip: true
        boundsBehavior: Flickable.StopAtBounds
        contentHeight: Math.max(mapColumn.implicitHeight, height)+50
        ScrollBar.vertical: ScrollBar {}
        z: 2
        Column{
            anchors.horizontalCenter: parent.horizontalCenter
            id:mapColumn
            spacing: 5
            anchors.fill : parent
            Row{
                anchors.horizontalCenter: parent.horizontalCenter
                spacing:25
                id:maprow
                Rectangle{
                width:mapColumn.width
                height:mapColumn.height/2

                Map {
                    id:map
                    anchors.fill: parent
                    plugin: Plugin {
                        name: "osm"
                        PluginParameter {
                            name: "osm.mapping.host";
                            value: "qrc:/terrain"
                        }
                    }
                }

          }
          }

          Column{
              id: combos
              spacing: 10
              width: parent.width
              anchors.verticalCenter: root.verticalCenter
                  Row{
                      anchors.horizontalCenter: parent.horizontalCenter
                      spacing:1
                      Label{ text:"Map Type: " }
                      // Map Types
                      ComboBox {
                          id: selectmap
                          width: 200
                          model:map.supportedMapTypes
                          textRole:"description"
                          onCurrentIndexChanged: map.activeMapType = map.supportedMapTypes[currentIndex]

                      }
                  }
          }
      }
    }
}

In terrain file I updated the parameter as "UrlTemplate" : "https://tile.thunderforest.com/landscape/{z}/{x}/{y}.png?apikey=<api-key>", This didn't work, the custom map view was empty. Is it possible to remove it with API key? Thanks


Solution

  • (Copied from my blog article here: http://blog.mikeasoft.com/2020/06/22/qt-qml-maps-using-the-osm-plugin-with-api-keys/)

    It’s not obvious, but after a bit of digging into the way the OSM plugin works I’ve discovered a mechanism by which an API key can be supplied to tile servers that require one.

    When the OSM plugin is initialised it communicates with the Qt providers repository which tells it what URLs to use for each map type. The location of the providers repository can be customised through the osm.mapping.providersrepository.address OSM plugin property, so all we need to do to use our API key is to set up our own providers repository with URLs that include our API key as a parameter. The repository itself is just a collection of JSON files, with specific names (cycle, cycle-hires, hiking, hiking-hires, night-transit, night-transit-hires, satellite, street, street-hires, terrain, terrain-hires, transit, transit-hires) each corresponding to a map type. The *-hires files provide URLs for tiles at twice the normal resolution, for high DPI displays.

    For example, this is the cycle file served by the default Qt providers repository:

    {
        "UrlTemplate" : "http://a.tile.thunderforest.com/cycle/%z/%x/%y.png",
        "ImageFormat" : "png",
        "QImageFormat" : "Indexed8",
        "ID" : "thf-cycle",
        "MaximumZoomLevel" : 20,
        "MapCopyRight" : "<a href='http://www.thunderforest.com/'>Thunderforest</a>",
        "DataCopyRight" : "<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors"
    }
    

    To provide an API key with our tile requests we can simply modify the UrlTemplate:

        "UrlTemplate" : "http://a.tile.thunderforest.com/cycle/%z/%x/%y.png?apikey=YOUR_API_KEY",
    

    Automatic repository setup

    I’ve created a simple tool for setting up a complete repository using a custom API key here: https://github.com/Elleo/qt-osm-map-providers

    1. First obtain an API key from https://www.thunderforest.com/docs/apikeys/
    2. Next clone my repository: git clone https://github.com/Elleo/qt-osm-map-providers.git
    3. Run: ./set_api_keys.sh your_api_key (replacing your_api_key with the key you obtained in step 1)
    4. Copy the files from this repository to your webserver (e.g. http://www.mywebsite.com/osm_repository)
    5. Set the osm.mapping.providersrepository.address property to point to the location setup in step 4 (see the QML example below)

    QML Example

    Here’s a quick example QML app that will make use of the custom repository we’ve set up:

    import QtQuick 2.7
    import QtQuick.Controls 2.5
    import QtLocation 5.10
    
    ApplicationWindow {
    
        title: qsTr("Map Example")
        width: 1280
        height: 720
    
        Map {
            anchors.fill: parent
            zoomLevel: 14
            plugin: Plugin {
                name: "osm"
                PluginParameter { name: "osm.mapping.providersrepository.address"; value: "http://www.mywebsite.com/osm_repository" }
                PluginParameter { name: "osm.mapping.highdpi_tiles"; value: true }
            }
            activeMapType: supportedMapTypes[1] // Cycle map provided by Thunderforest
        }
        
    }
    

    Screenshot of QML map example