[postgis-users] invalid polygons, buffer(geom, 0) and silent changes to the actual geometry

Steve Grey stevegrey78 at gmail.com
Tue Apr 7 03:56:44 PDT 2009


Hi,

I hope someone can help, postgis appears to be silently changing invalid
geometries when attempting to "clean" with buffer(geom,0).

select postgis_full_version() gives:
'POSTGIS="1.3.3" GEOS="3.0.0-CAPI-1.4.1" PROJ="Rel. 4.6.0, 21 Dec 2007"
USE_STATS'

select version() gives:
'PostgreSQL 8.3.5 on x86_64-pc-linux-gnu, compiled by GCC gcc-4.3.real
(Ubuntu 4.3.2-1ubuntu11) 4.3.2'


I've been trying to "clean" some invalid polygons, and the advice often
seems to buffer(geom,0) which turns an invalid polygon into a valid
polygon.  However, the actual shape itself seems to change:

select asewkt(geomfromtext('POLYGON((100 100,100 200,400 200,400 400,200
400,200 100,100 100))',27700)) gives...
'SRID=27700;POLYGON((100 100,100 200,400 200,400 400,200 400,200 100,100
100))'
...with no warning that the geometry is invalid - only when checking
isvalid() is there a notice of  "Self-intersection at or near point 200
200".

If I do...
select isvalid(buffer(geomfromtext('POLYGON((100 100,100 200,400 200,400
400,200 400,200 100,100 100))',27700),0))
...I get...
't'
...so I've made the polygon valid and check it is so i the way that is often
recommended.

Except, if I look at the resulting shape as text using...
select asewkt(buffer(geomfromtext('POLYGON((100 100,100 200,400 200,400
400,200 400,200 100,100 100))',27700),0))
...I get...
'SRID=27700;POLYGON((200 200,200 400,400 400,400 200,200 200))'
..which is a different shape, silent of errors, warnings or notices.  I've
lost the smaller part of the shape.



This follows onto similar lines with donut polygons.  I had a function that
was occasionally being sent malformed polygons (as text) from a client
application.  Checking if they are invalid, such as ...
select isvalid(geomfromtext('MULTIPOLYGON(((100 100,100 400,600 400,600
100,100 100)),((200 200,200 300,300 300,300 200,200 200)))',27700))
... I get a warning (NOTICE:  Holes are nested at or near point 200 200)
and...
'f'

Again, isvalid() is raising an error - but simply putting the string into a
geometry and getting it back, as in ...
select asewkt(geomfromtext('MULTIPOLYGON(((100 100,100 400,600 400,600
100,100 100)),((200 200,200 300,300 300,300 200,200 200)))',27700))
...raises no notices etc.

More seriously,  if I ask for the area of the polygon I don't get an error -
I get...
select area(geomfromtext('MULTIPOLYGON(((100 100,100 400,600 400,600 100,100
100)),((200 200,200 300,300 300,300 200,200 200)))',27700))
160000

If I had a properly formed donut, I get
select area(geomfromtext('MULTIPOLYGON(((100 100,100 400,600 400,600 100,100
100),(200 200,200 300,300 300,300 200,200 200)))',27700))
140000


So, unless I check a polygon is valid, I could silently be getting an
incorrect area measure, and perhaps more besides.  As far as this particular
application goes I think I can work around he issue by assembling the
(multi)polygons myself, but I'm concerned at the lack of warnings and its
not just this application - some of my data providers send data with
self-intersecting polygons etc..

Regards,

Steve
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20090407/7d46bfd9/attachment.html>


More information about the postgis-users mailing list