Example of displaying location data and a map in your application
The following example illustrates how to access the Nokia Maps plugin from your application and enable your application to show the current location of the device on the map. In addition, the application enables users to zoom and pan the map on the Harmattan device.
In the example, the location and map functionalities are implemented in a QML file as follows:
- The QML file starts with import statements for Qt Quick 1.1, com.nokia.meego 1.0, and Qt Mobility 1.2 Location API.
- The Page component contains the Map element.
- The PositionSource::stop method stops updates from the location source (in this example, the global positioning system), when the application is terminated.
- The Connections element defines that position updates stop when the application is in the background.
- The Map object and the associated plugin element enable the map functionality. In this example, the plugin name "nokia" defines that the application uses the Nokia Maps plugin (included in Qt Mobility). The following properties are also used:
- The center property defines the central point for the displayed portion of the map. In this example, the application shows the current location of the device as the central point.
- The mapType property defines which type of map is displayed. In this example, the application shows a 2D street map.
- The zoomLevel property defines the zoom level for the map.
- The MapImage object defines the icon that shows the user's current location on the map. The following properties are also used:
- The source property defines the directory in which the icon is stored. Note that a direct reference to an icon present in the device's theme is not possible when a MapImage is used, hence a separate file is used.
- The coordinate property sets the icon to show the current location on the map.
- The offset.x and offset.y properties define how many pixels the icon is moved away from the on-screen position of the coordinate.
- Note: You must adjust the offset values in the example according to the shape and size of the icon.
- The PinchArea element enables the user to zoom in and out of the map view.
- The MouseArea element enables the user to:
- Navigate on the map by panning the touch screen.
- Zoom in the map view by double-tapping the touch screen.
- The PositionSource element provides access to the positioning information. In this example, the default location source (the GPS) is used.
- The updateInterval property defines how often the application fetches location data from the location source. In this example, the interval between updates is 10000 milliseconds.
For more information, see the code comments in the following section.
Creating the example application
To use the Location API and the Nokia Maps plugin in an example application:
- 1. Create a new project and select Qt Quick Components for MeeGo/Harmattan as the application type.
- 2. Add the following lines into your application's project file:
- CONFIG += mobility
- MOBILITY += location
- 3. Create an icons directory under the qml directory (where the source code resides).
- 4. Create an icon for the example application. In the following example, the size of the icon is 48 x 48.
- 5. Save the icon in the icons directory.
- 6. Edit MainPage.qml to access location service and display the location of the device on the map. Add the following code to the file:
import QtQuick 1.1 import com.nokia.meego 1.0 import QtMobility.location 1.2 /*! * @brief Includes sample code for QtMobility Location and Map demo * Show map with current position displaying coordinates. */ Page { id: mainPage property string latitudeStr: "RESOLVING" property string longitudeStr: "RESOLVING" property Coordinate currentCoord //! Used to indicate if device is in portrait mode property bool isPortrait: (screen.currentOrientation===Screen.Landscape) ? false : true //! Using common toolbar defined in main/qml/main.qml tools: commonTools //! We stop retrieving position information when component is to be destroyed Component.onDestruction: positionSource.stop(); //! Check if application is active, stop position updates if not Connections { target: Qt.application onActiveChanged: { if (Qt.application.active) positionSource.start(); else positionSource.stop(); } } //! Container for map element Rectangle { id : mapview height: parent.height width: parent.width //! Map element centered with current position Map { id: map plugin : Plugin { name : "nokia"; //! Location requires usage of app_id and token parameters. //! Values below are for testing purposes only, please obtain real values. //! Go to https://api.developer.nokia.com/ovi-api/ui/registration?action=list. parameters: [ PluginParameter { name: "app_id"; value: "APPID" }, PluginParameter { name: "token"; value: "TOKEN" } ] } anchors.fill: parent size { width: parent.width; height: parent.height } center: positionSource.position.coordinate mapType: Map.StreetMap zoomLevel: map.maximumZoomLevel - 1 //! Icon to display the current position MapImage { id: mapPlacer source: "icons/icon-m-common-location-selected.png" coordinate: positionSource.position.coordinate /*! * We want that bottom middle edge of icon points to the location, so using offset parameter * to change the on-screen position from coordinate. Values are calculated based on icon size, * in our case icon is 48x48. */ offset.x: -24 offset.y: -48 } } //! Panning and pinch implementation on the maps PinchArea { id: pincharea //! Holds previous zoom level value property double __oldZoom anchors.fill: parent //! Calculate zoom level function calcZoomDelta(zoom, percent) { return zoom + Math.log(percent)/Math.log(2) } //! Save previous zoom level when pinch gesture started onPinchStarted: { __oldZoom = map.zoomLevel } //! Update map's zoom level when pinch is updating onPinchUpdated: { map.zoomLevel = calcZoomDelta(__oldZoom, pinch.scale) } //! Update map's zoom level when pinch is finished onPinchFinished: { map.zoomLevel = calcZoomDelta(__oldZoom, pinch.scale) } } //! Map's mouse area for implementation of panning in the map and zoom on double click MouseArea { id: mousearea //! Property used to indicate if panning the map property bool __isPanning: false //! Last pressed X and Y position property int __lastX: -1 property int __lastY: -1 anchors.fill : parent //! When pressed, indicate that panning has been started and update saved X and Y values onPressed: { __isPanning = true __lastX = mouse.x __lastY = mouse.y } //! When released, indicate that panning has finished onReleased: { __isPanning = false } //! Move the map when panning onPositionChanged: { if (__isPanning) { var dx = mouse.x - __lastX var dy = mouse.y - __lastY map.pan(-dx, -dy) __lastX = mouse.x __lastY = mouse.y } } //! When canceled, indicate that panning has finished onCanceled: { __isPanning = false; } //! Zoom one level when double clicked onDoubleClicked: { map.center = map.toCoordinate(Qt.point(__lastX,__lastY)) map.zoomLevel += 1 } } } //! Source for retrieving the positioning information PositionSource { id: positionSource //! Desired interval between updates in milliseconds updateInterval: 10000 active: true //! When position changed, update the location strings onPositionChanged: { updateGeoInfo() } } function updateGeoInfo() { currentCoord = positionSource.position.coordinate latitudeStr = currentCoord.latitude longitudeStr = currentCoord.longitude } Column { anchors { bottom: parent.bottom; bottomMargin: 32; left: parent.left; leftMargin: 16 } spacing: 16 Rectangle { id: longRect color: "#FFFFFF" height: 36 width: 330 Label { id: longLabel anchors { fill: parent; margins: 5 } font { family: "Nokia Pure Text"; weight: Font.Light; pixelSize: 24 } text: "Longitude: " + longitudeStr + "." } } Rectangle { id: latRect color: "#FFFFFF" height: 36 width: 330 Label { id: latLabel anchors { fill: parent; margins: 5 } font { family: "Nokia Pure Text"; weight: Font.Light; pixelSize: 24 } text: "Latitude: " + latitudeStr + "." } } } }
The final example application displays the device's location on a map, as illustrated in the following figure.