Calculate the vertical distance between two lines that just intersects on 2D

Jorge Gustavo Rocha jgr at di.uminho.pt
Tue Sep 2 10:53:35 PDT 2025


Hi,

I need to calculate the vertical offset between 3D lines that really 
does not have a common intersection point.

Example: the following perpendicular lines, 100m wide, crossing at the 
center, have a vertical offset of 25 m at the intersection point. One is 
flat, the other goes from 0 to 50m.

           ST_MakeLine(ST_PointZ(-43000, -276500, 0, 3763), 
ST_PointZ(-42900, -276500, 0, 3763)) As line1,
         ST_MakeLine(ST_PointZ(-42950, -276450, 0, 3763), 
ST_PointZ(-42950, -276550, 50, 3763)) As line2

My approach is top calculate the 2D intersection point, and then 
calculate the z difference between the lines at that point.

To do so, I and up with this LISP style query, that returns 25 as expected.

SELECT
st_z( ST_3DLineInterpolatePoint( line2, ST_LineLocatePoint(line2, 
ST_Intersection( line1, line2)))) -
st_z( ST_3DLineInterpolatePoint( line1, ST_LineLocatePoint(line1, 
ST_Intersection( line1, line2))))
   FROM (
       select
           ST_MakeLine(ST_PointZ(-43000, -276500, 0, 3763), 
ST_PointZ(-42900, -276500, 0, 3763)) As line1,
         ST_MakeLine(ST_PointZ(-42950, -276450, 0, 3763), 
ST_PointZ(-42950, -276550, 50, 3763)) As line2
) As foo;

Using, for example, ST_3DClosestPoint will return wrong results, because 
the closest point are calculated in any direction. The following query 
returns 22.5 m, for example.

SELECT
st_z(ST_3DClosestPoint(line2, ST_Intersection( line1, line2))) -
st_z(ST_3DClosestPoint(line1, ST_Intersection( line1, line2)))
   FROM (
       select
           ST_MakeLine(ST_PointZ(-43000, -276500, 0, 3763), 
ST_PointZ(-42900, -276500, 0, 3763)) As line1,
         ST_MakeLine(ST_PointZ(-42950, -276450, 0, 3763), 
ST_PointZ(-42950, -276550, 50, 3763)) As line2
) As foo;

Does anyone has a more elegant way to compute this vertical distance?

A variant of ST_InterpolatePoint that works on the Z value would be nice 
to have; or a ST_3DLineInterpolatePoint function that receives a POINT, 
instead of a fraction.

Regards,

Jorge







More information about the postgis-users mailing list