This is an automated email from the ASF dual-hosted git repository.
jiayu 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 7005e6e925 [GH-2231] Implement is_ring (#2232)
7005e6e925 is described below
commit 7005e6e925b81faa10aa144c1426fabdc4520338
Author: Peter Nguyen <[email protected]>
AuthorDate: Tue Aug 5 20:49:56 2025 -0700
[GH-2231] Implement is_ring (#2232)
* Implement is_ring
* Also add test for geodataframe
* Update python/tests/geopandas/test_match_geopandas_series.py
Co-authored-by: Copilot <[email protected]>
---------
Co-authored-by: Jia Yu <[email protected]>
Co-authored-by: Copilot <[email protected]>
---
python/sedona/spark/geopandas/base.py | 38 ++++++++++++++++++++--
python/sedona/spark/geopandas/geoseries.py | 10 +++---
python/tests/geopandas/test_geoseries.py | 15 ++++++++-
.../tests/geopandas/test_match_geopandas_series.py | 6 +++-
4 files changed, 59 insertions(+), 10 deletions(-)
diff --git a/python/sedona/spark/geopandas/base.py
b/python/sedona/spark/geopandas/base.py
index 7bbc048651..e22c5f876e 100644
--- a/python/sedona/spark/geopandas/base.py
+++ b/python/sedona/spark/geopandas/base.py
@@ -350,9 +350,41 @@ class GeoFrame(metaclass=ABCMeta):
"""
return _delegate_to_geometry_column("is_simple", self)
- # @property
- # def is_ring(self):
- # raise NotImplementedError("This method is not implemented yet.")
+ @property
+ def is_ring(self):
+ """Return a ``Series`` of ``dtype('bool')`` with value ``True`` for
+ features that are closed.
+
+ When constructing a LinearRing, the sequence of coordinates may be
+ explicitly closed by passing identical values in the first and last
indices.
+ Otherwise, the sequence will be implicitly closed by copying the first
tuple
+ to the last index.
+
+ Examples
+ --------
+ >>> from sedona.spark.geopandas import GeoSeries
+ >>> from shapely.geometry import LineString, LinearRing
+ >>> s = GeoSeries(
+ ... [
+ ... LineString([(0, 0), (1, 1), (1, -1)]),
+ ... LineString([(0, 0), (1, 1), (1, -1), (0, 0)]),
+ ... LinearRing([(0, 0), (1, 1), (1, -1)]),
+ ... ]
+ ... )
+ >>> s
+ 0 LINESTRING (0 0, 1 1, 1 -1)
+ 1 LINESTRING (0 0, 1 1, 1 -1, 0 0)
+ 2 LINEARRING (0 0, 1 1, 1 -1, 0 0)
+ dtype: geometry
+
+ >>> s.is_ring
+ 0 False
+ 1 True
+ 2 True
+ dtype: bool
+
+ """
+ return _delegate_to_geometry_column("is_ring", self)
# @property
# def is_ccw(self):
diff --git a/python/sedona/spark/geopandas/geoseries.py
b/python/sedona/spark/geopandas/geoseries.py
index c9dc7b7f3b..648f6860a0 100644
--- a/python/sedona/spark/geopandas/geoseries.py
+++ b/python/sedona/spark/geopandas/geoseries.py
@@ -944,12 +944,12 @@ class GeoSeries(GeoFrame, pspd.Series):
@property
def is_ring(self):
- # Implementation of the abstract method
- raise NotImplementedError(
- _not_implemented_error(
- "is_ring", "Tests if LineString geometries are closed rings."
- )
+ spark_expr = stf.ST_IsRing(self.spark.column)
+ result = self._query_geometry_column(
+ spark_expr,
+ returns_geom=False,
)
+ return _to_bool(result)
@property
def is_ccw(self):
diff --git a/python/tests/geopandas/test_geoseries.py
b/python/tests/geopandas/test_geoseries.py
index d12a2afd18..61ca151317 100644
--- a/python/tests/geopandas/test_geoseries.py
+++ b/python/tests/geopandas/test_geoseries.py
@@ -869,7 +869,20 @@ e": "Feature", "properties": {}, "geometry": {"type":
"Point", "coordinates": [3
assert_series_equal(df_result, expected)
def test_is_ring(self):
- pass
+ s = GeoSeries(
+ [
+ LineString([(0, 0), (1, 1), (1, -1)]),
+ LineString([(0, 0), (1, 1), (1, -1), (0, 0)]),
+ LinearRing([(0, 0), (1, 1), (1, -1)]),
+ ]
+ )
+ result = s.is_ring
+ expected = pd.Series([False, True, True])
+ self.check_pd_series_equal(result, expected)
+
+ # Check that GeoDataFrame works too
+ result = s.to_geoframe().is_ring
+ self.check_pd_series_equal(result, expected)
def test_is_ccw(self):
pass
diff --git a/python/tests/geopandas/test_match_geopandas_series.py
b/python/tests/geopandas/test_match_geopandas_series.py
index aa4ae6d238..c845bf99a0 100644
--- a/python/tests/geopandas/test_match_geopandas_series.py
+++ b/python/tests/geopandas/test_match_geopandas_series.py
@@ -578,7 +578,11 @@ class TestMatchGeopandasSeries(TestGeopandasBase):
self.check_pd_series_equal(sgpd_result, gpd_result)
def test_is_ring(self):
- pass
+ # is_ring is only meaningful for linestrings so we use
self.linestrings instead of self.geoms
+ for geom in self.linestrings:
+ sgpd_result = GeoSeries(geom).is_ring
+ gpd_result = gpd.GeoSeries(geom).is_ring
+ self.check_pd_series_equal(sgpd_result, gpd_result)
def test_is_ccw(self):
pass