diff --git a/scripts/geodata/polygons/index.py b/scripts/geodata/polygons/index.py index 4893885c..e8cd1efa 100644 --- a/scripts/geodata/polygons/index.py +++ b/scripts/geodata/polygons/index.py @@ -145,13 +145,21 @@ class PolygonIndex(object): return poly @classmethod - def to_polygon(cls, coords): + def to_polygon(cls, coords, holes=None): ''' Create shapely polygon from list of coordinate tuples if valid ''' if not coords or len(coords) < 3: return None - poly = Polygon(coords) + + # Fix for polygons crossing the 180th meridian + lons = [lon for lon, lat in coords] + if (max(lons) - min(lons) > 180): + coords = [(lon + 360.0 if lon < 0 else lon, lat) for lon, lat in coords] + if holes: + holes = [(lon + 360.0 if lon < 0 else lon, lat) for lon, lat in holes] + + poly = Polygon(coords, holes) return poly def add_geojson_like_record(self, rec, include_only_properties=None): @@ -247,12 +255,12 @@ class PolygonIndex(object): def polygon_from_geojson(cls, feature): poly_type = feature['geometry']['type'] if poly_type == 'Polygon': - poly = Polygon(feature['geometry']['coordinates'][0]) + poly = cls.to_polygon(feature['geometry']['coordinates'][0]) return poly elif poly_type == 'MultiPolygon': polys = [] for coords in feature['geometry']['coordinates']: - poly = Polygon(coords[0]) + poly = cls.to_polygon(coords[0]) polys.append(poly) return MultiPolygon(polys) diff --git a/scripts/geodata/polygons/language_polys.py b/scripts/geodata/polygons/language_polys.py index 539ecf95..25c1c5f2 100644 --- a/scripts/geodata/polygons/language_polys.py +++ b/scripts/geodata/polygons/language_polys.py @@ -109,14 +109,14 @@ class LanguagePolygonIndex(RTreePolygonIndex): poly_type = rec['geometry']['type'] if poly_type == 'Polygon': - poly = Polygon(rec['geometry']['coordinates'][0]) + poly = cls.to_polygon(rec['geometry']['coordinates'][0]) index.index_polygon(poly) poly = index.simplify_polygon(poly) index.add_polygon(poly, dict(rec['properties'])) elif poly_type == 'MultiPolygon': polys = [] for coords in rec['geometry']['coordinates']: - poly = Polygon(coords[0]) + poly = cls.to_polygon(coords[0]) polys.append(poly) index.index_polygon(poly) diff --git a/scripts/geodata/polygons/reverse_geocode.py b/scripts/geodata/polygons/reverse_geocode.py index 9e73a046..caf1f216 100644 --- a/scripts/geodata/polygons/reverse_geocode.py +++ b/scripts/geodata/polygons/reverse_geocode.py @@ -205,14 +205,14 @@ class QuattroshapesReverseGeocoder(RTreePolygonIndex): poly_type = rec['geometry']['type'] if poly_type == 'Polygon': - poly = Polygon(rec['geometry']['coordinates'][0]) + poly = cls.to_polygon(rec['geometry']['coordinates'][0]) index.index_polygon(poly) poly = index.simplify_polygon(poly) index.add_polygon(poly, dict(rec['properties']), include_only_properties=include_props) elif poly_type == 'MultiPolygon': polys = [] for coords in rec['geometry']['coordinates']: - poly = Polygon(coords[0]) + poly = cls.to_polygon(coords[0]) polys.append(poly) index.index_polygon(poly) @@ -388,7 +388,7 @@ class OSMReverseGeocoder(RTreePolygonIndex): if interior: # Polygon with holes constructor - poly = Polygon(p, [zip(*p2.exterior.coords.xy) for p2 in interior]) + poly = cls.to_polygon(p, [zip(*p2.exterior.coords.xy) for p2 in interior]) if poly is None or not poly.bounds or len(poly.bounds) != 4: continue # R-tree only stores the bounding box, so add the whole polygon