QML Maps

概述

The Map type allows the display of a map and placing objects within the map. Various points of interest can be defined and added to the map for display. Also the Map has features to control how the map is displayed. With the Map item you can center the map, zoom, pinch and make the item flickable.

The places to be added to the map are MapItems . The item's position is defined by a coordinate which includes latitude, longitude and altitude. The item is then displayed automatically after it is added to the Map .

Position on map

All position APIs are part of the QtPositioning module. The basic piece of position information is the coordinate . A coordinate encapsulates data for the latitude, longitude and altitude of the location. Altitude is in meters. It also has a method to determine distance to another coordinate coordinate type may also be held within a 定位 element, this will also have information on a bounding box size to determine sufficient proximity to the location and a location address.

Here is an example of a client that uses a position source to center a map on the current position:

import QtPositioning 5.2
import QtLocation 5.3
...
Rectangle {
    Map {
        id: map
        // initialize map
        ...
    }
    PositionSource {
        onPositionChanged: {
            // center the map on the current position
            map.center = position.coordinate
        }
    }
}
					

Geocoding

Geocoding is the derivation of geographical coordinates (latitude and longitude) from other geographical references to the locations. For example, this can be a street address. Reverse geocoding is also possible with a street address being used to determine a geographical coordinate. Geocoding is performed by using the GeocodeModel 类型。

The following code examples are a small part of the map component in the 地图查看器 (QML) example. The snippets demonstrate the declaration of the GeocodeModel 组件。

In the snippet we see that the [QML]{ GeocodeModel } contains the plugin and two signal handlers. One for changes in status onStatusChanged and the other to update the centering of the Map object onLocationsChanged .

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
        }
    }
}
MapItemView {
    parent: view.map
    model: geocodeModel
    delegate: pointDelegate
}
					

The geocoding features are called from a higher level piece of code. In this snippet we see an 地址 object filled with the desired parameters.

Address {
    id :fromAddress
    street: "Sandakerveien 116"
    city: "Oslo"
    country: "Norway"
    state : ""
    postalCode: "0484"
}
					

The 地址 is later used in a query for the GeocodeModel to process and determine the geographical coordinates .

// send the geocode request
geocodeModel.query = fromAddress
geocodeModel.update()
					

A very important function of the Map type is navigation from one place to a destination with possible waypoints along the route. The route will be divided up into a series of segments. At the end of each segment is a vertex called a maneuver segments contain information about the time and distance to the end of the segment. The maneuvers contain information about what to do next, how to get onto the next segment, if there is one. So a maneuver contains navigational information, for example "turn right now".

To find a suitable route we will need to use a RouteQuery to define the selection criteria and adding any required waypoints. The RouteModel should return a list of routeSegment s that defines the route to the destination complete with navigation advice at the joins between segments, called routeManeuver s

There are many options that you can add to the query to narrow the criteria. The RouteQuery properties can include

numberAlternativeRoutes The number of alternative routes
travelModes Travel modes
routeOptimizations Required route optimizations
segmentDetail Level of detail in segments
maneuverDetail Level of detail in maneuvers between segments
waypoints A list of waypoints
excludedAreas A list of excluded areas that the route must not cross
featureTypes Relevant map features, for example highway, ferry

In the following example a default RouteQuery is declared within 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()
        }
    }
}
					

The user enters some information such as the starting point of the route, some waypoints and the destination. All of these locations are waypoints so the locations from start to finish will be entered as a sequence of waypoints. Then other query properties can be set that may be specific to this trip.

// 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();
					

The routeInfoModel ListModel is used to grab the results of the query and construct a suitable list for display.

ListView {
    interactive: true
    model: ListModel { id: routeInfoModel }
    header: RouteListHeader {}
    delegate:  RouteListDelegate{
        routeIndex.text: index + 1
        routeInstruction.text: instruction
        routeDistance.text: distance
    }
}
					

The ListModel routeInfoModel can be filled with values using a code, that loops through the segments extracting the segment length, instruction text and distance to the next instruction. The extracted data is formatted for display as it is retrieved.

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)
        });
    }
}
					

For more information on the example see the 地图查看器 (QML) 范例。

Zoom, Pinch and Flickable

The Map item also supports user interface interactions with the map using tactile and mouse gestures. That is features such as swiping to pan, pinching to zoom.

Enabling and configuring pinch and flickable is easy within the MapView 类型。

MapView {
    id: view
TapHandler {
    id: tapHandler
    property variant lastCoordinate
    acceptedButtons: Qt.LeftButton | Qt.RightButton
    onPressedChanged: (eventPoint, button) => {
        if (pressed) {
            lastCoordinate = view.map.toCoordinate(tapHandler.point.position)
        }
    }
    onSingleTapped: (eventPoint, button) => {
            if (button === Qt.RightButton) {
                showMainMenu(lastCoordinate)
            }
    }
    onDoubleTapped: (eventPoint, button) => {
        var preZoomPoint = view.map.toCoordinate(eventPoint.position);
        if (button === Qt.LeftButton) {
            view.map.zoomLevel = Math.floor(view.map.zoomLevel + 1)
        } else if (button === Qt.RightButton) {
            view.map.zoomLevel = Math.floor(view.map.zoomLevel - 1)
        }
        var postZoomPoint = view.map.toCoordinate(eventPoint.position);
        var dx = postZoomPoint.latitude - preZoomPoint.latitude;
        var dy = postZoomPoint.longitude - preZoomPoint.longitude;
        view.map.center = QtPositioning.coordinate(view.map.center.latitude - dx,
                                                   view.map.center.longitude - dy);
    }
}
}
					

Zoom can also be controlled by other objects like sliders, with binding to the Map zoomLevel .

QML 类型

映射

Map Type displays a map
MapCircle Type displays a geographic circle on a Map
MapCopyrightNotice Item displays the current valid copyright notice for a Map element
MapItemGroup Type is a container for map items
MapItemView Used to populate Map from a model
MapPolygon Type displays a polygon on a Map
MapPolyline Type displays a polyline on a map
MapQuickItem Type displays an arbitrary Qt Quick object on a Map
MapRectangle Type displays a rectangle on a Map
MapRoute Type displays a Route on a Map
cameraCapabilities Type holds information about the camera capabilities for a specific map type
mapType Type holds information about a map type

Geocoding

GeocodeModel Type provides support for searching operations related to geographic information

Routing

RouteModel Type provides access to routes
RouteQuery Type is used to provide query parameters to a RouteModel
route Type represents one geographical route
routeManeuver Type represents the information relevant to the point at which two routeSegments meet
routeSegment Type represents a segment of a Route

范例

The above snippets are taken from the 地图查看器 (QML) 范例。