From f79a3c5bf4518f46dbed201f67e38d64859ffa34 Mon Sep 17 00:00:00 2001 From: Al Date: Sun, 17 Jan 2016 15:43:21 -0500 Subject: [PATCH] [osm/polygons] Allowing polygons that GEOS claims are invalid in OSM polygon index (there were some glaring omissions from the index like the polygons for the UK or Berlin). For some reason .buffer(0) creates weird multipolygons that no longer contain their centroids, etc. and aren't useful in reverese geocoding --- scripts/geodata/polygons/reverse_geocode.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/scripts/geodata/polygons/reverse_geocode.py b/scripts/geodata/polygons/reverse_geocode.py index 3fba9df1..cf864b04 100644 --- a/scripts/geodata/polygons/reverse_geocode.py +++ b/scripts/geodata/polygons/reverse_geocode.py @@ -41,6 +41,8 @@ from geodata.statistics.tf_idf import IDFIndex from geodata.text.tokenize import tokenize, token_types from geodata.text.normalize import * +from shapely.topology import TopologicalError + decode_latin1 = partial(safe_decode, encoding='latin1') @@ -682,6 +684,11 @@ class OSMReverseGeocoder(RTreePolygonIndex): poly = cls.to_polygon(p) if poly is None or not poly.bounds or len(poly.bounds) != 4: continue + if not poly.is_valid: + poly = cls.fix_polygon(poly) + if poly is None or not poly.bounds or len(poly.bounds) != 4: + continue + if poly.type != 'MultiPolygon': inner.append(poly) else: @@ -692,8 +699,17 @@ class OSMReverseGeocoder(RTreePolygonIndex): poly = cls.to_polygon(p) if poly is None or not poly.bounds or len(poly.bounds) != 4: continue - # Figure out which outer polygon contains each inner polygon - interior = [p2 for p2 in inner if poly.contains(p2)] + + interior = [] + try: + # Figure out which outer polygon contains each inner polygon + interior = [p2 for p2 in inner if poly.contains(p2)] + except TopologicalError: + poly = cls.fix_polygon(poly) + if poly is None or not poly.bounds or len(poly.bounds) != 4: + continue + if poly.is_valid: + interior = [p2 for p2 in inner if poly.contains(p2)] if interior: # Polygon with holes constructor