1

I have came across a problem where I have to dynamically draw a polygon on QML Map using mouse and make its points movable so that user can change those points location. There is a very nice answer to a similar question which helped me to at least add some points/markers dynamically and connect them through lines but it doesn't allow the markers to be movable.

Can somebody please help me in this regard?

Shuji
  • 624
  • 1
  • 8
  • 24
  • 1
    1) My solution does not implement a polygon but a set of consecutive lines so I have the doubt Do you want a polygon or only the consecutive lines? 2) My solution uses markers but in your description of the problem you don't point out any markers. Do you need markers? – eyllanesc Feb 09 '20 at 21:11
  • 1) I want a polygon 2) I need movable markers. – Shuji Feb 09 '20 at 21:14
  • @eyllanesc Your answer on the following question is a bit helpful but still missing my requirements https://stackoverflow.com/questions/51428077/qml-mappolygon-from-c-model – Shuji Feb 09 '20 at 21:42

1 Answers1

3

In the following code a marker will be added with the right click and you can drag a marker with the right click.

The logic of adding is simple is to detect the right click of the mouse and obtain with that information the position by adding it to the model associated with the MapItemView that handles the markers and the MapPolygon points.

On the other hand, the logic of the drag is first to detect without a marker has been pressed so that a MouseArea attached to each marker is used obtaining the index of that element, disabling the "gesture" of the map. The MouseArea of the markers was configured so that they continue to propagate the mouse events to the other elements since the detection of the release must be done on the map, for this the positionChanged and Released signals are used with which the position of the marker is updated and restore the variables when necessary.

import QtQuick 2.14
import QtQuick.Window 2.14
import QtLocation 5.14
import QtPositioning 5.14

Window {
    visible: true
    width: 640
    height: 480
    property int currentIndex: -1
    ListModel{
        id: polygonmodel
    }
    Map {
        id: map
        anchors.fill: parent
        plugin: Plugin {
            name: "osm"
        }
        gesture.enabled: currentIndex == -1
        center: QtPositioning.coordinate(59.91, 10.75) // Oslo
        zoomLevel: 14
        MapItemView{
            z: polygon.z + 1
            model: polygonmodel
            delegate: MapQuickItem{
                anchorPoint: Qt.point(sourceItem.width/2, sourceItem.height/2)
                coordinate: QtPositioning.coordinate(model.coords.latitude, model.coords.longitude)
                sourceItem: Image {
                    width: 40
                    height: 40
                    source: "http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_red.png"
                    MouseArea{
                        anchors.fill: parent
                        acceptedButtons: Qt.LeftButton
                        propagateComposedEvents: true
                        onPressed: {
                            currentIndex = index
                            mouse.accepted = false
                        }
                    }
                }
            }
        }
        MapPolygon{
            id: polygon
            border.color: "green"
            border.width: 10
        }
        MouseArea{
            anchors.fill: parent
            acceptedButtons: Qt.LeftButton | Qt.RightButton
            onClicked: {
                var point = Qt.point(mouse.x, mouse.y)
                var coord = map.toCoordinate(point);
                if (mouse.button == Qt.RightButton)
                    addMarker(coord)
            }
            onPositionChanged: {
                if (currentIndex != -1){
                    var point = Qt.point(mouse.x, mouse.y)
                    var coord = map.toCoordinate(point);
                    if(coord.isValid)
                        moveMarker(currentIndex, coord)
                }
            }
            onReleased: {
                if (mouse.button == Qt.LeftButton && currentIndex != -1){
                    var point = Qt.point(mouse.x, mouse.y)
                    var coord = map.toCoordinate(point);
                    if(coord.isValid)
                        moveMarker(currentIndex, coord)
                    currentIndex = -1;
                }
            }
        }
    }
    function moveMarker(index, coordinate){
        polygonmodel.set(index, {"coords": coordinate})
        var path = polygon.path;
        path[index] = coordinate
        polygon.path = path
    }
    function addMarker(coordinate){
        polygonmodel.append({"coords": coordinate})
        polygon.addCoordinate(coordinate)
    }
}
eyllanesc
  • 235,170
  • 19
  • 170
  • 241