QtLocation OSM API 需要密钥

QtLocation OSM API Key required

我正在使用 OSM,这里是 QML 应用程序的地图插件。我在 ComboBox 中使用 map.activeMapType = map.supportedMapTypes[currentIndex] 来在地图区域显示来自地图提供商的支持的地图类型。这里的地图插件使用 "here.app_id""here.token" 参数。但对于 OSM 插件、Terrain、transit 和除 Street map tile display 之外的其他 tiles "API Key Required"。我从 thunderforest.com 得到了 API 密钥。使用参数时,还是显示"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>" }
        }

我还从 http://maps-redirect.qt.io/osm/5.8/ 站点下载了地形文件参数,以便像这样与 qrc 一起使用:

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]

                      }
                  }
          }
      }
    }
}

在地形文件中,我将参数更新为 "UrlTemplate" : "https://tile.thunderforest.com/landscape/{z}/{x}/{y}.png?apikey=<api-key>", 这没有用,自定义地图视图是空的。是否可以使用 API 键将其删除?谢谢

(从我的博客文章中复制过来:http://blog.mikeasoft.com/2020/06/22/qt-qml-maps-using-the-osm-plugin-with-api-keys/

这并不明显,但在深入研究 OSM 插件的工作方式后,我发现了一种机制,通过该机制可以将 API 密钥提供给需要密钥的磁贴服务器。

当 OSM 插件初始化时,它会与 Qt 提供程序存储库通信,该存储库会告诉它要为每种地图类型使用哪些 URL。供应商存储库的位置可以通过 osm.mapping.providersrepository.address OSM 插件 属性 自定义,所以我们需要做的就是使用我们的 API 密钥使用包含我们的 API 键作为参数的 URL 来设置我们自己的提供商存储库。存储库本身只是 JSON 文件的集合,具有特定名称(cycle、cycle-hires、hiking、hiking-hires、night-transit、night-transit-hires、satellite、street、 street-hires, terrain, terrain-hires, transit, transit-hires) 每个对应一个地图类型。 *-hires 文件为高 DPI 显示提供两倍正常分辨率的图块 URL。

例如,这是默认 Qt 提供程序存储库提供的循环文件:

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

要为磁贴请求提供 API 键,我们只需修改 UrlTemplate:

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

自动存储库设置

我在这里创建了一个简单的工具,用于使用自定义 API 密钥设置完整的存储库:https://github.com/Elleo/qt-osm-map-providers

  1. 首先从https://www.thunderforest.com/docs/apikeys/
  2. 获得一个API密钥
  3. 接下来克隆我的存储库:git clone https://github.com/Elleo/qt-osm-map-providers.git
  4. 运行:./set_api_keys.sh your_api_key(将your_api_key替换为您在步骤1中获得的密钥)
  5. 将文件从此存储库复制到您的网络服务器(例如 http://www.mywebsite.com/osm_repository
  6. 将 osm.mapping.providersrepository.address 属性 设置为指向第 4 步中的位置设置(参见下面的 QML 示例)

QML 示例

这是一个 QML 应用程序的简单示例,它将使用我们设置的自定义存储库:

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

另一个与 Mike 类似的想法是在您自己的应用程序中创建服务器,但这样可以节省您设置 Web 服务器的时间。

这里有一个示例实现,它支持 thunderforest API 键,还允许 MapTiler 用于卫星地图:

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

此服务器将在空闲 IP 端口上启动,因此不应与其他应用发生冲突。然后您需要将 osm.mapping.providersrepository.address 设置为 http://127.0.0.1:port/