8

I need help to understand what am I doing wrong in this expression. I have two layers, one with lines and one with polygons. I wished to achieve through Geometry Generator a dissolve of all the polygons that intersects with the line.

This is the code I'm using:

buffer (
    collect(
         intersects( 
            geometry(
                get_feature(
                    'line', 'id', $id
                )
            ), $geometry
        )
    ), 0
)

enter image description here

4
  • 1
    I believe the wrong layer is being styled. Every polygon feature will be styled, one after another. If you want to dissolve the polygons intersecting the line, you will end up with many overlapping new geometries (in the example picture, the new polygon would cover polygons #7,8,10,9,11,12,13, but you would get 7 copies of it). Maybe you want to style the line? (one line intersects many polygons, which are dissolved, and display 1 new polygon for 1 input line) – JGH Mar 22 at 18:29
  • 1
    If you truly want to style the polygon layer, you would have to start with (each) polygon, find the intersecting line, then find every intersecting polygons for this line, so you would to add a new reference to the "current" layer – JGH Mar 22 at 18:32
  • 1
    related: gis.stackexchange.com/a/390748/84870 – JGH Mar 22 at 18:33
  • 1
    @Felippe M. What QGIS version are you referring to ? – Snaileater Mar 22 at 18:49
10

@snaileater already explained why your expression wont work. Here is how you can do it with QGIS 3.16+ (explanation as comments in expression):

buffer( -- dissolve result
 collect_geometries( -- collect geometry array to multipolygon
  array_filter( -- only keep not null values in array
   aggregate( -- collect the polygonlayer
    @layer,
    'array_agg', -- create an array of the result
    if(overlay_intersects('line',$geometry)[0]is not null,$geometry,null) -- only add geometries to the array that actually intersect with the line layer, if not, write null instead of $geometry
   ) -- aggregate()
  ,@element is not null) -- array_filter()
 ), -- collect_geometries()
0) -- buffer()

enter image description here

I want to add, that using expressions for such cases is not very efficient because in fact this will return as many features as your polygon layer features has. Keep that in mind when styling large layers this way.


To answer your further questions from comment:

  • An array (also known as list data structures) in this case, as returned by aggregate() looks like this: [<geometry: Polygon>,NULL,<geometry: Polygon>,<geometry: Polygon>,NULL,NULL,NULL,<geometry: Polygon]. So in this case it is not a collection of features, but it is a collection of geometries. However, if you would replace $geometry with $currentfeature in the expression above, this array would be a collection of features.
  • aggregate() is a function collecting features, geometries or attributes of a layer. You can choose between different types of "collections", such as mean, max, sum, etc. or an array, listing all the single attributes, features or geometries.
  • The [0] in the if-statement will return the first element of the array, delivered by overlay_intersects(). The array is zero-based. You can find this kind of notation e.g. a lot when looking at Python scripts. An alternative in QGIS-Expressions for overlay_intersects('line',$geometry)[0] would be array_get(overlay_intersects('line',$geometry),0). Both expressions do exactly the same.
1
  • Thank you for you help, this is all hypothetical as I'm trying to learn the expressions in QGIS! Could you clarify me some things? For example, what'd be an array in this case? Would it be a collection of the features? Where does it difference from aggregate collection? In the IF what does that [0] mean? I couldn't find it in the documentation. Sorry if I seem quite an ignorant but I'm still learning much of it. – Felippe M. Mar 22 at 19:31
8

Intersects doesn't return a geometry. It only returns true or 1 when the two passed geometries intersect.

That explains why collect won't work either.

You should build your formula step by step and each time you make it more complex check what it returns or how it behaves.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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