I'm new to Qgis.

I have two point groups. One is the points representing the road with an interval of 1 m, and another is the forest area. Each point has x, y, and z values. I want to calculate the shortest distances between road points and forest points.

I used the "NNjoin" plugin, but it provided 2D distance (ie, x and y). Are there any ways to calculate adjacent 3D distance between multiple points?

  • 2
    If you know the 2D distance and the height difference, you can compute the 3D distances with the field calaculator using that formula (pythagoras): dist3D = sqrt( (height_p1-height_p2)^2 + dist2D^2)
    – eurojam
    Feb 28 at 8:10
  • How many points in each layer?
    – BERA
    Feb 28 at 18:49
  • Each layer has more than 1000 points.
    – Kang
    Mar 2 at 3:52
  • I understand the formula suggest by eurojam. However, if I calculate the adjacent 3D distance from road to forest using this way, is it really adjacent distance?? For example, there are two road points and one forest point, and each 2D distance is 5 m and 10 m, respectively. In this case, the former point is nearer to forest point than latter point. However, if the differences in elevation between two road points and the forest point are 10 m and 1 m, respectively, the latter point is nearer to forest point than former point.
    – Kang
    Mar 2 at 4:04

1 Answer 1


Export your layers to a Spatialite database (right click - Export - Save feature as)

Connect to the database in Database manager: enter image description here

The query below will join the road table to the forest table and find the closest forest point for each road point. The join is based on 2D distance, so all points within 5000 m will be measured. Adjust 5000 so you're sure that the closest point is included in that distance (see my screenshot at the bottom, the closest 3D point is somewhere within 5000 m)

The closest forest is measured by 3D distance.

Adjust roadpoints and forestpoints below to match the names of your layers:

select  r.id as roadid, 
        f.id forestid, 
        distance(r.geometry, f.geometry) as distance_2D,
        min(st_3ddistance(r.geometry, f.geometry)) as distance_3D
from roadpoints r
left join forestpoints f
on PtDistWithin(r.geometry, f.geometry, 5000)
group by roadid

enter image description here

  • Thank you for the answer. However, when I ran the query, I get error message like "no such column: r.id". Can you show me the each column name of layers?
    – Kang
    Mar 6 at 5:57
  • You need some unique id column, my is called id. Change r.id to the name of yours, r.youridcolumn. If you dont have one you need to create one, for example using Field Calculator with @row_number function
    – BERA
    Mar 6 at 6:51
  • 1
    Thank you for your kindness. I have one more question. What is the geometry?? I should make the "geometry" (r.geometry and f.geometry) column using x, y in each layer??
    – Kang
    Mar 6 at 8:47
  • It is the point geometry. If you have point layers where the points show up on the map you should not need to create them. In my first screenshot there are four tables in my zdata.sqlite database, the first two does not have geometries so the icons are just tables, the second two have geometries so the icons show points
    – BERA
    Mar 6 at 9:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.