English | Български

QML Map using PinchArea to zoom and MouseArea to pan

Qt Mobility’s Location plugin provides a very nice QML Map item, but currently leaves navigation up to the developer to implement. Two common navigation methods are using a swipe gesture to pan the map around and using a pinch gesture to zoom in and out.

Having not found any solid examples of how to do these two things together, I thought I would post an example of some code which implement these two features. The code uses the PinchArea [doc.qt.nokia.com] element which was introduced in Qt Quick 1.1.

I hope you find this helpful!

  1. import QtQuick 1.1
  2. import QtMobility.location 1.2
  3.  
  4. Rectangle {
  5.    id: pinchmap
  6.  
  7.    property double defaultLatitude: 37.69
  8.    property double defaultLongitude: -97.33
  9.    property int  defaultZoomLevel: 7
  10.  
  11.    property alias mapType: map.mapType
  12.  
  13.    width: 640
  14.    height: 350
  15.  
  16.    Map {
  17.       id: map
  18.  
  19.       anchors.fill: parent
  20.       zoomLevel: pinchmap.defaultZoomLevel
  21.       plugin: Plugin { name: "nokia" }
  22.       mapType: Map.StreetMap
  23.  
  24.       center: Coordinate {
  25.          latitude: pinchmap.defaultLatitude
  26.          longitude: pinchmap.defaultLongitude
  27.       }
  28.    }
  29.  
  30.    PinchArea {
  31.       id: pincharea
  32.  
  33.       property double __oldZoom
  34.  
  35.       anchors.fill: parent
  36.  
  37.       function calcZoomDelta(zoom, percent) {
  38.          return zoom + Math.log(percent)/Math.log(2)
  39.       }
  40.  
  41.       onPinchStarted: {
  42.          __oldZoom = map.zoomLevel
  43.       }
  44.  
  45.       onPinchUpdated: {
  46.          map.zoomLevel = calcZoomDelta(__oldZoom, pinch.scale)
  47.       }
  48.  
  49.       onPinchFinished: {
  50.          map.zoomLevel = calcZoomDelta(__oldZoom, pinch.scale)
  51.       }
  52.    }
  53.  
  54.    MouseArea {
  55.       id: mousearea
  56.  
  57.       property bool __isPanning: false
  58.       property int __lastX: -1
  59.       property int __lastY: -1
  60.  
  61.       anchors.fill : parent
  62.  
  63.       onPressed: {
  64.          __isPanning = true
  65.          __lastX = mouse.x
  66.          __lastY = mouse.y
  67.       }
  68.  
  69.       onReleased: {
  70.          __isPanning = false
  71.       }
  72.  
  73.       onPositionChanged: {
  74.          if (__isPanning) {
  75.             var dx = mouse.x - __lastX
  76.             var dy = mouse.y - __lastY
  77.             map.pan(-dx, -dy)
  78.             __lastX = mouse.x
  79.             __lastY = mouse.y
  80.          }
  81.       }
  82.  
  83.       onCanceled: {
  84.          __isPanning = false;
  85.       }
  86.    }
  87. }

Categories: