Dynamic Polyline in Qt Location/Map



  • Hello,

    I want to create an application which allow me to draw polyline when I click two points somewhere on the map. Something like googlemap.

    I managed to draw one polyline, but how to create more than one polyline?
    main.qml

    import QtQuick 2.6
    import QtQuick.Window 2.2
    import "componentCreation.js" as MyScript
    import QtQuick.Controls 2.1
    import QtLocation 5.3
    import QtPositioning 5.2
    
    Window {
        id: appWindow
        width: 512
        height: 512
        visible: true
        Map {
            id: map
            //width: win.width - kolom.width - row1.spacing
            anchors.fill: parent
            activeMapType: map.supportedMapTypes[2]
            zoomLevel: 1
            //z:1
    
    
            center {
                latitude: 5
                longitude: 100
            }
            plugin: Plugin {
                name: 'osm';
                PluginParameter {
                    name: 'osm.mapping.offline.directory';
                    value: ':/offline_tiles/'
                }
            }
            MapCircle {
                radius: 800000
                color: 'blue'
                center {
                    latitude: 5
                    longitude: 100
                }
            }
    
            MouseArea {
                anchors.fill: parent
                onPressed: {
                    var coord = map.toCoordinate(Qt.point(mouse.x,mouse.y))
                    console.log("coordinate: " + coord)
    
                    //MyScript.createSpriteObjects(map.toCoordinate(Qt.point(mouse.x,mouse.y)).latitude,map.toCoordinate(Qt.point(mouse.x,mouse.y)).longitude)
                    MyScript.createSpriteObjects(mouse.x,mouse.y)
    
                }
            }
        }
    
    
    }
    
    

    componentCreation.js

    var component
    var sprite
    
    function createSpriteObjects(posX,posY) {
        component = Qt.createComponent("Sprite.qml");
        if (component.status == Component.Ready)
            finishCreation(posX,posY);
        else
            component.statusChanged.connect(finishCreation);
    
    }
    
    function finishCreation(posX,posY) {
        if (component.status == Component.Ready) {
            //sprite = component.createObject(map, {"marker.coordinate": map.toCoordinate(Qt.point(posX,posY))});
            sprite = component.createObject(map);
            console.log("Object Created " + map.toCoordinate(Qt.point(posX,posY)));
            //sprite = component.createObject(appWindow);
            if (sprite == null) {
                console.log("Error creating Object");
            }
        }
        else if (component.status == Component.Error) {
            console.log("Error loading component:", component.errorString());
        }
    }
    
    

    Sprite.qml

    import QtQuick 2.0
    import QtLocation 5.3
    
    
    MapQuickItem {
        id: marker
        sourceItem: Image {
            id: image
            source: "marker.png"
        }
        coordinate {
            latitude: 5
            longitude: 100
        }
        anchorPoint.x: image.width / 2
        anchorPoint.y: image.height / 2
        visible: true
    }
    
    /*Rectangle {
        width: 100
        height: 20
        x: 10
        y:10
    }*/
    
    

  • Moderators

    @mkhtrmn

    Probably you need to show the source code.

    Crystall ball reading tells me that you are deleting or refreshing some view while preparing for the next polyline.



  • @mkhtrmn

    Try the following:
    QVector<QLineF> polyPath;
    polyPath.append(QLineF(p1p, p1));
    p.drawLines(polyPath);

    The first line creates a container for the line segments; the second add the line segments to the container; and the third draws the segments. You can add as many polylines as required, since they are treated as individual line segments.



  • @ofmrew said in Dynamic Polyline in Qt Location/Map:

    @mkhtrmn

    Try the following:
    QVector<QLineF> polyPath;
    polyPath.append(QLineF(p1p, p1));
    p.drawLines(polyPath);

    The first line creates a container for the line segments; the second add the line segments to the container; and the third draws the segments. You can add as many polylines as required, since they are treated as individual line segments.

    Thanks for the recommendation. Actually, I am working on QML and I use MapPolyline to draw on the map.

    I have made a progress, I can create a rectangle dynamicaly using QML dynamic object creation. But, when I tried to draw a MapQuickItem or MapCircle it shows nothing.

    *I have updated my post with my code



  • @koahnig I have updated my post by adding the source code


  • Moderators

    @mkhtrmn

    Sorry, QML is not my field of expertize at all.

    My guess is that you are displaying something with a local instance and therefore, it is vanishing for the next trial. However, with QML there is no chance that I can help.

    I will move your post to QML forum.



  • So, this post is old relatively. However, it is marked as UNSOLVED. Anyway, there is someone that can be helpful.

    This is the funcionality asked: dynamic polyline with two modes. One mode is continous polilyne, the other is an array of single lines. The code speak by itself.

    main.qml

    ApplicationWindow {
        id: applicationWindow
        visible: true
        width: 640
        height: 480
    
        // This property indicates the mode, if changeMode=0 is a polyline,
        // if changeMode=OtherNumber is an array or single lines
        property int changeMode: 1
    
        Plugin {
            id: osmMapPlugin
            name: "osm"
        }
    
        Map {
            id: themap
            anchors.fill: parent
            zoomLevel: 12
            plugin: osmMapPlugin
            center: QtPositioning.coordinate(-34.171634, -70.734406)
        }
    
        MouseArea{
            anchors.fill: parent
            z:1
            onClicked: {
                MyScript.createElements(Qt.point(mouse.x,mouse.y))
            }
        }
    }
    

    Line.qml

    MapPolyline {
    
        property alias mainPolyline: mainPolyline
    
        id: mainPolyline
        line.width: 3
        line.color: 'blue'
    }
    

    Marker.qml

    MapQuickItem {
    
        property alias marker: marker
    
        id: marker
        sourceItem: Rectangle {
            width: 10
            height: 10
            color: "red"
            smooth: true
            radius: 15
        }
        opacity: 1.0
        anchorPoint: Qt.point(sourceItem.width/2, sourceItem.height/2)
    }
    

    componentCreation.js (import as MyScript)

    var arrayLines=[]
    var lineComplete=false
    
    function createElements(point) {
    
        var componentMarker = Qt.createComponent("Marker.qml");
    
        if (componentMarker.status === Component.Ready) {
            var markerFirstCorner = componentMarker.createObject(themap);
            markerFirstCorner.coordinate = themap.toCoordinate(point)
    
            themap.addMapItem(markerFirstCorner)
        }else{
            console.log("Marker not created")
        }
    
        var theLine
    
        if(changeMode===0){
    
            //Polyline mode
            if(arrayLines.length===0){
                createLine(point)
            }else{
                theLine = arrayLines[arrayLines.length-1]
    
                theLine.mainPolyline.addCoordinate(themap.toCoordinate(point))
            }
    
        }else{
            //Array of lines
    
            if(arrayLines.length===0 || !lineComplete){
                createLine(point)
                lineComplete=true
            }else{
                theLine = arrayLines[arrayLines.length-1]
    
                theLine.mainPolyline.addCoordinate(themap.toCoordinate(point))
    
                lineComplete=false
            }
        }
    }
    
    function createLine(point){
    
        var componentLine = Qt.createComponent("Line.qml")
    
        if (componentLine.status === Component.Ready) {
            var lineFirstCorner = componentLine.createObject(themap);
            lineFirstCorner.mainPolyline.addCoordinate(themap.toCoordinate(point))
    
            themap.addMapItem(lineFirstCorner)
            arrayLines.push(lineFirstCorner)
        }else{
            console.log("Line not created")
        }
    }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.