2

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

Edip Ahmet
  • 465
  • 8
  • 18
  • what is currentIndex? – Pa_ May 12 '20 at 06:59
  • I added ComboBox to the question. Current index is 0 by default which is Open Street Map. – Edip Ahmet May 12 '20 at 15:53
  • the url you are adding refers to the custom map type, that is typically the last in the availableMapType array – Pa_ May 12 '20 at 18:13
  • Actually I don't know much about map parameters. I saw it in a sample source code and I used it. last index of the model is Hiking map view. – Edip Ahmet May 12 '20 at 18:47
  • I asked the same question to Facebook Qt group, and someone said OSM plugin is no longer supported by Qt. Also there were similar questions on Qt forum without answer. – Edip Ahmet May 12 '20 at 18:51

3 Answers3

7

(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

3

An alternate idea similar to Mike's, but that saves you having to set up a web server, is to create the server in your own application.

An example implementation is here, that supports thunderforest API keys, and also allows MapTiler to be used for the Satellite maps:

https://github.com/f4exb/sdrangel/blob/master/plugins/feature/map/osmtemplateserver.h

This server will start on a free IP port, so shouldn't clash with other apps. You just then need to set osm.mapping.providersrepository.address to http://127.0.0.1:port/

srce
  • 45
  • 5
0

The simplest solution is to just use local files, no server needed (neither local nor remote).

Just make sure they are valid URLs, like:

PluginParameter {
  name: "osm.mapping.providersrepository.address"
  value: "file:///home/user/tile-provider/" // development
  //value: "qrc:///tile-provider/"          // final app
}

Put all the required json files (without file ending) under the above path (like street, satellite, terrain etc).

P.S. This is tested with Qt 5.15.2 on all platforms, including mobile.

user644348
  • 33
  • 3
  • Didn't worked for me. server setup worked fine. – ניר Aug 28 '23 at 08:57
  • of course it works, this is tested with Qt 5.15., just pay attention to not use file endings with the json files; I have an app which runs on every platform, including mobile, and it works perfectly everywhere, so please don't spread false information @ניר – user644348 Aug 30 '23 at 07:39
  • I tried on qt/6.5.0. Also note that I said "Didn't worked **for me**" no *"false information"* here. – ניר Aug 30 '23 at 11:57
  • ok sorry, I will try to get it to work with Qt6, let's see if I can trick it to work... – user644348 Aug 30 '23 at 16:48