This commit is contained in:
2025-01-26 19:24:23 -08:00
parent 32cd60e92b
commit d1dde0dbc6
4155 changed files with 29170 additions and 216373 deletions

View File

@@ -5,11 +5,13 @@ geopandas.clip
A module to clip vector data using GeoPandas.
"""
import warnings
import numpy as np
import pandas.api.types
from shapely.geometry import Polygon, MultiPolygon, box
from shapely.geometry import MultiPolygon, Polygon, box
from geopandas import GeoDataFrame, GeoSeries
from geopandas.array import _check_crs, _crs_mismatch_warn
@@ -21,7 +23,7 @@ def _mask_is_list_like_rectangle(mask):
)
def _clip_gdf_with_mask(gdf, mask):
def _clip_gdf_with_mask(gdf, mask, sort=False):
"""Clip geometry to the polygon/rectangle extent.
Clip an input GeoDataFrame to the polygon extent of the polygon
@@ -35,6 +37,10 @@ def _clip_gdf_with_mask(gdf, mask):
mask : (Multi)Polygon, list-like
Reference polygon/rectangle for clipping.
sort : boolean, default False
If True, the results will be sorted in ascending order using the
geometries' indexes as the primary key.
Returns
-------
GeoDataFrame
@@ -47,7 +53,9 @@ def _clip_gdf_with_mask(gdf, mask):
else:
intersection_polygon = mask
gdf_sub = gdf.iloc[gdf.sindex.query(intersection_polygon, predicate="intersects")]
gdf_sub = gdf.iloc[
gdf.sindex.query(intersection_polygon, predicate="intersects", sort=sort)
]
# For performance reasons points don't need to be intersected with poly
non_point_mask = gdf_sub.geom_type != "Point"
@@ -60,13 +68,13 @@ def _clip_gdf_with_mask(gdf, mask):
if isinstance(gdf_sub, GeoDataFrame):
clipped = gdf_sub.copy()
if clipping_by_rectangle:
clipped.loc[
non_point_mask, clipped._geometry_column_name
] = gdf_sub.geometry.values[non_point_mask].clip_by_rect(*mask)
clipped.loc[non_point_mask, clipped._geometry_column_name] = (
gdf_sub.geometry.values[non_point_mask].clip_by_rect(*mask)
)
else:
clipped.loc[
non_point_mask, clipped._geometry_column_name
] = gdf_sub.geometry.values[non_point_mask].intersection(mask)
clipped.loc[non_point_mask, clipped._geometry_column_name] = (
gdf_sub.geometry.values[non_point_mask].intersection(mask)
)
else:
# GeoSeries
clipped = gdf_sub.copy()
@@ -81,7 +89,7 @@ def _clip_gdf_with_mask(gdf, mask):
return clipped
def clip(gdf, mask, keep_geom_type=False):
def clip(gdf, mask, keep_geom_type=False, sort=False):
"""Clip points, lines, or polygon geometries to the mask extent.
Both layers must be in the same Coordinate Reference System (CRS).
@@ -112,6 +120,9 @@ def clip(gdf, mask, keep_geom_type=False):
If True, return only geometries of original type in case of intersection
resulting in multiple geometry types or GeometryCollections.
If False, return all resulting geometries (potentially mixed-types).
sort : boolean, default False
If True, the results will be sorted in ascending order using the
geometries' indexes as the primary key.
Returns
-------
@@ -185,11 +196,11 @@ def clip(gdf, mask, keep_geom_type=False):
return gdf.iloc[:0]
if isinstance(mask, (GeoDataFrame, GeoSeries)):
combined_mask = mask.geometry.unary_union
combined_mask = mask.geometry.union_all()
else:
combined_mask = mask
clipped = _clip_gdf_with_mask(gdf, combined_mask)
clipped = _clip_gdf_with_mask(gdf, combined_mask, sort=sort)
if keep_geom_type:
geomcoll_concat = (clipped.geom_type == "GeometryCollection").any()