4

I have two layers. One shapefile point layer, called "point1" and one csv no geometry layer, called "Meta".

"point1" looks like:

id   bd
1    a
2    b
3    c
4    d
5    e
6    f

and so on...

"Meta" looks like:

Name    ids
sample  1, 2, 3, 6

It is a one-line layer and 1, 2, 3, 6 is one single string. Layer "point1" will always stay the same and "Meta" will change everytime the project is opened.

Now I want to create a new layer (multipoint) from point1 layer which id's are listed in the ids string of Meta layer. Out of curiosity I want to know whether this is possible or not using Geometry by expression. (If you have an answer for virtual layers feel free to share as well.)

So far I have the following expression built up which returns an array like this: [<feature: 0>, <feature: 1>, NULL, <feature: 3>] and so on... Here is my expression:

array_agg( 
    get_feature( 'point1','id',
        array_find(  
            (
                array_foreach( 
                    string_to_array(attribute(get_feature_by_id('Meta',2),'ids')),to_int(@element)
                )
            )
                ,attribute( $currentfeature, 'id' )
        )
    )
)

Replacing array_agg() with geometry() returns a copy of point1 layer keeping only the wanted geometries. But how can I create a multipointlayer out of it?

Can I create a multipointlayer using expressions and arrays using QGIS 3.6 this way?

1 Answer 1

1

Your expression could work with a few extensions, but only in Geoemtry Generator, not in Geometry by Expression as this one doesn't accept aggregate functions. See below how to improve your expression, at least for Geometry Generator. However, I propose another solution that also works in Geometry by Expression:

case
when array_contains (
    array_foreach (
        string_to_array(
            attribute(get_feature_by_id ('meta',1),'ids'),
            delimiter:=','
        ), 
        trim(@element)
    ), 
    id
)
then $geometry
end

Initial points in blue, plus duplicated points in red = points from layer points with id value contained in string from attribute field ids of layer meta are created: enter image description here


Back to your expression. You can make it work, at least in Geometry generator, by adding the following functions:

  • Convert the features to geometies with geometry() function that contains the whole get_feature() part of your expression (line 2 to 2nd last line in your expression)

  • Than apply an array_filter() function to the output of your expression (including the additional geometry() part), filtering out the NULL elements:

    array_filter( [your expression], @element is not NULL)

  • Finally, convert the array to multipart geometry with collect_geometries()

So the final expression looks like:

collect_geometries(
    array_filter(
        array_agg( 
            geometry (
                get_feature ('points','id',
                    array_find(
                        array_foreach( 
                            string_to_array(attribute(get_feature_by_id('meta',1),'ids')),
                            to_int(@element)
                        ),
                        attribute ($currentfeature, 'id')
                    )
                )
            )
        ),
        @element is not NULL
    )
)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.