def fix_polygon(polygon): """ Attempt to fix the given polygon. We return the fixed polygon, or None if we are unable to fix it. """ # Start by splitting the polygon up into an exterior ring, and zero or more # interior rings. exterior_ring = polygon[0] interior_rings = [] for ring in polygon[1:]: interior_rings.append(ring) # If the exterior ring is invalid, we can't fix the polygon -> give up. if not is_ring_valid(exterior_ring): return None # Check each interior ring, removing any which aren't valid. fixed_interiors = [] for ring in interior_rings: if is_ring_valid(ring): fixed_interiors.append(ring) # Reconstruct the polygon out of the remaining linear rings. rings = [] rings.append(exterior_ring) rings.extend(fixed_interiors) fixed_polygon = Polygon(*rings) # Finally, attempt to buffer the polygon, to fix any remaining problems. try: fixed_polygon = fixed_polygon.buffer(0) except GEOSException: fixed_polygon = None return fixed_polygon