From 6504ece93560fa8eacc3e479519a592a29ab3fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=B8xbro?= Date: Tue, 26 Jul 2022 13:58:04 +0200 Subject: [PATCH] Added projection to .geoms() --- examples/user_guide/Annotators.ipynb | 6 ++-- geoviews/element/geo.py | 49 +++++++++++++++++++--------- geoviews/util.py | 12 ++++--- 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/examples/user_guide/Annotators.ipynb b/examples/user_guide/Annotators.ipynb index 11617630..83c5eebc 100644 --- a/examples/user_guide/Annotators.ipynb +++ b/examples/user_guide/Annotators.ipynb @@ -88,7 +88,7 @@ "metadata": {}, "outputs": [], "source": [ - "point_annotate.annotated.geom()" + "point_annotate.annotated.geom(projection=\"wgs84\")" ] }, { @@ -207,7 +207,7 @@ "metadata": {}, "outputs": [], "source": [ - "path_annotate.annotated.geom()" + "path_annotate.annotated.geom(projection=\"wgs84\")" ] }, { @@ -264,7 +264,7 @@ "metadata": {}, "outputs": [], "source": [ - "poly_annotate.annotated.iloc[0].geom()" + "poly_annotate.annotated.iloc[0].geom(projection=\"wgs84\")" ] } ], diff --git a/geoviews/element/geo.py b/geoviews/element/geo.py index 6ba428cd..81a0674a 100644 --- a/geoviews/element/geo.py +++ b/geoviews/element/geo.py @@ -41,7 +41,7 @@ from ..util import ( path_to_geom_dicts, polygons_to_geom_dicts, load_tiff, from_xarray, - poly_types, expand_geoms, transform_shapely_to_wsg84 + poly_types, expand_geoms, transform_shapely ) geographic_types = (GoogleTiles, cFeature, BaseGeometry) @@ -266,7 +266,7 @@ class Points(_Element, HvPoints): group = param.String(default='Points') - def geom(self, union=False): + def geom(self, union=False, projection=None): """ Converts the Points to a shapely geometry. @@ -274,6 +274,8 @@ def geom(self, union=False): ---------- union: boolean (default=False) Whether to compute a union between the geometries + projection : EPSG string | Cartopy CRS | None + Whether to project the geometry to other coordinate system Returns ------- @@ -287,7 +289,8 @@ def geom(self, union=False): geom = points[0] else: geom = MultiPoint(points) - geom = transform_shapely_to_wsg84(geom, self.crs) + if projection: + geom = transform_shapely(geom, self.crs, projection) return unary_union(geom) if union else geom @@ -519,7 +522,7 @@ class Path(_Element, HvPath): group = param.String(default='Path', constant=True) - def geom(self, union=False): + def geom(self, union=False, projection=None): """ Converts the Path to a shapely geometry. @@ -527,6 +530,8 @@ def geom(self, union=False): ---------- union: boolean (default=False) Whether to compute a union between the geometries + projection : EPSG string | Cartopy CRS | None + Whether to project the geometry to other coordinate system Returns ------- @@ -540,7 +545,8 @@ def geom(self, union=False): geom = geoms[0] else: geom = MultiLineString(geoms) - geom = transform_shapely_to_wsg84(geom, self.crs) + if projection: + geom = transform_shapely(geom, self.crs, projection) return unary_union(geom) if union else geom @@ -663,7 +669,7 @@ class Contours(_Element, HvContours): group = param.String(default='Contours', constant=True) - def geom(self, union=False): + def geom(self, union=False, projection=None): """ Converts the Contours to a shapely geometry. @@ -671,6 +677,8 @@ def geom(self, union=False): ---------- union: boolean (default=False) Whether to compute a union between the geometries + projection : EPSG string | Cartopy CRS | None + Whether to project the geometry to other coordinate system Returns ------- @@ -684,7 +692,8 @@ def geom(self, union=False): geom = geoms[0] else: geom = MultiLineString(geoms) - geom = transform_shapely_to_wsg84(geom, self.crs) + if projection: + geom = transform_shapely(geom, self.crs, projection) return unary_union(geom) if union else geom @@ -697,7 +706,7 @@ class Polygons(_Element, HvPolygons): group = param.String(default='Polygons', constant=True) - def geom(self, union=False): + def geom(self, union=False, projection=None): """ Converts the Path to a shapely geometry. @@ -705,6 +714,8 @@ def geom(self, union=False): ---------- union: boolean (default=False) Whether to compute a union between the geometries + projection : EPSG string | Cartopy CRS | None + Whether to project the geometry to other coordinate system Returns ------- @@ -718,7 +729,8 @@ def geom(self, union=False): geom = geoms[0] else: geom = MultiPolygon(geoms) - geom = transform_shapely_to_wsg84(geom, self.crs) + if projection: + geom = transform_shapely(geom, self.crs, projection) return unary_union(geom) if union else geom @@ -736,7 +748,7 @@ class Rectangles(_Element, HvRectangles): bottom-left (lon0, lat0) and top right (lon1, lat1) coordinates of each box.""") - def geom(self, union=False): + def geom(self, union=False, projection=None): """ Converts the Rectangles to a shapely geometry. @@ -744,6 +756,8 @@ def geom(self, union=False): ---------- union: boolean (default=False) Whether to compute a union between the geometries + projection : EPSG string | Cartopy CRS | None + Whether to project the geometry to other coordinate system Returns ------- @@ -757,7 +771,8 @@ def geom(self, union=False): geom = boxes[0] else: geom = MultiPolygon(boxes) - geom = transform_shapely_to_wsg84(geom, self.crs) + if projection: + geom = transform_shapely(geom, self.crs, projection) return unary_union(geom) if union else geom @@ -775,7 +790,7 @@ class Segments(_Element, HvSegments): bottom-left (lon0, lat0) and top-right (lon1, lat1) coordinates of each segment.""") - def geom(self, union=False): + def geom(self, union=False, projection=None): """ Converts the Segments to a shapely geometry. """ @@ -788,7 +803,8 @@ def geom(self, union=False): geom = lines[0] else: geom = MultiLineString(lines) - geom = transform_shapely_to_wsg84(geom, self.crs) + if projection: + geom = transform_shapely(geom, self.crs, projection) return unary_union(geom) if union else geom @@ -969,7 +985,7 @@ def from_records(cls, records, dataset=None, on=None, value=None, return element(data, vdims=kdims+vdims, **kwargs).opts(color=value) - def geom(self, union=False): + def geom(self, union=False, projection=None): """ Returns the Shape as a shapely geometry @@ -977,11 +993,14 @@ def geom(self, union=False): ---------- union: boolean (default=False) Whether to compute a union between the geometries + projection : EPSG string | Cartopy CRS | None + Whether to project the geometry to other coordinate system Returns ------- A shapely geometry """ geom = self.data['geometry'] - geom = transform_shapely_to_wsg84(geom, self.crs) + if projection: + geom = transform_shapely(geom, self.crs, projection) return unary_union(geom) if union else geom diff --git a/geoviews/util.py b/geoviews/util.py index 46427913..71dfb32a 100644 --- a/geoviews/util.py +++ b/geoviews/util.py @@ -11,7 +11,7 @@ from cartopy.io.img_tiles import GoogleTiles, QuadtreeTiles from holoviews.element import Tiles from packaging.version import Version -from pyproj import CRS, Transformer +from pyproj import Transformer from shapely.geometry import ( LinearRing, LineString, MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, box @@ -779,8 +779,10 @@ def get_tile_rgb(tile_source, bbox, zoom_level, bbox_crs=ccrs.PlateCarree()): ).clone(datatype=['grid', 'xarray', 'iris'])[l:r, b:t] -def transform_shapely_to_wsg84(geom, crs_from): - crs_to = CRS('WGS84') +def transform_shapely(geom, crs_from, crs_to): + if isinstance(crs_to, str): + crs_to = ccrs.CRS(crs_to) + if isinstance(crs_from, str): + crs_from = ccrs.CRS(crs_from) project = Transformer.from_crs(crs_from, crs_to).transform - flip = lambda x, y: (y, x) - return transform(flip, transform(project, geom)) + return transform(project, geom)