[postgis-users] Cleaning non valid multipolygon

Yves Moisan yves.moisan at boreal-is.com
Wed Feb 4 05:36:35 PST 2009


Kevin,

Thanx a lot.  I ended up doing the few remaining by hand.  I could start
from the linestring and figure out where the bad vertex was.  Not all
the polygons I had closed and some even missed a side or two, so no hope
for any algorithm there.  I'll study what you're proposing and see how
many remaining non valid geometries remain.

Thanx again for your helpful comments.

Yves

Le mardi 03 février 2009 à 14:11 -0800, Kevin Neufeld a écrit :
> 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 ?
> > 
> _______________________________________________
> postgis-users mailing list
> postgis-users at postgis.refractions.net
> http://postgis.refractions.net/mailman/listinfo/postgis-users




More information about the postgis-users mailing list