Using Python2.7 and shapely, let:
import shapely
coords = [(0, 0), (0, 2), (2, 0), (2, 2), (0, 0)]
bowtie = shapely.geometry.Polygon(coords)
bowtie.is_valid
which gives this :
Self-intersection at or near point 1 1
Out[2]: False
So let try the buffer(0)
method as describer in the doc (http://toblerity.org/shapely/manual.html):
clean = bowtie.buffer(0)
type(clean)
which gives that:
Out[4]: shapely.geometry.polygon.Polygon
The difference between the example in the doc is that in the present case, the crossing point is not defined in the original coordinates, so it's not resulting in a multipolygon and it's not really consistent with these initial coordinates, as this command:
clean.wkt
shows when it returns:
Out[16]: 'POLYGON ((0 0, 0 2, 1 1, 0 0))'
And the resulting image for a more visual understanding:
With:
Red: original self-intersecting polygon
Teal: cleaned bowtie polygon with buffer(0)
method (only one half of the original polygon. Take care of the different scaling effect on iPython…)
Question:
How to easily get the original shape back with a valid geometry so that we can perform further operations like intersections, etc?
Best Answer
A different hack would be using only the exterior of the bowtie, intersecting it with itself (generating a MultiLineString), polygonizing that (generating Polygons) and finally aggregating into a MultiPolygon: