This is an automated email from the ASF dual-hosted git repository.
petern pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sedona.git
The following commit(s) were added to refs/heads/master by this push:
new 81adf486e5 [GH-2230] Implement GeoSeries.minimum_clearance (#2772)
81adf486e5 is described below
commit 81adf486e549f6d9234874c71ee0a28b00ab2e7b
Author: piyushka-ally <[email protected]>
AuthorDate: Tue Mar 24 21:07:02 2026 +0530
[GH-2230] Implement GeoSeries.minimum_clearance (#2772)
Co-authored-by: Piyush Kanti Chanda <[email protected]>
---
python/sedona/spark/geopandas/base.py | 28 ++++++++++++++++++++--
python/sedona/spark/geopandas/geoseries.py | 12 +++++++---
python/tests/geopandas/test_geoseries.py | 15 +++++++++++-
.../tests/geopandas/test_match_geopandas_series.py | 5 +++-
4 files changed, 53 insertions(+), 7 deletions(-)
diff --git a/python/sedona/spark/geopandas/base.py
b/python/sedona/spark/geopandas/base.py
index 7db50e7f8f..e406052c2a 100644
--- a/python/sedona/spark/geopandas/base.py
+++ b/python/sedona/spark/geopandas/base.py
@@ -1129,8 +1129,32 @@ class GeoFrame(metaclass=ABCMeta):
"""
return _delegate_to_geometry_column("minimum_bounding_radius", self)
- # def minimum_clearance(self):
- # raise NotImplementedError("This method is not implemented yet.")
+ def minimum_clearance(self) -> ps.Series:
+ """Return a ``Series`` containing the minimum clearance distance,
+ which is the smallest distance by which a vertex of the geometry
+ could be moved to produce an invalid geometry.
+
+ If no minimum clearance exists for a geometry (for example,
+ a single point, or an empty geometry), infinity is returned.
+
+ Examples
+ --------
+ >>> from sedona.spark.geopandas import GeoSeries
+ >>> from shapely.geometry import Polygon, LineString, Point
+ >>> s = GeoSeries(
+ ... [
+ ... Polygon([(0, 0), (1, 1), (0, 1), (0, 0)]),
+ ... LineString([(0, 0), (1, 1), (3, 2)]),
+ ... Point(0, 0),
+ ... ]
+ ... )
+ >>> s.minimum_clearance()
+ 0 0.707107
+ 1 1.414214
+ 2 inf
+ dtype: float64
+ """
+ return _delegate_to_geometry_column("minimum_clearance", self)
def normalize(self):
"""Return a ``GeoSeries`` of normalized geometries.
diff --git a/python/sedona/spark/geopandas/geoseries.py
b/python/sedona/spark/geopandas/geoseries.py
index 60b9fa29bf..231b82d144 100644
--- a/python/sedona/spark/geopandas/geoseries.py
+++ b/python/sedona/spark/geopandas/geoseries.py
@@ -15,6 +15,7 @@
# specific language governing permissions and limitations
# under the License.
+import sys
import typing
from typing import Any, Union, Literal, List
@@ -1081,9 +1082,14 @@ class GeoSeries(GeoFrame, pspd.Series):
returns_geom=False,
)
- def minimum_clearance(self):
- # Implementation of the abstract method.
- raise NotImplementedError("This method is not implemented yet.")
+ def minimum_clearance(self) -> pspd.Series:
+ spark_col = stf.ST_MinimumClearance(self.spark.column)
+ # JTS returns Double.MAX_VALUE for degenerate geometries (e.g. Point,
empty);
+ # convert to float('inf') to match geopandas/shapely behaviour.
+ spark_expr = F.when(
+ spark_col >= sys.float_info.max, F.lit(float("inf"))
+ ).otherwise(spark_col)
+ return self._query_geometry_column(spark_expr, returns_geom=False)
def normalize(self):
spark_expr = stf.ST_Normalize(self.spark.column)
diff --git a/python/tests/geopandas/test_geoseries.py
b/python/tests/geopandas/test_geoseries.py
index b61e8e5056..1486ab85da 100644
--- a/python/tests/geopandas/test_geoseries.py
+++ b/python/tests/geopandas/test_geoseries.py
@@ -1614,7 +1614,20 @@ e": "Feature", "properties": {}, "geometry": {"type":
"Point", "coordinates": [3
self.check_pd_series_equal(df_result, expected)
def test_minimum_clearance(self):
- pass
+ s = GeoSeries(
+ [
+ Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]),
+ Polygon([(0, 0), (0.5, 0), (0.5, 0.5), (0, 0.5)]),
+ MultiPoint([(1, 1), (1, 1)]),
+ ]
+ )
+ expected = pd.Series([1.0, 0.5, float("inf")])
+ result = s.minimum_clearance()
+ self.check_pd_series_equal(result, expected)
+
+ gdf = s.to_geoframe()
+ df_result = gdf.minimum_clearance()
+ self.check_pd_series_equal(df_result, expected)
def test_normalize(self):
s = GeoSeries(
diff --git a/python/tests/geopandas/test_match_geopandas_series.py
b/python/tests/geopandas/test_match_geopandas_series.py
index 3138e8c267..372e66f737 100644
--- a/python/tests/geopandas/test_match_geopandas_series.py
+++ b/python/tests/geopandas/test_match_geopandas_series.py
@@ -851,7 +851,10 @@ class TestMatchGeopandasSeries(TestGeopandasBase):
self.check_pd_series_equal(sgpd_result, gpd_result)
def test_minimum_clearance(self):
- pass
+ for geom in self.geoms:
+ sgpd_result = GeoSeries(geom).minimum_clearance()
+ gpd_result = gpd.GeoSeries(geom).minimum_clearance()
+ self.check_pd_series_equal(sgpd_result, gpd_result)
def test_normalize(self):
for geom in self.geoms: