[postgis-users] Cleaning non valid multipolygon

Kevin Neufeld kneufeld at refractions.net
Mon Feb 2 23:47:20 PST 2009


This may work, but be careful!  ST_Union is designed to work on *valid* 
geometries. 

IE. on 1.4.0SVN I get a geos error trying to union this polygon with the 
startpoint from it's boundary.

    NOTICE:  TopologyException: side location conflict 376250 8.71766e+006

    ERROR:  GEOS union() threw an error!

    ********** Error **********

    ERROR: GEOS union() threw an error!
    SQL state: XX000

On version 1.3.3, this will actually segfault!


You'll find this with most GEOS functions in PostGIS - they *assume* the 
geometries are valid to begin with.  Really, the best thing to do is 
deconstruct and rebuild your invalid geometries from properly noded base 
linework.  (In some cases, the common hack of buffering by 0 does this 
for you as a side effect, but this doesn't work on this particular example).

-- Here's how I would rebuild your geometry
SELECT ST_AsText(
   -- properly deals with polygon holes
   ST_BuildArea(
      -- generate properly noded linework
      ST_Union(
         ST_Boundary(column1),
         ST_Startpoint(ST_Boundary(column1))
      )
   )
)
FROM ( VALUES ('MULTIPOLYGON(((
376249.7830234 8717655.6050357,
376268.0818048 8717666.0116082,
376265.2666038 8717670.5117466,
376247.812391 8717660.3864341,
376249.7830234 8717655.6050357,
376247.812391 8717660.3864341,
376265.2666038 8717670.5117466,
376268.0818048 8717666.0116082,
376249.7830234 8717655.6050357)))'::geometry)) AS foo;

Cheers,
Kevin

Simon Greener wrote:
> Yves,
>
> I don't know if this helps. In Oracle, to fix self-intersecting polygons one can do a "self-union". 
>
> I looked to see if this would work for PostGIS and, from what I can tell from my simple testing, it does:
>
> drop table crap;
> create table crap (oid serial);
> SELECT AddGeometryColumn('public', 'crap', 'geom', -1, 'MULTIPOLYGON', 2);
> alter TABLE crap DROP CONSTRAINT enforce_geotype_geom;
> alter TABLE crap ADD CONSTRAINT enforce_geotype_geom CHECK (geometrytype(geom) IN ('MULTIPOLYGON'::text,'POLYGON'::text) OR geom IS NULL);
> insert into crap (geom) values(st_geomfromtext('MULTIPOLYGON(((
> 376249.7830234 8717655.6050357,
> 376268.0818048 8717666.0116082,
> 376265.2666038 8717670.5117466,
> 376247.812391 8717660.3864341,
> 376249.7830234 8717655.6050357,
> 376247.812391 8717660.3864341,
> 376265.2666038 8717670.5117466,
> 376268.0818048 8717666.0116082,
> 376249.7830234 8717655.6050357)))'));
> insert into crap (geom)
> select ST_AsText(st_makepolygon(st_linemerge(st_union(geom,geom))))
> from (select st_geomfromtext('MULTIPOLYGON(((
> 376249.7830234 8717655.6050357,
> 376268.0818048 8717666.0116082,
> 376265.2666038 8717670.5117466,
> 376247.812391 8717660.3864341,
> 376249.7830234 8717655.6050357,
> 376247.812391 8717660.3864341,
> 376265.2666038 8717670.5117466,
> 376268.0818048 8717666.0116082,
> 376249.7830234 8717655.6050357)))') as geom) as a;
>
> This may help. But I am sure more experienced experts have a better solution.
>
> S
> On Tue, 03 Feb 2009 06:00:18 +1100, Yves Moisan <yves.moisan at boreal-is.com> wrote:
>
>   
>> Hi All,
>>
>> I have some data from an AutoCAD file (dwg) for which some of the
>> multipolygon elements are not valid geometries.  The pattern is pretty
>> simple : some polygons display the origin vertex 3 times as though one
>> started digitizing going clockwise to close the polygon and then came
>> back counterclockwise not necessarily exactly on the same vertices and
>> closed again.  An example :
>>
>> "MULTIPOLYGON(((
>> 376249.7830234 8717655.6050357,
>> 376268.0818048 8717666.0116082,
>> 376265.2666038 8717670.5117466,
>> 376247.812391 8717660.3864341,
>> 376249.7830234 8717655.6050357,
>> 376247.812391 8717660.3864341,
>> 376265.2666038 8717670.5117466,
>> 376268.0818048 8717666.0116082,
>> 376249.7830234 8717655.6050357)))"
>>
>> Deleting the last 4 lines on that geometry and shoving it back in does
>> the job.  I tried to find an automated way of doing this (buffer,
>> st_geometry ...) and but didn't find anything.  Any pointer to an
>> automated way of doing that, short of writing my own function, which I
>> would need pointers for examples too :-),
>>
>> TIA,
>>
>> Yves Moisan
>>
>> _______________________________________________
>> 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