3

I have LineLayer with "start_point" and "end_point" field attributes which can snap to either PointLayer1 or PointLayer2.

Using the Field calculator, I would like to make an expression which would take "id" attribute from the point it is snapped, regardless of which point layer it is snapped to.

"start_point":

aggregate(
    layer:='PointLayer1 name',
    aggregate:='max',
    expression:="id",
    filter:=intersects(buffer($geometry, 0.05), start_point(geometry(@parent)))
    )

"end_point" attribute field is the same with end_point(geometry(@parent)) instead.

I'm just trying to cover PointLayer2 so I get its "id" field value as well. So with line layer having a "start_point" and "end_point" to its geometry, to which can be snapped either a PointLayer1 or PointLayer2 feature, I want the start_point and end_point attribute fields to receive the "id" feature from the point features snapped to them.

I use basic QGIS and I don't use RefFunctions as I need it as simple and reusable as possible for multiple PCs.

if (PointLayer1 feature is snapped to LineLayer's geometry start_point)
    {
    LineLayer start_point attribute field receives PointLayer1 feature's id value
    }
else if (PointLayer2 feature is snapped to LineLayer's geometry start_point)
    {
    LineLayer start_point attribute field receives PointLayer2 feature's id value
    }
4
  • 2
    Sorry, not really clear what you want to do, how many layer (and which ones) you have, if your points are already snapped to a point or if you want to achieve that etc. Can you add a screenshot?
    – Babel
    Aug 25, 2021 at 12:16
  • Yes, the points are already snapped to the line layer. I have 3 layers: LineLayer, PointLayer1, PointLayer2. LineLayer possesses 2 field attributes (start_point, end_point) which I want to take the id attribute from the point feature which is snapped them. Do I need to upload the screenshot on a filesharing platform? Aug 25, 2021 at 12:23
  • Does this answer your question? Fill attribute-table on feature-creation based on intersection with other layer
    – Erik
    Aug 25, 2021 at 14:19
  • Unfortunately it doesn't. ||' - '|| seems to simply join the two features' values which are snapped to the line into one string or something like that. I need an OR condition. Either point layer feature that is snapped to the line's start_point/end_point should have its id given to the line's start_point attribute Aug 25, 2021 at 14:58

1 Answer 1

2

Edit

For the additional information you provided in the comments, the solution has to be modified (old solution below).

First create a virtual layer that collects the two point layers in one layer. That makes it easier to get the id using expressions, as we only have to check one layer (the virtual one).

  1. Create a "Virtual Layer" through Layer > Add Layer > Add/Edit Virtual Layer... called virtual with this query:
SELECT
    a.geometry,
    a.id
FROM
    point1 a
UNION
SELECT
    b.geometry,
    b.id
FROM
    point2 b
  1. On the line layer, use this expression that creates the values for start- and end-point at once:
    array_to_string (
        array_foreach (
            array(1,2),
            with_variable (
                'count',
                @element,
                if (@count=1,'start: ' , 'end: ') || 
                attribute (
                    get_feature_by_id (
                        'virtual',
                        array_first (
                            array_remove_all(
                                array_foreach (
                                    overlay_touches('virtual',$id),
                                    if (
                                        length(
                                            make_line(
                                                if (@count=1, start_point($geometry),end_point($geometry)),
                                                geometry(get_feature_by_id ('virtual',@element))
                                        ))=0,
                                        @element,
                                        ''
                                )),
                                ''
                    ))),
                    'id'
    ))))

enter image description here

Old solution

If you have three layers: line, PointLayer1, and PointLayer2, use this expression on the line layer for the start_point (and replace start_point with end_point for the end_point):

if(
    within(
        array_first(overlay_touches('PointLayer1', $geometry)),
        buffer(end_point($geometry), 0.00001)),
    array_first(overlay_touches('PointLayer1', $id)),
    array_first(overlay_touches('PointLayer2', $id))
    )

Screenshot: PointLayer1 in red, PointLayer2 in blue; line in black with arrow-symbol at the end-point and labeled with the expression from above (highlighted in yellow, with an additional text-string stating start_/end_point = PointLayer1/2, id: ): enter image description here

11
  • Hi! It does work though there seems to be an issue where PointLayer2's id is retrieved for both the start_point and end_point of a given line (despite there being only 1 id, the other feature has its id set as NULL) Aug 25, 2021 at 15:39
  • OK, does this appear in all or just some cases? The expression is based on the overlapping of the point layers with a (small) buffer around the start_/end_points. If the buffer size is too large, both start_ and end_points are covered. Try to reduce the size of the buffer at the end of line 2 from 0.00001 to a smaller number. Does this solve the problem? Otherwise: can you post a screenshot or share a sample of your data for testing?
    – Babel
    Aug 25, 2021 at 15:42
  • It did happen in most cases and there would be instances where the start_point and end_point for a given line are both snapped to 2 features from the same point layer and in that casem it would take the id of only one of them. Also reducing the size of the buffer doesn't seem to change the results Aug 25, 2021 at 16:12
  • 1
    Hi, I just wanted to say that your solution works perfectly, I wasn't using the expressions properly. Sorry for the confusion and thank you! Aug 27, 2021 at 9:44
  • Hello, I'm adding an update. Eventually, using your expression, I end up with the same result I mentioned in my previous comment (start_point and end_point snapped to features from the same layer) I end up with both start and end attributes receiving the same value, here's a screenshot: i.stack.imgur.com/APFyo.png Sep 29, 2021 at 11:42

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.