Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions python/sedona/spark/geopandas/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,6 @@ def is_ring(self):
"""
return _delegate_to_geometry_column("is_ring", self)

# @property
# def is_ccw(self):
# raise NotImplementedError("This method is not implemented yet.")

Expand Down Expand Up @@ -1129,8 +1128,33 @@ def minimum_bounding_radius(self):
"""
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 the minimum clearance of each geometry.

The minimum clearance is the smallest distance by which a vertex of
a geometry could be moved to produce an invalid geometry. A larger
value indicates a more robust geometry.

Returns
-------
Series of float64

Examples
--------
>>> from sedona.spark.geopandas import GeoSeries
>>> from shapely.geometry import Polygon
>>> s = GeoSeries(
... [
... Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]),
... Polygon([(0, 0), (0.5, 0), (0.5, 0.5), (0, 0.5)]),
... ]
... )
>>> s.minimum_clearance()
0 1.0
1 0.5
dtype: float64
"""
return _delegate_to_geometry_column("minimum_clearance", self)

def normalize(self):
"""Return a ``GeoSeries`` of normalized geometries.
Expand Down
12 changes: 9 additions & 3 deletions python/sedona/spark/geopandas/geoseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# specific language governing permissions and limitations
# under the License.

import sys
import typing
from typing import Any, Union, Literal, List

Expand Down Expand Up @@ -1077,9 +1078,14 @@ def minimum_bounding_radius(self) -> 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)
Expand Down
14 changes: 13 additions & 1 deletion python/tests/geopandas/test_geoseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -1614,7 +1614,19 @@ def test_minimum_bounding_radius(self):
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)]),
]
)
expected = pd.Series([1.0, 0.5])
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(
Expand Down
5 changes: 4 additions & 1 deletion python/tests/geopandas/test_match_geopandas_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,10 @@ def test_minimum_bounding_radius(self):
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:
Expand Down