From df3ec135e2070d01e61c37c0998e4550ef8730a7 Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Mon, 2 Dec 2024 19:42:31 +0100 Subject: [PATCH 1/6] exposures: appropriate error message in latitude/longitude --- climada/entity/exposures/base.py | 30 +++++++++++++++++++-- climada/entity/exposures/test/test_base.py | 31 +++++++++++++++++++++- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/climada/entity/exposures/base.py b/climada/entity/exposures/base.py index 0c62af1b53..3318141d06 100644 --- a/climada/entity/exposures/base.py +++ b/climada/entity/exposures/base.py @@ -132,12 +132,38 @@ def gdf(self): @property def latitude(self): """Latitude array of exposures""" - return self.data.geometry.y.values + try: + return self.data.geometry.y.values + except ValueError as valerr: + nonpoints = list( + self.data[ + self.data.geometry.type != "Point" + ].geometry.type.drop_duplicates() + ) + if nonpoints: + raise ValueError( + "Can only calculate latitude from Points." + f" GeoDataFrame contains {', '.join(nonpoints)}" + ) from valerr + raise @property def longitude(self): """Longitude array of exposures""" - return self.data.geometry.x.values + try: + return self.data.geometry.x.values + except ValueError as valerr: + nonpoints = list( + self.data[ + self.data.geometry.type != "Point" + ].geometry.type.drop_duplicates() + ) + if nonpoints: + raise ValueError( + "Can only calculate longitude from Points." + f" GeoDataFrame contains {', '.join(nonpoints)}" + ) from valerr + raise @property def geometry(self): diff --git a/climada/entity/exposures/test/test_base.py b/climada/entity/exposures/test/test_base.py index 7c79f4a22d..de2552b31d 100644 --- a/climada/entity/exposures/test/test_base.py +++ b/climada/entity/exposures/test/test_base.py @@ -27,7 +27,7 @@ import rasterio import scipy as sp from rasterio.windows import Window -from shapely.geometry import Point +from shapely.geometry import MultiPolygon, Point, Polygon from sklearn.metrics import DistanceMetric import climada.util.coordinates as u_coord @@ -652,6 +652,35 @@ def test_to_crs_epsg_crs(self): Exposures.to_crs(self, crs="GCS", epsg=26915) self.assertEqual("one of crs or epsg must be None", str(cm.exception)) + def test_latlon_with_polygons(self): + """Check for proper error message if the data frame contains non-Point shapes""" + poly = Polygon( + [(10.0, 0.0), (10.0, 1.0), (11.0, 1.0), (11.0, 0.0), (10.0, 0.0)] + ) + point = Point((1, -1)) + multi = MultiPolygon( + [ + ( + ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)), + [((0.1, 1.1), (0.1, 1.2), (0.2, 1.2), (0.2, 1.1))], + ) + ] + ) + poly = Polygon() + exp = Exposures(geometry=[poly, point, multi, poly]) + with self.assertRaises(ValueError) as valer: + exp.latitude + self.assertEqual( + "Can only calculate latitude from Points. GeoDataFrame contains Polygon, MulitPolygon", + str(valer.exception), + ) + with self.assertRaises(ValueError) as valer: + exp.longitude + self.assertEqual( + "Can only calculate latitude from Points. GeoDataFrame contains Polygon, MulitPolygon", + str(valer.exception), + ) + class TestImpactFunctions(unittest.TestCase): """Test impact function handling""" From e8e3646bfd2bf7dd2fc464565902365309ad4857 Mon Sep 17 00:00:00 2001 From: Emanuel Schmid <51439563+emanuel-schmid@users.noreply.github.com> Date: Mon, 2 Dec 2024 19:56:51 +0100 Subject: [PATCH 2/6] Update test_base.py fix typo --- climada/entity/exposures/test/test_base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/climada/entity/exposures/test/test_base.py b/climada/entity/exposures/test/test_base.py index de2552b31d..04d84ff8e1 100644 --- a/climada/entity/exposures/test/test_base.py +++ b/climada/entity/exposures/test/test_base.py @@ -671,13 +671,13 @@ def test_latlon_with_polygons(self): with self.assertRaises(ValueError) as valer: exp.latitude self.assertEqual( - "Can only calculate latitude from Points. GeoDataFrame contains Polygon, MulitPolygon", + "Can only calculate latitude from Points. GeoDataFrame contains Polygon, MultiPolygon", str(valer.exception), ) with self.assertRaises(ValueError) as valer: exp.longitude self.assertEqual( - "Can only calculate latitude from Points. GeoDataFrame contains Polygon, MulitPolygon", + "Can only calculate latitude from Points. GeoDataFrame contains Polygon, MultiPolygon", str(valer.exception), ) From c71db3c02e7b1c267e29345accf381eadc8b9c06 Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Mon, 2 Dec 2024 20:19:54 +0100 Subject: [PATCH 3/6] typo --- climada/entity/exposures/test/test_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/climada/entity/exposures/test/test_base.py b/climada/entity/exposures/test/test_base.py index 04d84ff8e1..f8c8db1f86 100644 --- a/climada/entity/exposures/test/test_base.py +++ b/climada/entity/exposures/test/test_base.py @@ -677,7 +677,7 @@ def test_latlon_with_polygons(self): with self.assertRaises(ValueError) as valer: exp.longitude self.assertEqual( - "Can only calculate latitude from Points. GeoDataFrame contains Polygon, MultiPolygon", + "Can only calculate longitude from Points. GeoDataFrame contains Polygon, MultiPolygon", str(valer.exception), ) From e40c1720149907c56f2c4c3a813acd56b6578026 Mon Sep 17 00:00:00 2001 From: Emanuel Schmid <51439563+emanuel-schmid@users.noreply.github.com> Date: Wed, 11 Dec 2024 18:01:54 +0100 Subject: [PATCH 4/6] add hint to error message Co-authored-by: Chahan M. Kropf --- climada/entity/exposures/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/climada/entity/exposures/base.py b/climada/entity/exposures/base.py index 3318141d06..df73a4da1b 100644 --- a/climada/entity/exposures/base.py +++ b/climada/entity/exposures/base.py @@ -162,6 +162,7 @@ def longitude(self): raise ValueError( "Can only calculate longitude from Points." f" GeoDataFrame contains {', '.join(nonpoints)}" + "Please see the lines_polygons module tutorial." ) from valerr raise From 1474b8112ccb749fb111b5eedb8ce99b2e85a271 Mon Sep 17 00:00:00 2001 From: Emanuel Schmid <51439563+emanuel-schmid@users.noreply.github.com> Date: Wed, 11 Dec 2024 18:02:54 +0100 Subject: [PATCH 5/6] add hint to error message Co-authored-by: Chahan M. Kropf --- climada/entity/exposures/base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/climada/entity/exposures/base.py b/climada/entity/exposures/base.py index df73a4da1b..031b65effc 100644 --- a/climada/entity/exposures/base.py +++ b/climada/entity/exposures/base.py @@ -143,7 +143,8 @@ def latitude(self): if nonpoints: raise ValueError( "Can only calculate latitude from Points." - f" GeoDataFrame contains {', '.join(nonpoints)}" + f" GeoDataFrame contains {', '.join(nonpoints)}." + "Please see the lines_polygons module tutorial." ) from valerr raise From 1490603a331ca715c2c038d0f586c33d1eaed152 Mon Sep 17 00:00:00 2001 From: emanuel-schmid Date: Fri, 13 Dec 2024 12:31:45 +0100 Subject: [PATCH 6/6] adjust test string and fix whitespace --- climada/entity/exposures/base.py | 6 +++--- climada/entity/exposures/test/test_base.py | 8 ++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/climada/entity/exposures/base.py b/climada/entity/exposures/base.py index 031b65effc..9575e746b2 100644 --- a/climada/entity/exposures/base.py +++ b/climada/entity/exposures/base.py @@ -144,7 +144,7 @@ def latitude(self): raise ValueError( "Can only calculate latitude from Points." f" GeoDataFrame contains {', '.join(nonpoints)}." - "Please see the lines_polygons module tutorial." + " Please see the lines_polygons module tutorial." ) from valerr raise @@ -162,8 +162,8 @@ def longitude(self): if nonpoints: raise ValueError( "Can only calculate longitude from Points." - f" GeoDataFrame contains {', '.join(nonpoints)}" - "Please see the lines_polygons module tutorial." + f" GeoDataFrame contains {', '.join(nonpoints)}." + " Please see the lines_polygons module tutorial." ) from valerr raise diff --git a/climada/entity/exposures/test/test_base.py b/climada/entity/exposures/test/test_base.py index f8c8db1f86..66e921cd46 100644 --- a/climada/entity/exposures/test/test_base.py +++ b/climada/entity/exposures/test/test_base.py @@ -671,13 +671,17 @@ def test_latlon_with_polygons(self): with self.assertRaises(ValueError) as valer: exp.latitude self.assertEqual( - "Can only calculate latitude from Points. GeoDataFrame contains Polygon, MultiPolygon", + "Can only calculate latitude from Points." + " GeoDataFrame contains Polygon, MultiPolygon." + " Please see the lines_polygons module tutorial.", str(valer.exception), ) with self.assertRaises(ValueError) as valer: exp.longitude self.assertEqual( - "Can only calculate longitude from Points. GeoDataFrame contains Polygon, MultiPolygon", + "Can only calculate longitude from Points." + " GeoDataFrame contains Polygon, MultiPolygon." + " Please see the lines_polygons module tutorial.", str(valer.exception), )