0

I seek for introduce a condition in a delegate.

Here is a simplified main.qml

import QtQuick 2.6
import QtQuick.Window 2.2
import QtPositioning 5.5
import QtLocation 5.6

Window {
    width: 1440
    height: 900
    visible: true

    property variant topLeftEurope: QtPositioning.coordinate(60.5, 0.0)
    property variant bottomRightEurope: QtPositioning.coordinate(51.0, 14.0)
    property variant boundingBox: QtPositioning.rectangle(topLeftEurope, bottomRightEurope)

    Map {
        id: mainMap
        anchors.centerIn: parent;
        anchors.fill: parent
        plugin: Plugin {name: "osm"}

        MapItemView {

            model: myModel

            delegate: Marker{}   

        }
        visibleRegion: boundingBox
    }
}

It displays the map and defines a bounding Box.

and here is the delegate : Marker.qml

import QtQuick 2.4
import QtLocation 5.6



MapQuickItem {
    id: mark

coordinate: position //"position" is roleName

    ... all the stuff for the marker to be displayed on the map
}

I wish to add this condition to discard the points which are not within the bounding box to be displayed :

if (main.boundingBox.contains(position)){
    ... display the marker on the map
}

but if is not usable directly in my code.

I've tried to add a function :

function isMarkerViewable(){
    if (!main.boundingBox.contains(position))
        return;
}

but I'm not able to call it, too.

Is it possible to add a condition in a delegate and, if yes, how to do it ?

Thanks for your help

kontiki
  • 186
  • 3
  • 16
  • Simply solution: set the visible property of your marker to your boolean condition, so it's still there but not visible. – xander Dec 20 '17 at 15:31
  • Thanks for your tip, but it's not possible. I have a huge number of points and it takes too many memory if all of them are processed. I must load only the ones which are useful. So I really need a if statement or equivalent to do the job. – kontiki Dec 20 '17 at 15:48
  • In that case you should make your marker model only return visible points, I guess that should be possible. There are also filtered models in Qt/QML, like the [QSortFilterProxyModel](http://doc.qt.io/qt-5/qsortfilterproxymodel.html). I'm not sure if there are any pure QML versions of a filter model as of yet. But that would be the best solution to your problem to start at the model, not the view. – xander Dec 20 '17 at 15:55
  • Thank you. I will move towards this solution. Nevertheless is it still possible to put a condition in a delegate. For example, if this, then display a circle, if that, display a rectangle? – kontiki Dec 20 '17 at 16:18
  • If you are going to discard points, the appropriate thing is to filter in the model through a QSortProxyModel, if you are going to say what type of item you want to see this you must do in the delegate. What do you want to do? – eyllanesc Dec 20 '17 at 16:41
  • Hi Eyllanesc, thank for you to join. For the datas, its ok, i'm going to filter in the model as you and xander propose. After that, for the delegate, some points to show are airports, some are navpoints. I must choose an icon according to the type of point, say a rectangle for airport, a circle for navpoint. I think this must be done into the delegate as you mentionne : if an airport, display a rectangle, else, display a circle. How this can be achieved ? – kontiki Dec 20 '17 at 17:28
  • I have no experience with the location stuff, but in regular QML I would use a `Loader` with `sourceComponent: (isAirport ? myAirportComponent : (isNavpoint ? myNavpointComponent : ...))` or something like that. – derM - not here for BOT dreams Dec 20 '17 at 18:38

2 Answers2

1

As @derM comments one option is to use Loader, in the following example each point has an attribute called type that serves to distinguish which items should be drawn a rectangle or circle.

Marker.qml

import QtQuick 2.0
import QtLocation 5.6

MapQuickItem {
    sourceItem: Loader{
        sourceComponent:
            if(type == 0)//some condition
                return idRect
            else if(type == 1) //another condition
                return idCircle

    }
    Component{
        id: idRect
        Rectangle{
            width: 20
            height: 20
            color: "blue"
        }
    }
    Component{
        id: idCircle
        Rectangle{
            color: "red"
            width: 20
            height: 20
            radius: 50
        }
    }
}

main.qml

MapItemView {
    model: navaidsModel
    delegate:  Marker{
        coordinate:  position
    }
}

Output:

enter image description here

You can find a complete example in the following link.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Thanks to @derM and eyllanesc for these new answers. Eyllanesc, once again, you did a great job. Your answers are very didactic for the learner I am. – kontiki Dec 21 '17 at 09:10
0

If your goal is not related to performance optimization (not loading items that aren't needed) but it is related simply to your business logic, the easiest solution to me seems to use the visible property of the MapQuickItem or of the source component. Like:

visible: main.boundingBox.contains(position)
Pa_
  • 641
  • 1
  • 5
  • 17
  • in fact it is not the case and performance optimization is a great deal for me. I have more than 500 000 points all around the globe to position, so if I can only load in memory a few of them, it is the achievement. – kontiki Dec 21 '17 at 20:20