QML 动态映射对象创建



我正在尝试构建交互式地图应用程序,当我单击地图上的某处时,该应用程序将允许我创建一个对象。我使用 QML 动态对象创建来创建对象。我已经成功地创建了一个矩形(仍然存在坐标问题(,但是当我使用MapQuickItem或MapCircle更改矩形时,它什么也没显示。

主.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)
}
}
}
}

组件创建.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());
}
}

雪碧.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
}*/

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

另一种方法是使用模型和视图来做到这一点,这是我最喜欢的,因为您不直接处理组件和对象实例化。

由于我们在这里不处理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中。

最新更新