QML Maps with Pinch Zoom

From Qt Wiki
Jump to: navigation, search
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

En Ar Bg De El Es Fa Fi Fr Hi Hu It Ja Kn Ko Ms Nl Pl Pt Ru Sq Th Tr Uk Zh

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