5

This question arose from a comment on this answer to Calculating distance between multiple points within buffer using QGIS.

I have followed the steps there, which use a one-to-many spatial join to generate separate features for each point that is within a buffer polygon in another layer (called buffers). Points that fall within multiple buffers are duplicated. The result is a layer called joined. The points layer has a field called buffer_id containing the id of the joined buffer polygon.

The lines connecting the points with their associated buffer centroid can be visualised using a Geometry Generator symbol layer like so:

collect_geometries(
    array_foreach(
        overlay_within(
            'buffers',
            @geometry
        ),
        make_line(@geometry, centroid(@element))
    )
)

How can I create the labels for the lines as shown in the screenshot?

enter image description here

5
  • Thanks for your detailed answer. Although, the expression to get lines returns "Eval Error: Cannot convert to geometry". The expression is used on the joined layer with a Simple Marker and a Geometry Generator LinesString/MultiLineString. I'm using QGIS 3.26.1.
    – HyPhens
    Commented Jun 5, 2023 at 7:21
  • 1
    It is hard to diagnose the problem without seeing your project setup. You have a layer called buffers that the joined points are within? Also - depending on your version of QGIS you might also need to use $geometry instead of @geometry (the @ prefix for the geometry variable was implemented relatively recently).
    – Matt
    Commented Jun 5, 2023 at 7:48
  • 1
    Yes, I solved it using a newer version (3.28.7). Everything now works fine.
    – HyPhens
    Commented Jun 5, 2023 at 10:47
  • The very last question: with this solution it is not necessary to calculate distances among points with the Field Calculator, but I visualize also '0' distances (i.e. the distance of a point from its duplicate). Is it possible to change the expression for labelling in order to avoid '0' values (I tried but I obtained only '0' and '1')?
    – HyPhens
    Commented Jun 5, 2023 at 12:17
  • 1
    The question/solution here refers to calculating distances to features in another layer, not the same layer, so it is outside the scope of this post. However, you can use rule-based labelling to label only features with distance > 0
    – Matt
    Commented Jun 5, 2023 at 15:01

1 Answer 1

6

Prerequisite

For this solution to work, the point layer must have a field (in this example called buffer_id) that contains the id of the joined buffer polygon. The solution was implemented in QGIS 3.30.3.

Label values

The values for the labels are generated with this expression:

to_int(                                           -- optional cast to integer
    length(
        make_line(
            $geometry,      
            centroid(
                geometry(
                    get_feature(                  -- get the centroid of the buffer that matches the buffer_id of the joined point. 
                        layer:='buffers', 
                        attribute:='id',   -- 'id' in single quotes is the `id` field name in the buffers layer
                        value:="buffer_id"        -- "buffer_id" in double quotes is the field value of the **current point** in the joined layer
                    )
                )
            )                                                                        
        )
    )
)

The expression finds the feature in the buffers layer where the buffer_id matches the joined field in the points layer, makes a line from the buffer centroid to the current point and gets the length of that line.

The expression is entered by clicking the epsilon button next to the Value text edit. The mode is changed to Offset from point and the lower center quadrant is selected.

enter image description here

Label placement

The labels are placed at the midpoint of the connecting lines using this expression:

centroid(                                 -- get the centroid (mid-point) of the line joining the point with the centroid of its associated buffer
    make_line(
        $geometry,      
        centroid(
            geometry(
                get_feature(                  
                    layer:='buffers', 
                    attribute:='id',      -- 'id' in single quotes is the `id` field name in the buffers layer
                    value:="buffer_id"
                )
            )
        )                                                                                
    )
)

The expression is entered by checking Geometry Generator and clicking on the ... button next to the text edit area. Point / MultiPoint is chosen as the geometry type.

enter image description here

Label rotation

The labels are rotated parallel to the line using this expression:

main_angle(                              -- get the angle of the line joining the point with the centroid of its associated buffer
    make_line(
        $geometry,      
        centroid(
            geometry(
                get_feature(                  
                    layer:='buffers', 
                    attribute:='id',     -- 'id' in single quotes is the `id` field name in the buffers layer
                    value:="buffer_id"
                )
            )
        )                                                                                
    )
) + 90                                 -- add 90 to make the label text parallel to the line

The expression is entered as a Data defined override by clicking the enter image description here button next to Rotation in the Data defined section

enter image description here

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.