4

Is there a way to simplify multipolygon by removing small gaps in PostGIS? Example:

Original:

enter image description here

Simplified:

enter image description here

It could also simplify the shape as ST_Simplify does but in addition it should remove small gaps between parts of the multipolygon.

1
  • Is that one multipolygon or two single parts?
    – BERA
    Aug 27, 2022 at 16:33

3 Answers 3

7

In the upcoming PostGIS 3.3 ST_ConcaveHull has been enhanced so that it respects boundaries when polygons are provided as input. So for this case you should be able to simply create a concave hull around the input, with a suitable concaveness parameter.

The result should look something like this: enter image description here

See also this blog post on the Concave Hull of Polygons algorithm.

5
  • 1
    Thank you. I will accept your answer once PostGIS 3.3 is released. Aug 27, 2022 at 16:45
  • It's just been released: postgis.net/2022/08/27/postgis-3.3.0-released
    – dr_jts
    Aug 27, 2022 at 20:26
  • 1
    I've upgraded, but I am getting ERROR: lwgeom_concavehull: GEOS Error: IllegalStateException: Unable to find a convex corner. Aug 28, 2022 at 8:48
  • 2
    Add your geometry as WKT into your question so others can have a try with the same data.
    – user30184
    Aug 28, 2022 at 8:54
  • 2
    There is a small known bug in the new algorithm, and unfortunately you've found it. Posting your geometries as WKT will help to fix this.
    – dr_jts
    Sep 1, 2022 at 5:24
7

Join the layer to itself by distance, snap and union:

WITH clusters 
  AS(select st_clusterdbscan(geom, 0, 2) over() cluster_id, geom 
  from 
    (select a.id as aid, case when a.geom is not null and b.geom is not null then st_snap(a.geom, b.geom, 500) else a.geom end as geom
    from public.polywithgaps a
    left join public.polywithgaps b
    on st_dwithin(a.geom, b.geom, 500) --Change 500 to the distance you want to snap
    and a.id<b.id) sub)
    
select st_union(geom) geom from clusters
where cluster_id is not null
group by cluster_id
union
select geom from clusters where cluster_id is null

enter image description here

1
  • 2
    ++1 for sexy pgsql Aug 28, 2022 at 19:16
1

How about customizable buffering.

Configure and run this SQL script:

SELECT ST_Buffer((ST_Dump((ST_Union(ST_Buffer((geom),0.1, 'side=left join=mitre'))))).geom,-0.1,'side=left join=mitre') geom FROM <sourse_table>

You should get a result like in my image.

enter image description here

Fun original geospatial solutions...

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.