Repository: geopandas/geopandas

Issue:
BUG: clip GeoSeries by non-overlapping mask raises error
Clipping GeoSeries by non-overlapping `mask` raises error as we try to return GeoDataFrame with original columns in here: https://github.com/geopandas/geopandas/blob/7350b49688f51b281f69638c8c51a448a0115fb0/geopandas/tools/clip.py#L155

In case of GeoSeries we should return empty GeoSeries I would say.
MRE:

```py
import geopandas as gpd
from shapely.geometry import Point

s = gpd.GeoSeries([Point(0,0), Point(1,1)])
mask = Point(10, 10).buffer(2)
gpd.clip(s, mask)
```


<details>

```
~/Dropbox/Python/geopandas/martinfleis/geopandas/tools/clip.py in clip(gdf, mask, keep_geom_type)
    153         and ((box_mask[1] <= box_gdf[3]) and (box_gdf[1] <= box_mask[3]))
    154     ):
--> 155         return GeoDataFrame(columns=gdf.columns, crs=gdf.crs)
    156 
    157     if isinstance(mask, (GeoDataFrame, GeoSeries)):

~/anaconda3/envs/geo_dev/lib/python3.8/site-packages/pandas/core/generic.py in __getattr__(self, name)
   5173             or name in self._accessors
   5174         ):
-> 5175             return object.__getattribute__(self, name)
   5176         else:
   5177             if self._info_axis._can_hold_identifiers_and_holds_name(name):

AttributeError: 'GeoSeries' object has no attribute 'columns'
```

</details>



Discussion:

Resolving patch:
diff --git a/geopandas/tools/clip.py b/geopandas/tools/clip.py
--- a/geopandas/tools/clip.py
+++ b/geopandas/tools/clip.py
@@ -152,7 +152,11 @@ def clip(gdf, mask, keep_geom_type=False):
         ((box_mask[0] <= box_gdf[2]) and (box_gdf[0] <= box_mask[2]))
         and ((box_mask[1] <= box_gdf[3]) and (box_gdf[1] <= box_mask[3]))
     ):
-        return GeoDataFrame(columns=gdf.columns, crs=gdf.crs)
+        return (
+            GeoDataFrame(columns=gdf.columns, crs=gdf.crs)
+            if isinstance(gdf, GeoDataFrame)
+            else GeoSeries(crs=gdf.crs)
+        )
 
     if isinstance(mask, (GeoDataFrame, GeoSeries)):
         poly = mask.geometry.unary_union


Test patch:
diff --git a/geopandas/tools/tests/test_clip.py b/geopandas/tools/tests/test_clip.py
--- a/geopandas/tools/tests/test_clip.py
+++ b/geopandas/tools/tests/test_clip.py
@@ -9,7 +9,7 @@
 
 import geopandas
 from geopandas import GeoDataFrame, GeoSeries, clip
-from geopandas.testing import assert_geodataframe_equal
+from geopandas.testing import assert_geodataframe_equal, assert_geoseries_equal
 
 import pytest
 
@@ -159,7 +159,7 @@ def test_returns_series(point_gdf, single_rectangle_gdf):
 
 
 def test_non_overlapping_geoms():
-    """Test that a bounding box returns error if the extents don't overlap"""
+    """Test that a bounding box returns empty if the extents don't overlap"""
     unit_box = Polygon([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)])
     unit_gdf = GeoDataFrame([1], geometry=[unit_box], crs="EPSG:4326")
     non_overlapping_gdf = unit_gdf.copy()
@@ -170,6 +170,8 @@ def test_non_overlapping_geoms():
     assert_geodataframe_equal(
         out, GeoDataFrame(columns=unit_gdf.columns, crs=unit_gdf.crs)
     )
+    out2 = clip(unit_gdf.geometry, non_overlapping_gdf)
+    assert_geoseries_equal(out2, GeoSeries(crs=unit_gdf.crs))
 
 
 def test_clip_points(point_gdf, single_rectangle_gdf):