[postgis-users] unable to assign hole to a shell
Patrick Valsecchi
patrick.valsecchi at camptocamp.com
Sun Sep 16 00:40:04 PDT 2007
Hi,
Thanks for the quick answer! Comments bellow.
On Sunday 16 September 2007, Kevin Neufeld wrote:
> So you're trying to use ST_Buffer(poly, 0.0) to clean-up your polygon?
Yes, trying. Because if my polygons are not clean, PostGIS/GEOS is dying on me
all the time. And I'm trying to document a method to fix polygons (thus the
blog) to help the others in my case.
> A little investigation revealed that your polygon is not as harmless as
> you thought. You actually have coincident line segments in the exterior
> ring of your polygon.
> LineSegment( 9.50351715087891 47.3943328857422 ) occurs three times.
> This, as well as other self-intersections, is why st_buffer() was dying
> on you.
Sorry, but I'm new to PostGIS and I come from a world where self-intersecting
polygons are considered mostly harmless. ;-)
I think my next post on this mailing list will be about a query on polylines
that makes the postgres backend crash (signal 11). I'm still investigating on
this one...
> Be careful using st_buffer() to cleanup geometries. Using 0.0 to trick
> the function to not actually buffer at all is really a hack that does
> not always work. I think we have planned to build a proper
> geometry-cleanup function down the road, but until then, just be careful.
What do you mean by "not working"? Returning a wrong polygon or throwing an
error?
Wouldn't that be a bug of st_buffer, if the 0.0 trick is not working?
A geometry-cleanup would be more than welcome. I've around 5 million polygons
in my DB and a lot of them are self-intersecting. Self intersection is a
trick used in my source data to reduce the number of points needed to
represent the polygons.
> I was able to rebuild your polygon this way:
> 1. extract the exterior ring - you may want to add to this subquery all
> the interior rings if you have any
> 2. extract all the points of the ext ring as ordered pairs (ie as
> point1-point2, point2-point3, point3-point4, ....)
> 3. recreate line segments from all these ordered point pairs, removing
> duplicates.
> 4. rebuild the polygon using st_buildarea()
Would this trick work on every polygon? By construction my polygons have no
interior ring.
> -- Rebuild the polygon from all the linework
> SELECT ST_BuildArea(geom) AS geom
> FROM
> (
> -- Recreate the line segments (2-point lines) from the ordered points.
> SELECT ST_Union(ST_MakeLine(pt1, pt2)) AS geom
> FROM
> (
> -- Extract the points as pairs from the exterior ring of the polygon
> SELECT ST_PointN(geom, generate_series(1, ST_NumPoints(geom)-1))
> AS pt1,
> ST_PointN(geom, generate_series(2, ST_NumPoints(geom))) AS pt2
> FROM
> (
> -- The exterior ring of your 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 point_pairs
> ) AS line_segments
>
> On a side note, your GEOS version is a little out of date. The new
> version doesn't crash when trying to buffer your polygon, but it does
> return an empty geometry collection.
That, IMHO, would be worse. I'd rather have an error than corrupted data.
>
> Hope this clarifies things.
Helps a lot, thanks.
More information about the postgis-users
mailing list