1
votes

I would like to display multiple MapPolygons. To structre it nicely, I would like to define the polygons in a separated file. After some googling around, I think an approach with ListView and ListModel could work.

So far I tried to define the complete MapPolygon inside the ListElement{}. This produced an error, that a ListElement{} can not contain any nested elements. So I defiend a viarable path and color in the ListElement{} and tried to delegate those to a MapPolygon. This produces the error: "ListElement: cannot use script for property value"

The ListView:

ListView {
        model: PolygonCoords {}
        delegate: MapPolygon {
            color: color
            path:   path
        }
    }

The ListModel, PolygonCoords.qml:

ListModel{
    ListElement{
            color: "blue"
            path: [ //very big
                {latitude: 47.30985701233802, longitude:  8.957498557565305},
                {latitude: 48.31223969058969, longitude:  12.959643094792634},
                {latitude: 50.31281785500094, longitude:  12.960823612887165},
                {latitude: 47.31281654102718, longitude:  8.962966471196324},
                {latitude: 47.30862993050194, longitude:  8.963243902017013},
                {latitude: 47.30863115391583, longitude:  8.963151349827395},
                {latitude: 47.30697209667029, longitude:  8.962058898768426},
                {latitude: 47.30985701233802, longitude:  8.957498557565305}
            ]
    }

    ListElement {
            color: "red"
            path: [ //very big
                {latitude: 45.30985701233802, longitude:  7.957498557565305},
                {latitude: 41.31223969058969, longitude:  11.959643094792634},
                {latitude: 54.31281785500094, longitude:  11.960823612887165},
                {latitude: 45.31281654102718, longitude:  7.962966471196324},
                {latitude: 45.30862993050194, longitude:  7.963243902017013},
                {latitude: 45.30863115391583, longitude:  7.963151349827395},
                {latitude: 45.30697209667029, longitude:  7.962058898768426},
                {latitude: 45.30985701233802, longitude:  7.957498557565305}
            ]
    }
}

How do I have to change my path-Variable that it is not read as a script and is the ListView even the right approach or is there a better option?

@Update Thanks to @folibis, I got it working with a Repeater as long the path and the repeater are in the same file as the map. Since the file with the map is already huge, I would like to move as much as possible in its own file.

I cannot begin a file with property var points, so I thought of using Item as a wrapper in PolygonCoords.qml:

Item {

 property var points: [
        {
                color: Qt.rgba(0, 80, 128, 0.5),
                path: [ //very big
                    {latitude: 47.30985701233802, longitude:  8.957498557565305},
                    {latitude: 48.31223969058969, longitude:  12.959643094792634},
                    {latitude: 50.31281785500094, longitude:  12.960823612887165},
                    {latitude: 47.31281654102718, longitude:  8.962966471196324},
                    {latitude: 47.30862993050194, longitude:  8.963243902017013},
                    {latitude: 47.30863115391583, longitude:  8.963151349827395},
                    {latitude: 47.30697209667029, longitude:  8.962058898768426},
                    {latitude: 47.30985701233802, longitude:  8.957498557565305}
                ]
        },
        {
               color: Qt.rgba(128, 80, 0, 0.5),
                path: [ //very big
                    {latitude: 45.30985701233802, longitude:  7.957498557565305},
                    {latitude: 41.31223969058969, longitude:  11.959643094792634},
                    {latitude: 54.31281785500094, longitude:  11.960823612887165},
                    {latitude: 45.31281654102718, longitude:  7.962966471196324},
                    {latitude: 45.30862993050194, longitude:  7.963243902017013},
                    {latitude: 45.30863115391583, longitude:  7.963151349827395},
                    {latitude: 45.30697209667029, longitude:  7.962058898768426},
                    {latitude: 45.30985701233802, longitude:  7.957498557565305}
                ]
        }
    ]
}

And then calling it like this:

Repeater {
        model: PolygonCoords.points
        MapPolygon {
            color:  Polygoncoords.points[index].color
            border {width: 2; color: "grey"}
            path:  PolygonCoords.points[index].path
        }
    }

Here I get no error, but the neither a MapPolygon on the map.

I also tried it with naming the Item with an id and calling it like this:

model: PolygonCoords.ItemID.points

But with this, I got the error: TypeError: Cannot read property points of undefined.

I further tried moving the repeater with the points together in another file and then just calling PolygonCoords. Again, no error and no MapPolygon:

Item {
 Repeater {
        model: PolygonCoords.points
        MapPolygon {
            color:  Polygoncoords.points[index].color
            border {width: 2; color: "grey"}
            path:  PolygonCoords.points[index].path
        }
    }

 property var points: [
        {
                color: Qt.rgba(0, 80, 128, 0.5),
                path: [ //very big
                    {latitude: 47.30985701233802, longitude:  8.957498557565305},
                    {latitude: 48.31223969058969, longitude:  12.959643094792634},
                    {latitude: 50.31281785500094, longitude:  12.960823612887165},
                    {latitude: 47.31281654102718, longitude:  8.962966471196324},
                    {latitude: 47.30862993050194, longitude:  8.963243902017013},
                    {latitude: 47.30863115391583, longitude:  8.963151349827395},
                    {latitude: 47.30697209667029, longitude:  8.962058898768426},
                    {latitude: 47.30985701233802, longitude:  8.957498557565305}
                ]
        },
        {
               color: Qt.rgba(128, 80, 0, 0.5),
                path: [ //very big
                    {latitude: 45.30985701233802, longitude:  7.957498557565305},
                    {latitude: 41.31223969058969, longitude:  11.959643094792634},
                    {latitude: 54.31281785500094, longitude:  11.960823612887165},
                    {latitude: 45.31281654102718, longitude:  7.962966471196324},
                    {latitude: 45.30862993050194, longitude:  7.963243902017013},
                    {latitude: 45.30863115391583, longitude:  7.963151349827395},
                    {latitude: 45.30697209667029, longitude:  7.962058898768426},
                    {latitude: 45.30985701233802, longitude:  7.957498557565305}
                ]
        }
    ]
}

And in the file with the map:

PolygonCoords {}

To make sure, I referenced PolygonCords right, I defined just a MapPolygon in it. This one was properly displayed on the map.

Any idea what I am missing?

1
Is your model modifiable or static (it won't be modified)? - GrecKo
@GrecKo for now it is static, i plan to use the hardcoded MapPolygons for a presentation - Geryones
ListElement can contain only simple values, like strings or numbers. See it here for more info. From 5.11 it accept also function so you can try to wrap your value ie. you can return path from a function. - folibis
@folibis Thank you for the clarification on that. I don't understand how I would return the path in a function. I still have to define the path for every Polygon? Do you have an example? - Geryones
You could not use custom item in this way. You should either create singleton (and so you will be able to use it as PolygonCoords.points) or create item ie PolygonCoords { id: poligonCoords } and so use it as poligonCoords.points - folibis

1 Answers

1
votes

Here is example to illustrate idea I was talking about. I've used Repeater instead of ListView since it is more suitable for your purpose I guess. The data array could be stored in a different javascript file.

import QtQuick 2.11
import QtQuick.Controls 2.4
import QtLocation 5.6
import QtPositioning 5.6

ApplicationWindow {
    id: mainWindow
    width: 800
    height: 600
    visible: true
    property var points: [
        {
            color: Qt.rgba(0, 80, 128, 0.5),
            path: [
                {latitude:59.91288302222718, longitude:10.728799819940349},
                {latitude:59.91821810440818, longitude:10.737211227411649},
                {latitude:59.912323649434825, longitude:10.754119873037723},
                {latitude:59.90961270928307, longitude:10.764762878423767},
                {latitude:59.90165073245826, longitude:10.759441375730745},
                {latitude:59.908364741793115, longitude:10.748540878294307},
                {latitude:59.9010050830971, longitude:10.741846084608},
                {latitude:59.910387286199025, longitude:10.731632232668204},
            ]
        },
        {
            color: Qt.rgba(128, 80, 0, 0.5),
            path: [
                {latitude:59.92101437751683, longitude:10.77077102661346},
                {latitude:59.920842305970744, longitude:10.772916793815767},
                {latitude:59.9168413910999, longitude:10.772830963132293},
                {latitude:59.915206469874626, longitude:10.769741058354015},
                {latitude:59.91787393143297, longitude:10.765792846683212},
            ]
        }
    ]

    Map {
        id: map
        anchors.fill: parent
        plugin: Plugin { id: mapPlugin; name: "esri" }
        center: QtPositioning.coordinate(59.91, 10.75)
        zoomLevel: 14
        MouseArea {
            anchors.fill: parent
            onPressed: {
                var coord = map.toCoordinate(Qt.point(mouse.x,mouse.y));
                console.log(coord.latitude, coord.longitude);
            }
        }
        Repeater {
            model: points
            MapPolygon {
                color: points[index].color
                border{ width: 1; color: "grey" }
                path: points[index].path
            }
        }
    }
}