From 28b90bc6e8f2c87f321fff1b846b4db53f32f842 Mon Sep 17 00:00:00 2001 From: Carson Farmer Date: Tue, 15 Oct 2013 11:28:34 -0400 Subject: [PATCH 1/3] changing the way 'bounds' is implemented to match shapely --- geopandas/geoseries.py | 18 ++++++++++++++++-- tests/test_geoseries.py | 9 +++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/geopandas/geoseries.py b/geopandas/geoseries.py index f1886bf..9ee25a5 100644 --- a/geopandas/geoseries.py +++ b/geopandas/geoseries.py @@ -295,14 +295,28 @@ class GeoSeries(Series): # Other operations # - # should this return bounds for entire series, or elementwise? @property - def bounds(self): + def element_bounds(self): """Return a DataFrame of minx, miny, maxx, maxy values of geometry objects""" bounds = np.array([geom.bounds for geom in self]) return DataFrame(bounds, columns=['minx', 'miny', 'maxx', 'maxy'], index=self.index) + + @property + def bounds(self): + """Return a single bounding box (minx, miny, maxx, maxy) for all geometries + + This is a shortcut for the following: + >>> aggregator = dict(minx=np.nanmin, miny=np.nanmin, + maxx=np.nanmax, maxy=np.nanmax) + >>> series.bounds.groupby(lambda x: 1).agg(aggregator) + + """ + aggregator = dict(minx=np.nanmin, miny=np.nanmin, + maxx=np.nanmax, maxy=np.nanmax) + bbox = self.element_bounds.groupby(lambda x: 1).agg(aggregator) + return tuple(bbox.values[0].tolist()) def buffer(self, distance, resolution=16): return GeoSeries([geom.buffer(distance, resolution) for geom in self], diff --git a/tests/test_geoseries.py b/tests/test_geoseries.py index 059af50..e679b69 100644 --- a/tests/test_geoseries.py +++ b/tests/test_geoseries.py @@ -81,8 +81,8 @@ class TestSeries(unittest.TestCase): self.assertTrue(b[0].equals(l1)) self.assertTrue(b[1].equals(l2)) - def test_bounds(self): - assert_array_equal(self.g1.bounds.values, np.array([[0, 0, 1, 1], + def test_element_bounds(self): + assert_array_equal(self.g1.element_bounds.values, np.array([[0, 0, 1, 1], [0, 0, 1, 1]])) def test_contains(self): @@ -285,4 +285,9 @@ class TestSeries(unittest.TestCase): res = self.g4.skew(ys=skew, origin=Point(0,0)) self.assertTrue(geom_almost_equals(self.g4, res.skew(ys=-skew, origin=Point(0,0)))) + + def test_bounds(self): + bbox = self.sol.x, self.sol.y, self.esb.x, self.esb.y + self.assertEqual(self.landmarks.bounds, bbox) + self.assertEqual(self.g1.bounds, (0, 0, 1, 1)) From 4e5639f5a431478124a17416873f15d2946f1ab3 Mon Sep 17 00:00:00 2001 From: Carson Farmer Date: Fri, 18 Oct 2013 16:32:52 -0400 Subject: [PATCH 2/3] return to original bounds name and create total_bounds property --- geopandas/geoseries.py | 9 +++++---- tests/test_geoseries.py | 10 +++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/geopandas/geoseries.py b/geopandas/geoseries.py index 9ee25a5..86d6fd4 100644 --- a/geopandas/geoseries.py +++ b/geopandas/geoseries.py @@ -5,6 +5,7 @@ import fiona from fiona.crs import from_epsg import numpy as np from pandas import Series, DataFrame +from pandas.util.decorators import cache_readonly import pyproj from shapely.geometry import shape, Polygon, Point from shapely.geometry.collection import GeometryCollection @@ -296,23 +297,23 @@ class GeoSeries(Series): # @property - def element_bounds(self): + def bounds(self): """Return a DataFrame of minx, miny, maxx, maxy values of geometry objects""" bounds = np.array([geom.bounds for geom in self]) return DataFrame(bounds, columns=['minx', 'miny', 'maxx', 'maxy'], index=self.index) - @property - def bounds(self): + @cache_readonly + def total_bounds(self): """Return a single bounding box (minx, miny, maxx, maxy) for all geometries This is a shortcut for the following: >>> aggregator = dict(minx=np.nanmin, miny=np.nanmin, maxx=np.nanmax, maxy=np.nanmax) >>> series.bounds.groupby(lambda x: 1).agg(aggregator) - """ + aggregator = dict(minx=np.nanmin, miny=np.nanmin, maxx=np.nanmax, maxy=np.nanmax) bbox = self.element_bounds.groupby(lambda x: 1).agg(aggregator) diff --git a/tests/test_geoseries.py b/tests/test_geoseries.py index e679b69..5137b38 100644 --- a/tests/test_geoseries.py +++ b/tests/test_geoseries.py @@ -81,8 +81,8 @@ class TestSeries(unittest.TestCase): self.assertTrue(b[0].equals(l1)) self.assertTrue(b[1].equals(l2)) - def test_element_bounds(self): - assert_array_equal(self.g1.element_bounds.values, np.array([[0, 0, 1, 1], + def test_bounds(self): + assert_array_equal(self.g1.bounds.values, np.array([[0, 0, 1, 1], [0, 0, 1, 1]])) def test_contains(self): @@ -286,8 +286,8 @@ class TestSeries(unittest.TestCase): self.assertTrue(geom_almost_equals(self.g4, res.skew(ys=-skew, origin=Point(0,0)))) - def test_bounds(self): + def test_total_bounds(self): bbox = self.sol.x, self.sol.y, self.esb.x, self.esb.y - self.assertEqual(self.landmarks.bounds, bbox) - self.assertEqual(self.g1.bounds, (0, 0, 1, 1)) + self.assertEqual(self.landmarks.total_bounds, bbox) + self.assertEqual(self.g1.total_bounds, (0, 0, 1, 1)) From 6b011b7b20b3c27357bb05c5c9718cf66de99521 Mon Sep 17 00:00:00 2001 From: Carson Farmer Date: Fri, 18 Oct 2013 16:36:31 -0400 Subject: [PATCH 3/3] fix typo --- geopandas/geoseries.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geopandas/geoseries.py b/geopandas/geoseries.py index 86d6fd4..28e85d8 100644 --- a/geopandas/geoseries.py +++ b/geopandas/geoseries.py @@ -316,7 +316,7 @@ class GeoSeries(Series): aggregator = dict(minx=np.nanmin, miny=np.nanmin, maxx=np.nanmax, maxy=np.nanmax) - bbox = self.element_bounds.groupby(lambda x: 1).agg(aggregator) + bbox = self.bounds.groupby(lambda x: 1).agg(aggregator) return tuple(bbox.values[0].tolist()) def buffer(self, distance, resolution=16):