[GIS] How to calculate the “depth” of a linestring using postgis

depthdistancelinestringpointpostgis

I have linestring features, which look like bent linestrings, hemicycles or convex or concave linestrings. In the moment I can select the distance between the startpoint and endpoint of each feature. Now I want to calculate the vertical (orthogonal) distance between

a) the imaginary line between startpoint and endpoint

b) and the most distant point of the linestring

Like the maximum orthogonal distance between the deepest point in a hole referring to a straight surface.
How can I calculate this with postgis?

Here is a picture:
enter image description here

Best Answer

Consider some test data similar top the thick line in the question's figure:

SELECT 'LINESTRING (114 374, 200 380, 250 350, 259 343, 350 280, 380 180, 383 169, 360 80)'::geometry AS geom
INTO TEMP data;

the straight line (dashed) can be constructed from the start and end points:

SELECT ST_AsText(ST_MakeLine(ST_StartPoint(geom), ST_EndPoint(geom)))
FROM data;

         st_astext
----------------------------
 LINESTRING(114 374,360 80)
(1 row)

Distances from each vertex (coordinate) can then be found to the straight line:

SELECT ST_Distance((ST_DumpPoints(geom)).geom, ST_MakeLine(ST_StartPoint(geom), ST_EndPoint(geom)))
FROM data
GROUP BY geom;

   st_distance
------------------
                0
  69.806901017674
 88.9020622825982
 91.3124350980067
  120.67515848571
 79.5109993654224
 74.7528608207199
                0
(8 rows)

All of this logic can be put into a nested query to get the maximum depth from the geometry:

SELECT geom, max(depth)
FROM (
  SELECT geom, ST_Distance((ST_DumpPoints(geom)).geom, ST_MakeLine(ST_StartPoint(geom), ST_EndPoint(geom))) AS depth
  FROM data
  GROUP BY geom
) AS f
GROUP BY geom;

which is 120.67515848571 for this example.