Calculate the vertical distance between two lines that just intersects on 2D
Jorge Gustavo Rocha <[email protected]> Tue, 2 Sep 2025 18:53:35 +0100
| Newsgroups | gmane.comp.gis.postgis |
|---|---|
| Message-ID | <[email protected]> |
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