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

Rectangle {
    id: root

    property real zoomLevel: 3
    property real nextZoomLevel: zoomLevel + 1
    property real prevZoomLevel: zoomLevel - 1

    function zoom(zoomType: string) {
        if (zoomType === "In" && zoomLevel < map.maximumZoomLevel) {
            zoomInAnimation.stop()
            zoomInAnimation.start()
        } else if (zoomType === "Out" && 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
    }

    Map {
        id: map

        anchors.fill: parent
        center {
            latitude: 65.044334
            longitude: 25.692558
        }
        zoomLevel: root.zoomLevel
        minimumZoomLevel: 0
        maximumZoomLevel: 3

        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

            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

            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

            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

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

        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()
    }
}