Andrei R.
Andrei R.

Reputation: 2452

QtQuick: dragging MapQuickItem on a Map

I want to achieve self-draggable MapQuickItem. Simple example:

MapQuickItem {
    id: markerItem

    sourceItem: Rectangle {
        id: sourceRect
        color: "red"
        width: 20
        height: 20
        x: 0
        y: 0

        MouseArea {
            drag.target: markerItem
            cursorShape: drag.active ? Qt.ClosedHandCursor : Qt.OpenHandCursor
            anchors.fill: parent
        }
    }
    Drag.active: true
}

The point is, if I drag fast, dragging is interrupted as soon as cursor leaves marker. Is there a way to make it work properly?

Upvotes: 1

Views: 1575

Answers (2)

Recai Sinekli
Recai Sinekli

Reputation: 26

Here is an up to date solution for dynamically populated map.

import QtQuick
import QtLocation
import QtPositioning

Rectangle {
    anchors.fill: parent
    id: mapRectangle

    Map {
        id: map
        anchors.fill: parent
        center: QtPositioning.coordinate(40.021468, 26.194329)
        zoomLevel: 14
        copyrightsVisible: false

        plugin:   Plugin {
            id: mapPlugin
            name: "osm"
            PluginParameter {name: "osm.mapping.providersrepository.disabled";value:true}
        }

        DragHandler{
            id: drag
            target: null
            onTranslationChanged: (delta) => map.pan(-delta.x, -delta.y)
        }
        WheelHandler{
            id: wheel
            rotationScale: 1/100
            property: "zoomLevel"
        }

        MapItemView{
            model: ListModel{
                id: pinPointModel
            }
            delegate: pinPointComponent
        }
    }

    Component{
        id: pinPointComponent
        MapQuickItem{
            coordinate: QtPositioning.coordinate(latitude, longitude)
            id:marker
            anchorPoint.x: image.width/2
            anchorPoint.y: image.height

            sourceItem:Rectangle{
                id: image
                width: 50
                height: 50
                color: "red"
            }
            TapHandler{
                id: tapHandler
                acceptedButtons: Qt.RightButton
                gesturePolicy: TapHandler.WithinBounds
                onTapped: {
                    console.log(marker.coordinate.latitude+", "+marker.coordinate.longitude)
                }
            }

            DragHandler{
                id: dragHandler
                grabPermissions: PointHandler.CanTakeOverFromItems | PointHandler.CanTakeOverFromHandlersOfDifferentType
            }
        }
    }

    MouseArea{
        anchors.fill: parent
        onPressAndHold: {
            var crd = map.toCoordinate(Qt.point(mouseX, mouseY))
            pinPointModel.append({"latitude": crd.latitude, "longitude": crd.longitude})
        }
    }
}

Upvotes: 0

Andrei R.
Andrei R.

Reputation: 2452

I have found a workaround: using separate draggable QQuickItem and an anchor MapQuickItem:

MapQuickItem {
    id: anchor
    sourceItem: Item {}
}

Rectangle {
    id: handle

    property bool dragged: mouseArea.drag.active

    color: "red"
    width: 20
    height: 20
    x: anchor.x - width
    y: anchor.y - height

    MouseArea {
        id: mouseArea
        enabled: draggable
        drag.target: handle
        drag.threshold: 0
        anchors.fill: parent
        cursorShape: dragged ? Qt.ClosedHandCursor : Qt.OpenHandCursor
    }

    Connections {
        target: anchor
        onXChanged: if (!dragged) x = anchor.x - width
        onYChanged: if (!dragged) y = anchor.y - height
    }

    onXChanged: if (dragged) anchor.x = x + width
    onYChanged: if (dragged) anchor.y = y + height

    Drag.active: true
}

It's not super convenient with dynamically populated QML Map, but does the job

Upvotes: 1

Related Questions