MeeGo 1.2 Harmattan Developer Documentation Develop for the Nokia N9

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.

Example of displaying a map