QML Maps with Pinch Zoom

From Qt Wiki
Revision as of 09:48, 25 February 2015 by Maintenance script (talk | contribs)
Jump to navigation Jump to search


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":http://doc.qt.nokia.com/4.7-snapshot/qml-pincharea.html element which was introduced in Qt Quick 1.1.

I hope you find this helpful!

import QtQuick 1.1
import QtMobility.location 1.2

Rectangle {
 id: pinchmap

property double defaultLatitude: 37.69
 property double defaultLongitude: 97.33
 property int defaultZoomLevel: 7

property alias mapType: map.mapType

width: 640
 height: 350

Map {
 id: map

anchors.fill: parent
 zoomLevel: pinchmap.defaultZoomLevel
 plugin: Plugin { name: "nokia" }
 mapType: Map.StreetMap

center: Coordinate {
 latitude: pinchmap.defaultLatitude
 longitude: pinchmap.defaultLongitude
 }
 }

PinchArea {
 id: pincharea

property double _''oldZoom

 anchors.fill: parent

 function calcZoomDelta(zoom, percent) {
 return zoom + Math.log(percent)/Math.log(2)
 }

 onPinchStarted: {
oldZoom = map.zoomLevel
 }

 onPinchUpdated: {
 map.zoomLevel = calcZoomDelta(oldZoom, pinch.scale)
 }

 onPinchFinished: {
 map.zoomLevel = calcZoomDelta(oldZoom, pinch.scale)
 }
 }

 MouseArea {
 id: mousearea

 property boolisPanning: false
 property intlastX: 1
 property intlastY: 1

 anchors.fill : parent

 onPressed: {
isPanning = true
lastX = mouse.x
lastY = mouse.y
 }

 onReleased: {
isPanning = false
 }

 onPositionChanged: {
 if (isPanning) {
 var dx = mouse.x -lastX
 var dy = mouse.y -lastY
 map.pan(-dx, -dy)
lastX = mouse.x
lastY = mouse.y
 }
 }

 onCanceled: {
''_isPanning = false;
 }
 }
}