5

I have a line layer and a polygon layer. I'm trying to create an expression to fetch a polygon attribute and add it to the line, based on in which polygon the line ends.

array_last(overlay_intersects('ok_ak_riks', kommunkod))

This isn't always working. How can I modify it? I've been thinking of if I can use end_point($geometry) somehow?

It is working for line 1 and 2, but not 3 (3 is one line, although the symbology is two arrows) end_polygon should be 2505:

enter image description here

Babel
  • 71,072
  • 14
  • 78
  • 208
BERA
  • 72,339
  • 13
  • 72
  • 161
  • Similar issue with another working possibility: https://gis.stackexchange.com/questions/325464/fill-attribute-table-on-feature-creation-based-on-intersection-with-other-layer – Erik Oct 30 '21 at 20:32

2 Answers2

5

You can use aggregate() with an intersects() filter:

aggregate(
'ok_ak_riks',
'concatenate',
"kommunkod",
filter:=intersects($geometry,end_point(geometry(@parent))),
concatenator:=','
)

Previous / alternative answer:

array_to_string(
    array_filter( 
        array_foreach( -- 2. iterate over ALL intersecting features
            overlay_intersects('ok_ak_riks',$currentfeature), -- 1. get ALL intersecting features
            if(
                intersects(geometry(@element),end_point($geometry)), -- 3. check if the current one intersects with the lines endpoint
                attribute(@element,'kommunkod'), -- 4a. if it does, return the attribute
                '' -- 4b. otherwise return an empty string
            )
        ),
    @element <> '') -- 5. filter out the empty strings from the array
)

Explanation: you can first get all intersecting features as array by using overlay_intersects('ok_ak_riks',$currentfeature), then iterate over this array by using array_foreach() and filter to the intersecting ones with your endpoint by testing if the current one intersects with your endpoint if(intersects(geometry(@element),end_point($geometry)). This will return the feature of ok_ak_riks intersecting with the lines end. At this point you will get an array like ['','your attribute','',''] where you never know at which position your value is. So you can use array_filter(array,@element <> '') to remove all empty values.

MrXsquared
  • 34,292
  • 21
  • 67
  • 117
4

Use this expression with poly as name of the polygon layer and number as the attribute fieldname you want to get:

array_max (
    array_foreach ( 
        overlay_intersects( 'poly', $id),
        if (
            within (end_point ($geometry), geometry (get_feature_by_id('poly',@element))),
            attribute (get_feature_by_id('poly',@element), 'number'),
            ''
        )
    )
)

The expression used as a dynamic label for the lines: enter image description here

Babel
  • 71,072
  • 14
  • 78
  • 208