地图查看器(QML)
地图查看器示例展示了如何在 Qt Location 中显示和交互地图、搜索地址以及查找行车路线。
这是一个大型示例,涵盖了 Qt Location 中许多基本地图、定位和导航服务的用法。本页面分为几个部分,每部分都包含相关功能的代码片段。
运行示例
要从 Qt Creator 中运行此示例,请打开 欢迎使用 模式并从 示例 中选择此示例。有关更多信息,请访问 构建和运行示例。
示例可以与任何可用的地理服务插件一起工作。但是,某些插件可能需要额外的 插件参数 以正确运行。可以使用 --plugin
参数将 插件参数 传递到命令行,该参数的形式如下
--plugin.<parameter name> <parameter value>
有关详细信息,请参阅每个地理服务插件的文档,了解它们支持的插件参数。本示例默认使用的插件是 Qt Location Open Street Map 插件,它不需要任何参数。
概述
此示例中展示的 QML 类型
- 显示地图
- 查找地址
- 路线和旅行路线
显示地图
如图所示,使用 MapView 类型在屏幕上绘制地图,如下所示。
MapView { id: view map.zoomLevel: (maximumZoomLevel - minimumZoomLevel)/2 map.center { // The Qt Company in Oslo latitude: 59.9485 longitude: 10.7686 } }
该 MapView 包含一个 map 并扩展了基本导航功能。在此示例中,我们给地图设置了一个初始中心 坐标,并设置了纬度和经度。我们还将初始缩放级别设置为 50%(最大和最小之间的中间值)。
查找地址(地理编码)
为了在地图上定位特定地址或地点,需要使用地理编码的过程。为了执行地理编码操作,我们首先需要调整我们的 Map 对象以接收结果。
通过 GeocodeModel 接收地理编码的结果
GeocodeModel { id: geocodeModel plugin: view.map.plugin onStatusChanged: { if ((status == GeocodeModel.Ready) || (status == GeocodeModel.Error)) view.geocodeFinished() } onLocationsChanged: { if (count === 1) { view.map.center.latitude = get(0).coordinate.latitude view.map.center.longitude = get(0).coordinate.longitude } } }
要显示 GeocodeModel 的内容,我们使用 MapItemView
MapItemView { parent: view.map model: geocodeModel delegate: pointDelegate }
MapItemView 使用一个名为 delegate
的对象作为其创建的项目的模板。这可以包含任何所需的地图对象,但在本例中,我们显示了一个包含标记图像的 MapQuickItem
Component { id: pointDelegate MapQuickItem { id: point parent: view.map coordinate: locationData.coordinate sourceItem: Image { id: pointMarker source: "../resources/marker_blue.png" } } }
有了这三个对象,我们就有了接收地理编码响应并在我们的地图上显示它们所需要的全部。最后一步是要发送实际的地理编码请求。
要发送一个地理编码请求,首先我们创建一个地址对象,并用期望的参数填写它。
Address { id :fromAddress street: "Sandakerveien 116" city: "Oslo" country: "Norway" state : "" postalCode: "0484" }
然后我们将geocodeModel.query
设置为我们填写的地址,并调用GeocodeModel的update()方法。
// send the geocode request geocodeModel.query = fromAddress geocodeModel.update()
路线和出行路线
类似于GeocodeModel,Qt Location还提供了RouteModel类型,该类型允许接收和使用两个或多个点之间的路线信息(例如驾驶方向),以在地图上显示和使用。
同样地,我们将RouteModel实例化为我们地图的一个属性
RouteModel { id: routeModel plugin : view.map.plugin query: RouteQuery { id: routeQuery } onStatusChanged: { if (status == RouteModel.Ready) { switch (count) { case 0: // technically not an error view.routeError() break case 1: view.showRouteList() break } } else if (status == RouteModel.Error) { view.routeError() } } }
为了将模型的内容显示给用户,我们需要一个视图。我们再次将MapItemView用于在地图上将路线显示为对象
MapItemView { parent: view.map model: routeModel delegate: routeDelegate
为了使视图创建的对象模板化,我们创建了一个代理组件
Component { id: routeDelegate MapRoute { id: route route: routeData line.color: "#46a2da" line.width: 5 smooth: true opacity: 0.8
随着模型、视图和代理组件都准备好了,唯一缺少的组件是对模型的一种控制,以开始路由请求过程。在最简单的情况下,我们可以使用两个已有的坐标填充一个路线请求
property variant fromCoordinate: QtPositioning.coordinate(59.9483, 10.7695) property variant toCoordinate: QtPositioning.coordinate(59.9645, 10.671)
在下一个代码片段中,我们展示如何设置请求对象并指示模型更新。我们也指示地图以路由请求的起始坐标为中心
// clear away any old data in the query routeQuery.clearWaypoints(); // add the start and end coords as waypoints on the route routeQuery.addWaypoint(startCoordinate) routeQuery.addWaypoint(endCoordinate) routeQuery.travelModes = RouteQuery.CarTravel routeQuery.routeOptimizations = RouteQuery.FastestRoute routeModel.update(); // center the map on the start coord view.map.center = startCoordinate;
这就是在地图上显示路线所需的所有内容。然而,能够检索路线文本和出行路线说明也是有用的。在示例中,这些信息在ListView元素中显示。为了创建这个内容,我们使用标准的ListModel和ListView对。ListModel中的数据是从routeModel的输出中构建的
ListView { interactive: true model: ListModel { id: routeInfoModel } header: RouteListHeader {} delegate: RouteListDelegate{ routeIndex.text: index + 1 routeInstruction.text: instruction routeDistance.text: distance } }
如上图所示,在RouteModel内部,我们添加了一个onStatusChanged处理器,它调用showRouteList()
来更新routeInfoModel
routeInfoModel.clear() if (routeModel.count > 0) { for (var i = 0; i < routeModel.get(0).segments.length; i++) { routeInfoModel.append({ "instruction": routeModel.get(0).segments[i].maneuver.instructionText, "distance": Helper.formatDistance(routeModel.get(0).segments[i].maneuver.distanceToNextInstruction) }); } }
© 2024 The Qt Company Ltd. 本文档中的文档贡献是各自所有者的版权。本处提供的文档是根据自由软件基金会发布的GNU自由文档许可协议版本1.3的条款许可的。Qt及其相应标志是芬兰和/或世界其他地区的The Qt Company Ltd.的商标。所有其他商标均为各自所有者的财产。