5

I have a multipolygon containing a one large polygon, itself containing a number of smaller polygons, which constitute 'holes' in the largest polygon.

My goal is to simplify the multipolygon into one polygon that closely respects the existing perimeter but removes all the smaller polygons (holes)

I have been using a combination of ST_ExteriorRing and ST_Dump to get rid of the points and lines, however I can't make this work when there are multiple polygons.

The closest working solution I've found is to use ST_ConcaveHull(geometry, 0.99), however this does not follow the perimeter of the shape closely enough (it smoothes over the recesses).

I've pasted the text representation of the multipolygon below https://gist.github.com/glennpjones/51acef849825470386f24a6c3259295d

I'm using PostGIS 2.5.

How would you approach this?

3
  • What is your desired outcome for two disjoint polygons? Have you tried a smaller percentage factor for ST_ConcaveHull?
    – geozelot
    Commented Jan 29, 2020 at 19:03
  • You're right! You put me on the right track, I will have to make a SQL subquery. Thank you
    – Glenn
    Commented Feb 5, 2020 at 13:56
  • Good luck and you, welcome to the mysterious world of geоSQL :-)... Commented Feb 5, 2020 at 14:00

3 Answers 3

3

According to the data provided

Try to go that way:

SELECT ST_MakePolygon(ST_ExteriorRing((ST_Dump(geom)).geom)) geom FROM data ORDER BY geom ASC LIMIT 2;

It's gotta work...

or

WITH 
tbla AS (SELECT ST_MakePolygon(ST_ExteriorRing((ST_Dump(geom)).geom)) geom FROM data)
SELECT ST_Union(geom) geom FROM tbla;

If the system "swears" at the data, you can enhance it with the function ST_MakeValid...

Success in knowing...

1
  • This returns one of the small polygons, which actually is outside of the larger polygon (I thought there were none completely outside). If I do limit 1 offset 1, it also picks a smaller polygon.
    – Glenn
    Commented Jan 29, 2020 at 18:31
1

The "lines and points" in the geometry are actually very narrow/small holes. So it seems like you are looking to remove all the holes from a MultiPolygon. An approach for this is:

  • "Explode" the MultiPolygon into separate Polygons using ST_Dump
  • Remove the holes from each element Polygon using ST_MakePolygon(ST_ExteriorRing(poly))
  • Combine the hole-free elements back using ST_Collect

A runnable SQL example showing this procedure:

WITH data AS (
  SELECT 'MULTIPOLYGON (((90 240, 260 240, 260 100, 90 100, 90 240), (130 200, 200 200, 200 140, 130 140, 130 200)), ((290 240, 380 240, 380 170, 290 170, 290 240), (324 216, 360 216, 360 180, 324 180, 324 216)), ((310 140, 375 140, 375 91, 310 91, 310 140)))'::geometry AS geom
),
polys AS (
  SELECT (ST_Dump( geom )).geom FROM data
),
polynoholes AS (
  SELECT ST_Collect( ST_MakePolygon( ST_ExteriorRing( geom ))) FROM polys
)
SELECT * FROM polynoholes
``

1
1

This is the final query I made, using a subquery. The source geometry (a field named geometry) is in SRID 28992, to be transformed into SRID 4326. The output is GeoJSON.

SELECT
  ( SELECT ST_AsGeoJSON(ST_Transform(ST_SetSRID(ST_MakePolygon(ST_ExteriorRing((ST_Dump(geometry)).geom)), 28992), 4326)) AS simplified
    WHERE provincienaam = P.provincienaam
    ORDER BY ST_Area(ST_Transform(ST_SetSRID(ST_MakePolygon(ST_ExteriorRing((ST_Dump(geometry)).geom)), 28992), 4326)) DESC LIMIT 1)
FROM source.table P;
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.