[postgis-users] Cleaning non valid multipolygon

Kevin Neufeld kneufeld at refractions.net
Tue Feb 3 14:11:56 PST 2009


Hi Yves,

No, you can't set a tolerance on building an area.  Depending on your requirements, you can snap all the vertices in the 
geometry to some grid so that such polygons do close.

Using OpenJUMP, I can see in your example that your linear ring falls short of about 0.15 units from closing.  So, this 
should work:

UPDATE mytable
SET the_geom = ST_BuildArea(
        ST_Union(
           ST_Boundary(ST_SnapToGrid(the_geom, 0.2)),
           ST_Startpoint(ST_Boundary(ST_SnapToGrid(the_geom, 0.2)))
        )
     )
WHERE id = 122;

If snapping the entire geometry to a grid is not preferable to you, then you're left with some mucky business, but I 
think you can do it.
1. extract and node the exterior ring (your geometry runs back on itself so you can't tell where the start and endpoints 
of the exterior ring lie)
2. merge the ring to a single linestring (making the start and end points obvious)
3. update the startpoint to be equal to the endpoint
4. repolygonize.


CREATE TABLE tmp AS
SELECT id,
   -- Create a single linestring
   ST_LineMerge(
     -- Remove overlapping segments
     ST_Union(
       ST_Boundary(the_geom),
       ST_StartPoint(ST_Boundary(the_geom))
     )
   ) AS the_geom
FROM mytable
WHERE id = 122;
-- At this point, you should only have LINESTRINGs in tmp, not MULTILINESTRINGs.  You should verify this to see if you 
have other problems than just the endpoints not closing.

UPDATE mytable a
SET the_geom =
   ST_BuildArea(
     ST_SetPoint(b.the_geom, 0, ST_EndPoint(b.the_geom)))
FROM tmp b
WHERE a.id = b.id;

Yields a single polygon for id=122:
POLYGON ((
         375838.8459248 8718402.9401143,
         375844.0704528 8718410.3968027,
         375904.0280814 8718366.8994515,
         375898.8035535 8718359.4427696,
         375838.8459248 8718402.9401143
     ))


It would complicate things if you have holes in your non-closing polygons, but for starters this should do for you.

Hope that helps,
Kevin

Yves Moisan wrote:
> [cut] Can I either set some tolerance on the buildarea so it
> snaps to the closest point in the case the multilinestring does not
> close or enforce a constraint on the union so it produces a closed
> linestring ?
> 



More information about the postgis-users mailing list