8

I try to delete the slivers that appeared when I have merged some polygons.

I have two different cases:enter image description here

For the CASE 1, no problem I fill the gap with:

CREATE OR REPLACE FUNCTION sliver_killer(geometry,float) RETURNS geometry AS
$$ SELECT ST_BuildArea(ST_Collect(a.geom)) as final_geom
FROM ST_DumpRings($1) AS a
WHERE a.path[1] = 0 OR
(a.path[1] > 0 AND ST_Area(a.geom) > $2)
$$
LANGUAGE 'sql' IMMUTABLE;

UPDATE merged SET geom = sliver_killer(geom,50::float);

A function that fill all the gaps smaller than x square meter.

BUT for the CASE 2, when the small gaps are "open" I can't manage to fill those gaps.

I have try something like: buffer(1) followed by buffer(-1) but of course I obtain some rounded corners. Did someone have a true solution ?

Andre Silva
  • 10,259
  • 12
  • 54
  • 106
obchardon
  • 1,724
  • 2
  • 13
  • 21

2 Answers2

6

Ok I found an answer:

You can avoid to get rounded corner by adding the parameter 'join=mitre' to st_buffer:

So it work perfectly fine with:

SELECT st_buffer(st_buffer(geom,1,'join=mitre'),-1,'join=mitre') FROM mygeotable;

EDIT

If the buffer is too large st_buffer(geom,10,'join=mitre') produce from time to time some strange results (the polygones become spiky). So to avoid this effect it's safer to preserve the old boundary with st_intersection:

SELECT st_intersection(st_buffer(st_buffer(geom,-1,'join=mitre'),1,'join=mitre'),geom) FROM mygeotable;
obchardon
  • 1,724
  • 2
  • 13
  • 21
0

The ST_Buffer solution already explained here is valid, but it can be improved in order to avoid the spikes (and the intersection step itself). You need to add a new parameter to the buffer mitre_limit.

SELECT st_intersection(
          st_buffer(
             st_buffer(geom, 1, 'join=mitre mitre_limit=1.0'
          ), -1, 'join=mitre mitre_limit=1.0'
        ), geom) as
FROM _mygeotable_ ;

This way you will get what you want much easier and cleaner.