From 12272620333d512bd695a28bb9e867dce8e00de6 Mon Sep 17 00:00:00 2001 From: Kelsey Jordahl Date: Tue, 2 Jul 2013 18:42:53 -0400 Subject: [PATCH 1/5] Implement __contains__ operator --- geopandas/geoseries.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/geopandas/geoseries.py b/geopandas/geoseries.py index 0a775d1..41811a0 100644 --- a/geopandas/geoseries.py +++ b/geopandas/geoseries.py @@ -341,6 +341,22 @@ class GeoSeries(Series): def project(self, *args, **kwargs): raise NotImplementedError + # + # Implement standard operators for GeoSeries + # + + def __contains__(self, other): + """ + Allow tests of the form "geom in s" to test whether a GeoSeries + contains a geometry. + + Note: This is not the same as the geometric method "contains". + """ + if isinstance(other, BaseGeometry): + return np.any(self.equals(other)) + else: + return False + # # Implement pandas methods # From 612ad3447945a07243039e3856fb035413d77e19 Mon Sep 17 00:00:00 2001 From: Kelsey Jordahl Date: Tue, 2 Jul 2013 18:46:32 -0400 Subject: [PATCH 2/5] Test for __contains__ method --- tests/test_geoseries.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_geoseries.py b/tests/test_geoseries.py index 530155d..d341bda 100644 --- a/tests/test_geoseries.py +++ b/tests/test_geoseries.py @@ -22,6 +22,12 @@ class TestSeries(unittest.TestCase): def test_area(self): assert np.allclose(self.g1.area.values, np.array([0.5, 1.0])) + def test_in(self): + assert self.t1 in self.g1 + assert self.sq in self.g1 + assert self.t1 in self.a1 + assert self.t2 in self.g3 + def test_boundary(self): l1 = LineString([(0, 0), (1, 0), (1, 1), (0, 0)]) l2 = LineString([(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)]) From 172282e50139ca271a4c19c7eb26b766567adf75 Mon Sep 17 00:00:00 2001 From: Kelsey Jordahl Date: Tue, 2 Jul 2013 21:38:07 -0400 Subject: [PATCH 3/5] Implement standard set operators ^ | & - --- geopandas/geoseries.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/geopandas/geoseries.py b/geopandas/geoseries.py index 41811a0..4d7207b 100644 --- a/geopandas/geoseries.py +++ b/geopandas/geoseries.py @@ -357,6 +357,34 @@ class GeoSeries(Series): else: return False + def __xor__(self, other): + """ + The ^ operator implements symmetric_difference() as it does + for the builtin set type. + """ + return self.symmetric_difference(other) + + def __or__(self, other): + """ + The | operator implements union() as it does + for the builtin set type. + """ + return self.union(other) + + def __and__(self, other): + """ + The & operator implements intersection() as it does + for the builtin set type. + """ + return self.intersection(other) + + def __sub__(self, other): + """ + The - operator implements difference() as it does + for the builtin set type. + """ + return self.difference(other) + # # Implement pandas methods # From f47d13f69ec8bb9659b510900b355add6350d69a Mon Sep 17 00:00:00 2001 From: Kelsey Jordahl Date: Tue, 2 Jul 2013 21:38:25 -0400 Subject: [PATCH 4/5] Tests for set operators --- tests/test_geoseries.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/tests/test_geoseries.py b/tests/test_geoseries.py index d341bda..39b8657 100644 --- a/tests/test_geoseries.py +++ b/tests/test_geoseries.py @@ -4,6 +4,15 @@ from shapely.geometry import Polygon, Point, LineString from geopandas import GeoSeries +def geom_equals(this, that): + """ + Test for geometric equality, allowing all empty geometries to be considered equal + """ + empty = np.logical_and(this.is_empty, that.is_empty) + eq = this.equals(that) + return np.all(np.logical_or(eq, empty)) + + class TestSeries(unittest.TestCase): def setUp(self): @@ -99,27 +108,30 @@ class TestSeries(unittest.TestCase): u = self.g1.union(self.g2) assert u[0].equals(self.sq) assert u[1].equals(self.sq) + assert geom_equals(u, self.g1 | self.g2) def test_union_polgon(self): u = self.g1.union(self.t2) assert u[0].equals(self.sq) assert u[1].equals(self.sq) - def test_difference_series(self): - u = self.g1.difference(self.g2) - assert u[0].is_empty - assert u[1].equals(self.t2) - def test_symmetric_difference_series(self): u = self.g3.symmetric_difference(self.g4) assert u[0].equals(self.sq) assert u[1].equals(self.sq) + assert geom_equals(u, self.g3 ^ self.g4) def test_symmetric_difference_poly(self): u = self.g3.symmetric_difference(self.t1) assert u[0].is_empty assert u[1].equals(self.sq) + def test_difference_series(self): + u = self.g1.difference(self.g2) + assert u[0].is_empty + assert u[1].equals(self.t2) + assert geom_equals(u, self.g1 - self.g2) + def test_difference_poly(self): u = self.g1.difference(self.t2) assert u[0].equals(self.t1) From 299803a547b088c3ca2cacbf68d1de563c43a561 Mon Sep 17 00:00:00 2001 From: Kelsey Jordahl Date: Tue, 2 Jul 2013 21:44:45 -0400 Subject: [PATCH 5/5] Add intersection test --- tests/test_geoseries.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_geoseries.py b/tests/test_geoseries.py index 39b8657..b5a15ae 100644 --- a/tests/test_geoseries.py +++ b/tests/test_geoseries.py @@ -104,6 +104,9 @@ class TestSeries(unittest.TestCase): # TODO pass + def test_intersection(self): + assert geom_equals(self.g1 & self.g2, self.t1) + def test_union_series(self): u = self.g1.union(self.g2) assert u[0].equals(self.sq)