0

我正在使用 OSM 和这里的 QML 应用程序的地图插件。我map.activeMapType = map.supportedMapTypes[currentIndex]在 ComboBox 中使用以在地图区域上显示来自地图提供者的支持的地图类型。这里地图插件使用"here.app_id""here.token"参数。但是对于 OSM 插件,Terrain、transit 和除街道地图图块外的其他图块显示“需要 API 密钥”。我从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 密钥将其删除?谢谢

4

2 回答 2

3

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

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

当 OSM 插件初始化时,它会与 Qt 提供者存储库通信,该存储库会告诉它要为每种地图类型使用哪些 URL。提供者存储库的位置可以通过osm.mapping.providersrepository.address OSM 插件属性进行自定义,因此我们需要做的就是使用我们的 API 密钥设置我们自己的提供者存储库,其 URL 包含我们的 API 密钥作为范围。存储库本身只是 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"
}

要为我们的 tile 请求提供 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/获取 API 密钥
  2. 接下来克隆我的存储库:git clone https://github.com/Elleo/qt-osm-map-providers.git
  3. 运行:(./set_api_keys.sh your_api_key将 your_api_key 替换为您在步骤 1 中获得的密钥)
  4. 将此存储库中的文件复制到您的网络服务器(例如http://www.mywebsite.com/osm_repository
  5. 将 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
    }
    
}

QML 地图示例截图

于 2020-06-23T09:03:01.153 回答
2

与 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/

于 2021-12-03T14:14:52.247 回答