C
Qt Quick Ultralite map example
// Copyright (C) 2025 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial import QtQuick import QtPositioning import QtLocation Item { id: root property real zoomLevel: mapParameters.zoomLevel property real nextZoomLevel: root.zoomLevel + 1 property real prevZoomLevel: root.zoomLevel - 1 signal startDemoMode(bool paused) signal endDemoMode MapParameters { id: mapParameters } function zoom(zoomType: string) { if (zoomType === "In" && root.zoomLevel < map.maximumZoomLevel) { zoomInAnimation.stop() zoomInAnimation.start() } else if (zoomType === "Out" && root.zoomLevel > map.minimumZoomLevel) { zoomOutAnimation.stop() zoomOutAnimation.start() } } function incrementZoomLevel() { if (root.zoomLevel < map.maximumZoomLevel) root.zoomLevel += 1 } function decrementZoomLevel() { if (root.zoomLevel > map.minimumZoomLevel) root.zoomLevel -= 1 } function startDemo(paused: bool) { if (paused) { posSource.active = false demoStartPause.imageSource = "start-resume.png" demoStartPause.demoPaused = true return } // start/resume posSource.active = true demoStartPause.imageSource = "pause.png" demoStartPause.demoPaused = false demoStop.visible = true } function endDemo() { posSource.active = false IndexManager.setIndex(0) demoStartPause.imageSource = "start-resume.png" demoStartPause.demoPaused = true demoStop.visible = false } onStartDemoMode: startDemo(paused) onEndDemoMode: endDemo() PositionSource { id: posSource active: false updateInterval: 1000 onPositionChanged: { map.center.latitude = posSource.position.coordinate.latitude map.center.longitude = posSource.position.coordinate.longitude bearingAnimation.start() } onSourceErrorChanged: { if (sourceError === PositionSource.ClosedError) endDemo() } } Map { id: map anchors.fill: parent center { latitude: mapParameters.latitude longitude: mapParameters.longitude } bearing: mapParameters.bearing zoomLevel: root.zoomLevel minimumZoomLevel: mapParameters.minimumZoomLevel maximumZoomLevel: mapParameters.maximumZoomLevel MapMarker { id: currentLocation imageSource: "nav-arrow.png" latitude: posSource.position.coordinate.latitude longitude: posSource.position.coordinate.longitude visible: !mapParameters.showButtons } MapMarker { id: poiQt imageSource: "location-marker.png" markerText: "The Qt Company" latitude: 65.05877 longitude: 25.45545 visible: !mapParameters.showButtons } MapMarker { id: poiMarket imageSource: "location-marker.png" markerText: "Supermarket" latitude: 65.054274 longitude: 25.456213 visible: !mapParameters.showButtons } MapMarker { id: poiStation imageSource: "location-marker.png" markerText: "Gas Station" latitude: 65.055253 longitude: 25.456561 visible: !mapParameters.showButtons } MouseArea { id: mapPan anchors.fill: parent property real pressPointX: 0 property real pressPointY: 0 property real translationX: 0 property real translationY: 0 onPressed: { pressPointX = mouse.x pressPointY = mouse.y translationX = 0 translationY = 0 } onPositionChanged: { var x = mouse.x - pressPointX var y = mouse.y - pressPointY var deltaX = x - translationX var deltaY = y - translationY translationX = x translationY = y map.pan(-deltaX, -deltaY) } } MapButton { id: zoomIn visible: mapParameters.showButtons width: root.width / 10 height: width anchors.top: parent.top anchors.right: parent.right anchors.topMargin: 10 anchors.rightMargin: 10 imageSource: "plus.png" backgroundColor: "#e0e0e0" onButtonClicked: { if (zoomOutAnimation.running) { zoomOutAnimation.stop() } zoom("In") } } MapButton { id: zoomOut visible: mapParameters.showButtons width: root.width / 10 height: width anchors.top: zoomIn.bottom anchors.right: parent.right anchors.topMargin: 5 anchors.rightMargin: 10 imageSource: "minus.png" backgroundColor: "#e0e0e0" onButtonClicked: { if (zoomInAnimation.running) { zoomInAnimation.stop() } zoom("Out") } } MapButton { id: rotateRight visible: mapParameters.showButtons width: root.width / 10 height: width anchors.top: zoomOut.bottom anchors.right: parent.right anchors.topMargin: 5 anchors.rightMargin: 10 imageSource: "rotate-right.png" backgroundColor: "#e0e0e0" onButtonClicked: { map.bearing -= 5 } } MapButton { id: rotateLeft visible: mapParameters.showButtons width: root.width / 10 height: width anchors.top: zoomOut.bottom anchors.right: rotateRight.left anchors.topMargin: 5 anchors.rightMargin: 10 imageSource: "rotate-left.png" backgroundColor: "#e0e0e0" onButtonClicked: { map.bearing += 5 } } MapButton { id: demoStartPause property bool demoPaused: true width: root.width / 10 height: width anchors.top: parent.top anchors.right: zoomIn.left anchors.topMargin: 10 anchors.rightMargin: 10 imageSource: "start-resume.png" backgroundColor: "#e0e0e0" onButtonClicked: { startDemoMode(!demoPaused) } } MapButton { id: demoStop visible: false width: root.width / 10 height: width anchors.top: parent.top anchors.left: demoStartPause.right anchors.topMargin: 10 anchors.leftMargin: 10 imageSource: "stop.png" backgroundColor: "#e0e0e0" onButtonClicked: { endDemoMode() } onVisibleChanged: { if (visible) { // only on demo start not on resume mapParameters.showButtons = false root.zoomLevel = 17 map.minimumZoomLevel = 17 map.maximumZoomLevel = 17.9 demoZoomInTimer.start() } else { mapParameters.showButtons = true root.zoomLevel = mapParameters.zoomLevel map.minimumZoomLevel = mapParameters.minimumZoomLevel map.maximumZoomLevel = mapParameters.maximumZoomLevel map.bearing = mapParameters.bearing } } } CopyrightText { id: copyrighttxt anchors.bottom: parent.bottom anchors.right: parent.right copyrightText: "© OpenStreetMap contributors" backgroundColor: "#e0e0e0" } } PropertyAnimation { id: zoomInAnimation target: map property: "zoomLevel" from: root.zoomLevel to: root.nextZoomLevel running: false alwaysRunToEnd: false duration: 500 onStopped: incrementZoomLevel() } PropertyAnimation { id: zoomOutAnimation target: map property: "zoomLevel" from: root.zoomLevel to: root.prevZoomLevel running: false alwaysRunToEnd: false duration: 500 onStopped: decrementZoomLevel() } PropertyAnimation { id: bearingAnimation target: map property: "bearing" from: map.bearing to: posSource.position.direction running: true duration: 2000 } Timer { id: demoZoomInTimer interval: 2000 running: false repeat: false onTriggered: zoomInAnimation.start() } }