Skip to content

Commit

Permalink
BUG: Set operators are inconsistently handled (#1255)
Browse files Browse the repository at this point in the history
  • Loading branch information
martinfleis committed Apr 19, 2020
1 parent 708b38e commit d550bb9
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
20 changes: 20 additions & 0 deletions geopandas/geodataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,26 @@ def astype(self, dtype, copy=True, errors="raise", **kwargs):
# do not return a GeoDataFrame
return pd.DataFrame(df)

#
# Implement standard operators for GeoSeries
#

def __xor__(self, other):
"""Implement ^ operator as for builtin set type"""
return self.geometry.symmetric_difference(other)

def __or__(self, other):
"""Implement | operator as for builtin set type"""
return self.geometry.union(other)

def __and__(self, other):
"""Implement & operator as for builtin set type"""
return self.geometry.intersection(other)

def __sub__(self, other):
"""Implement - operator as for builtin set type"""
return self.geometry.difference(other)


def _dataframe_set_geometry(self, col, drop=False, inplace=False, crs=None):
if inplace:
Expand Down
12 changes: 10 additions & 2 deletions geopandas/tests/test_geom_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ def setup_method(self):
self.gdf2 = GeoDataFrame(
{"geometry": self.g1, "col3": [4, 5], "col4": ["rand", "string"]}
)
self.gdf3 = GeoDataFrame(
{"geometry": self.g3, "col3": [4, 5], "col4": ["rand", "string"]}
)

def _test_unary_real(self, op, expected, a):
""" Tests for 'area', 'length', 'is_valid', etc. """
Expand Down Expand Up @@ -123,6 +126,7 @@ def _test_binary_operator(self, op, expected, a, b):
"""
The operators only have GeoSeries on the left, but can have
GeoSeries or GeoDataFrame on the right.
If GeoDataFrame is on the left, geometry column is used.
"""
if isinstance(expected, GeoPandasBase):
Expand Down Expand Up @@ -655,25 +659,29 @@ def test_explode_geodataframe(self, index_name):

#
# Test '&', '|', '^', and '-'
# The left can only be a GeoSeries. The right hand side can be a
# GeoSeries, GeoDataFrame or Shapely geometry
#
def test_intersection_operator(self):
self._test_binary_operator("__and__", self.t1, self.g1, self.g2)
self._test_binary_operator("__and__", self.t1, self.gdf1, self.g2)

def test_union_operator(self):
self._test_binary_operator("__or__", self.sq, self.g1, self.g2)
self._test_binary_operator("__or__", self.sq, self.gdf1, self.g2)

def test_union_operator_polygon(self):
self._test_binary_operator("__or__", self.sq, self.g1, self.t2)
self._test_binary_operator("__or__", self.sq, self.gdf1, self.t2)

def test_symmetric_difference_operator(self):
self._test_binary_operator("__xor__", self.sq, self.g3, self.g4)
self._test_binary_operator("__xor__", self.sq, self.gdf3, self.g4)

def test_difference_series2(self):
expected = GeoSeries([GeometryCollection(), self.t2])
self._test_binary_operator("__sub__", expected, self.g1, self.g2)
self._test_binary_operator("__sub__", expected, self.gdf1, self.g2)

def test_difference_poly2(self):
expected = GeoSeries([self.t1, self.t1])
self._test_binary_operator("__sub__", expected, self.g1, self.t2)
self._test_binary_operator("__sub__", expected, self.gdf1, self.t2)

0 comments on commit d550bb9

Please sign in to comment.