3

I have 2 tables/layers:

  • A Point table called "Chambers Used" with names in a field called "Chamber Identifier"
  • A LineString table called "Ducts Used" including fields "A End" and "B End"

I'd like the form for when creating new items in the "Ducts Used" table to default the "A End" and "B End" attributes to the "Chamber Identifier" of the nearest (or touching) entry in the "Chambers Used" layer.

Things I have attempted in the Default value expression:

array_to_string(overlay_nearest('Chambers Used', "Chamber Identifier", max_distance:=5))

This just returns blank.

And this one inspired by Find item from start point and end point of line

array_first(
array_remove_all( 
    array_foreach (
        overlay_nearest ('Chambers Used',$id, limit:=2),
        if (
            within (
                geometry (get_feature_by_id ('Chambers Used',@element)),
                buffer (end_point($geometry), 5)
            ),
            attribute (get_feature_by_id ('Chambers Used',@element), 'Chamber Identifier'),
            ''
    )),
    ''

))

This returns null.

1 Answer 1

2

With your first expression, if you are getting NULL in the preview when setting up the default expression, this is normal if you have no features in your layer (or if all of the existing features happen to be nowhere near your point layer). I trust you got blank/NULL results when trying to digitise a line?

Furthermore, you have set up the expression to have a limit of 5 metres from the point -

  1. Have you made sure that your lines' endpoints are in fact anywhere within 5 metres of those points?

  2. Also, are you using a projected CRS (metres or feet)? If you are using a non-projected CRS (e.g. units in degrees) then it may not work.

I was able to get your expression to pick up a non-null value using a projected CRS for the project and layers, per below:

enter image description here

However as you can see in that example, and as you have surmised in your original post, it just picks up the closest point to the entire line, rather than differentiating between first and last point.

The second expression you use should work if the first one does. For the sake of things I simplified the expression a little to the following:

array_to_string(
    array_filter(
          array_foreach(
                 overlay_nearest('Chambers Used', 
                                  $id, 
                                  limit:=2),
                 if(
                    within(geometry(get_feature_by_id('Chambers Used',@element)),
                           buffer(start_point($geometry),5)),
                    attribute(get_feature_by_id('Chambers Used',@element),
                                                'Chamber Identifier'),
                      '')),
         @element!=''))

And changed start_point() to end_point() for the end point.

Result:

enter image description here

Both using QGIS 3.22.4

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.