Clean Polygons
It often happens that geometry data has invalid topology according to the OGC model used by PostGIS. This situation causes many operations to fail or give incorrect results.
To correct this, it is necessary to correct the invalid polygonal topology by cleaning the polygon. One the basic approach to do this is:
- extract the linework from the polygon to a lineal geometry
- union the lineal geometry together along with a single point from the geometry (this effectively forces the the linework to be noded & dissolved)
- polygonize the resulting linework
Caution: this may not create the expected topology if the polygon contains holes.
Alternatively you can download a plpgsql function from http://www.kappasys.ch/pgtools/cleangeometry/cleanGeometry.sql This function works with polygons containig holes as well as with linestrings.
Example:
SELECT cleanGeometry(the_geom) FROM foo;
Example:
-- Polygonize the noded linework SELECT ST_BuildArea(geom) AS geom FROM ( -- Node & dissolve the linear ring SELECT ST_Union(geom, ST_Startpoint(geom)) AS geom FROM ( -- Extract the exterior ring of the polygon SELECT ST_ExteriorRing( 'POLYGON(( 9.50351715087891 47.3943328857422, 9.50386047363281 47.3943328857422, 9.50351715087891 47.3943328857422, 9.50248718261719 47.3943328857422, 9.50214385986328 47.3939895629883, 9.50180053710938 47.3943328857422, 9.50145721435547 47.3939895629883, 9.50111389160156 47.3936462402344, 9.50145721435547 47.3936462402344, 9.50145721435547 47.3939895629883, 9.50214385986328 47.3939895629883, 9.50248718261719 47.3939895629883, 9.50386047363281 47.3943328857422, 9.50351715087891 47.3943328857422))'::geometry) AS geom ) AS ring ) AS fixed_ring
which produces:
MULTIPOLYGON ((( 9.50351715087891 47.3943328857422, 9.50386047363281 47.3943328857422, 9.50248718261719 47.3939895629883, 9.50214385986328 47.3939895629883, 9.50248718261719 47.3943328857422, 9.50351715087891 47.3943328857422 )), (( 9.50145721435547 47.3939895629883, 9.50180053710938 47.3943328857422, 9.50214385986328 47.3939895629883, 9.50145721435547 47.3939895629883 )), (( 9.50145721435547 47.3939895629883, 9.50145721435547 47.3936462402344, 9.50111389160156 47.3936462402344, 9.50145721435547 47.3939895629883 )))