QML动态地图对象创建

时间:2017-07-06 08:45:44

标签: javascript qt qml

我正在尝试构建交互式地图应用程序,这将允许我在地图上的某个位置单击时创建对象。我使用QML Dynamic Object Creation来创建对象。我成功创建了一个矩形(仍然有坐标问题),但是当我用MapQuickItem或MapCircle更改矩形时,它什么都没有显示。

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

1 个答案:

答案 0 :(得分:2)

MapQuickItemMapCircle不是Item,它们属于MapItem类型。 仅将Map设置为其父级并不足以在Map中显示它们。

您还需要致电addMapItem

sprite = component.createObject(map);
map.addMapItem(sprite);

还有其他方法可以动态创建QML对象,我相信它们更好,因为它涉及较少的命令式javascript并且更具可读性。

第一个是使用声明性创建的Component(您可以直接在main.qml中执行):

Component {
    id: mapCircleComponent
    MapCircle { //instead of defining it inline, you can also set the source property to point to another file
        radius: 80000
        color: 'blue'
    }
}

MouseArea {
    anchors.fill: parent
    onClicked: {
        var coord = map.toCoordinate(Qt.point(mouse.x,mouse.y))
        var circle = mapCircleComponent.createObject(map, {"center.latitude" : coord.latitude, "center.longitude": coord.longitude});
        map.addMapItem(circle);
    }
}

另一种方法是使用model and views来完成它,这是我最喜欢的,因为你没有直接处理组件和对象的实例化。

由于我们未在此处理Item,因此通常的ListViewRepeater将不起作用。我们需要使用MapItemView

ListModel {
    id: mapModel
}

Map {
    id: map
    //...
    MapItemView {
        model: mapModel
        delegate: MapCircle {
            radius: 80000
            color: 'blue'
            center {
                latitude: lat
                longitude: longi
            }
        }
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            var coord = map.toCoordinate(Qt.point(mouse.x,mouse.y))
            mapModel.append({lat : coord.latitude, longi: coord.longitude});
        }
    }
}

onClicked中,我们只是向模型添加一行,MapItemView会自动为每行MapCircle实例化,并将其添加到Map