6

enter image description here

I am very new to QGIS.

Attached is an image of my QGIS project so far. In this, you have the pinkish points of the "Point_centers" layer and green points labeled "Point_trees" which are tree species that I am interested in. What I want to do is calculate the distance of the Point_centers to all the Point_trees within the 15 meter buffer layer I created. I want it to calculate the distances regardless whether or not the Trees overlap in different buffers.

3 Answers 3

7

To get the distance from the center point to each tree inside the buffer, use this expression:

array_foreach (
    overlay_nearest( 
        'Point_trees', 
        $geometry, 
        max_distance:=15, 
        limit:=-1
    ),
    length (
        make_line (
            $geometry,
            @element
        )
    )
)

This generates an array of distances from the center to each tree inside the buffer. The get the sum of all distances, enclose the expression in an array_sum() function.

The expression calculates the lengths of the black lines. These lines here are created based on the same expression for visualization purpose: enter image description here

6
  • Is it possible to get a result similar to the one showed by Matt in his answer to this question and here within the Geometry Generator, so that the changes in distances are visualized immediately without generating specific layers?
    – HyPhens
    Commented Jun 5, 2023 at 11:49
  • 1
    Unfortunately not, there's no easy way to create individual labels as Geometry Generator can have just one individual label per feature - but here, you want have several different labels per point (one for each connecting line).
    – Babel
    Commented Jun 5, 2023 at 12:03
  • And what about calculating the number of lines/connections existent for each point and store them as an attribute?
    – HyPhens
    Commented Jul 6, 2023 at 12:52
  • 1
    @HyPhens this is possible: replace array_foreach with array_length to calculate the number of lines for each point
    – Babel
    Commented Jul 6, 2023 at 13:07
  • I noticed that the result is always '+1', probably because it counts also the point with itself, so maybe a '-1' at the end of the expression can help.
    – HyPhens
    Commented Jul 6, 2023 at 13:29
5

To calculate the distances in a table:

  1. First ensure that your buffers layer and trees layer have a field with a unique identifier. I used tree_id and buffer_id.

  2. Perform a spatial join between the trees and the buffers using a one-to-many join type. This will give you a new points layer where points are duplicated when they are within more than one buffer.

enter image description here

Tree T23 now appears 3 times, in buffers 2, 3, and 4.

enter image description here

  1. Then use this expression in the Field Calculator on the joined layer:
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:='buffer_id',   -- 'buffer_id' in single quotes is the field name
                              value:="buffer_id")))     -- "buffer_id" in double quotes is the field value of the current joined point
                                                                             
        
    )
)

enter image description here

Now each tree point has a distance to its corresonding buffer centroid:

enter image description here

Example:

enter image description here

(The lines are for visualisation purposes only)

8
  • How did you get the last picture, with the lines labelled with the lengths?
    – HyPhens
    Commented May 26, 2023 at 10:49
  • 1
    The lines were created with a Geometry Generator symbol layer. The expression to create the lines is the same as above but without the outer length() function. The label text was created using the whole expression above.
    – Matt
    Commented May 26, 2023 at 11:14
  • 1
    A couple of things to check: Did you change the output geometry type of the symbol layer to line, and are your layer and field names consistent with those in the expression?
    – Matt
    Commented May 26, 2023 at 12:06
  • 1
    I am away from my computer at the moment so I can't test it. I will take a look a little later and get back to you.
    – Matt
    Commented May 26, 2023 at 12:26
  • 1
    See this question that covers the steps: gis.stackexchange.com/questions/461010
    – Matt
    Commented Jun 4, 2023 at 17:42
4

You can use a virtual layer to compute the distance and optionally draw a line to the center point.

Go the the menu layer / add layer / add-edit virtual layer and enter the following query. You can add any field from the point or polygon layer.

select make_line(pt.geometry, st_centroid(poly.geometry)) as geometry, 
       st_distance(pt.geometry, st_centroid(poly.geometry)) as dist
from myPolygonLayer poly
join myPointLayer pt
 on st_intersects(pt.geometry,poly.geometry)

enter image description here

PS: See how accurate is my buffer polygon?! That's why it is usually better NOT to select point within a buffer, but rather to select points within a distance of another point.

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.