# How can I calculate the nearest 3D distance (x, y, z) between points in Qgis?

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?

• 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) Commented Feb 28, 2023 at 8:10
• How many points in each layer?
– Bera
Commented Feb 28, 2023 at 18:49
• Each layer has more than 1000 points.
– Kang
Commented Mar 2, 2023 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
Commented Mar 2, 2023 at 4:04

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

Connect to the database in Database manager:

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
left join forestpoints f
on PtDistWithin(r.geometry, f.geometry, 5000)
``````

• 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
Commented Mar 6, 2023 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
Commented Mar 6, 2023 at 6:51
• 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
Commented Mar 6, 2023 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
Commented Mar 6, 2023 at 9:01