3

The medial axis for a polygon computed by ST_ApproximateMedialAxis() is usually a single MultiLineString with possibly many branches (see e.g. ST_ApproximateMedialAxis returns multilinestring instead of single linestring). In other words, it's often a tree or network compressed into a single multigeometry. And the monolithic geometry is quite difficult to analyze.

Is there a way in PostGIS to break the MultiLineString representation of medial axis into a small set of simple LineStrings?

(In a way, this is similar to ArcHydro's stream link function, but instead of breaking down a raster network into links, break down a compressed multi-linestring network into links)

-- Edit --

To detail the issue, below is a test medial axis generated by PostGIS. I'd like to extract the handful (~ 10) segments each as a simple polyline:

enter image description here

But it seems that the multi-linestring from ST_ApproximateMedialAxis() is composed of a very large number of two-node parts, each corresponding to one segment of the zigzag shape of the zoomed-in view below:

enter image description here

The number of points in the multi-linestring is exactly twice the number of parts:

SELECT ST_NumGeometries(geom), ST_NPoints(geom) FROM road_line;

 st_numgeometries | st_npoints 
------------------+------------
             6188 |      12376
(1 row)

ST_Dump (as suggested in the answers) generates a very large (too large) number of two-node LineString's.

1
  • 1
    You can use ST_LineMerge to connect 2-point lines into longer runs between actual nodes.
    – dr_jts
    Commented May 18, 2023 at 16:27

1 Answer 1

3

Decomposing MULTILINESTRINGS into simple LINESTRINGs - or any MULTI geometry or GEOMETRYCOLLECTION into their simple parts and components - is trivial with ST_Dump:

  • using (CROSS JOIN) LATERAL set decomposition over processed rows:
    SELECT
      <id>,
      dmp.path[1] AS sid,
      dmp.geom
    FROM
      <polygon_table>,
      LATERAL ST_Dump(ST_ApproximateMedialAxis(geom)) AS dmp
    ;
    
  • same LATERAL set decomposition on a sub-query - using a grouped ST_Union as example:
    SELECT
      <id>,
      dmp.path[1] AS sid,
      dmp.geom
    FROM
      (
        SELECT
          <id>,
          ST_ApproximateMedialAxis(ST_Union(geom)) AS ama
        FROM
          <polygon_table>
        GROUP BY
          <id>
      ) AS q,
      LATERAL ST_Dump(ama) AS dmp
    ;
    
  • using composite type columnar accessors:
    SELECT
      (
        ST_Dump(
          ST_ApproximateMedialAxis(geom)
        )
      ).*
    FROM
      <polygon_table>
    ;
    
0

Your Answer

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

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