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 c7b5a7f69b [GH-2016] Geopandas.GeoSeries: Implement x(), y(), z(), 
has_z (#2017)
c7b5a7f69b is described below

commit c7b5a7f69b1ae5cad2e8ea29cdbade807516a9cc
Author: Peter Nguyen <[email protected]>
AuthorDate: Tue Jul 1 14:56:15 2025 -0700

    [GH-2016] Geopandas.GeoSeries: Implement x(), y(), z(), has_z (#2017)
    
    * Implement x(), y(), z()
    
    * Change None to np.nan
    
    Co-authored-by: Copilot <[email protected]>
    
    * Implemnet has_z
    
    ---------
    
    Co-authored-by: Copilot <[email protected]>
---
 python/sedona/geopandas/geoseries.py               | 114 +++++++++++++++++++--
 python/tests/geopandas/test_geoseries.py           |  34 +++++-
 .../tests/geopandas/test_match_geopandas_series.py |  23 ++++-
 3 files changed, 157 insertions(+), 14 deletions(-)

diff --git a/python/sedona/geopandas/geoseries.py 
b/python/sedona/geopandas/geoseries.py
index 4dc612d171..5844b3b21d 100644
--- a/python/sedona/geopandas/geoseries.py
+++ b/python/sedona/geopandas/geoseries.py
@@ -619,9 +619,37 @@ class GeoSeries(GeoFrame, pspd.Series):
         raise NotImplementedError("This method is not implemented yet.")
 
     @property
-    def has_z(self):
-        # Implementation of the abstract method
-        raise NotImplementedError("This method is not implemented yet.")
+    def has_z(self) -> pspd.Series:
+        """Returns a ``Series`` of ``dtype('bool')`` with value ``True`` for
+        features that have a z-component.
+
+        Notes
+        -----
+        Every operation in GeoPandas is planar, i.e. the potential third
+        dimension is not taken into account.
+
+        Examples
+        --------
+        >>> from shapely.geometry import Point
+        >>> s = geopandas.GeoSeries(
+        ...     [
+        ...         Point(0, 1),
+        ...         Point(0, 1, 2),
+        ...     ]
+        ... )
+        >>> s
+        0        POINT (0 1)
+        1    POINT Z (0 1 2)
+        dtype: geometry
+
+        >>> s.has_z
+        0    False
+        1     True
+        dtype: bool
+        """
+        return self._process_geometry_column(
+            "ST_HasZ", rename="has_z"
+        ).to_spark_pandas()
 
     def get_precision(self):
         # Implementation of the abstract method
@@ -865,15 +893,89 @@ class GeoSeries(GeoFrame, pspd.Series):
 
     @property
     def x(self) -> pspd.Series:
-        raise NotImplementedError("GeoSeries.x() is not implemented yet.")
+        """Return the x location of point geometries in a GeoSeries
+
+        Returns
+        -------
+        pandas.Series
+
+        Examples
+        --------
+
+        >>> from shapely.geometry import Point
+        >>> s = geopandas.GeoSeries([Point(1, 1), Point(2, 2), Point(3, 3)])
+        >>> s.x
+        0    1.0
+        1    2.0
+        2    3.0
+        dtype: float64
+
+        See Also
+        --------
+
+        GeoSeries.y
+        GeoSeries.z
+
+        """
+        return self._process_geometry_column("ST_X", 
rename="x").to_spark_pandas()
 
     @property
     def y(self) -> pspd.Series:
-        raise NotImplementedError("GeoSeries.y() is not implemented yet.")
+        """Return the y location of point geometries in a GeoSeries
+
+        Returns
+        -------
+        pandas.Series
+
+        Examples
+        --------
+
+        >>> from shapely.geometry import Point
+        >>> s = geopandas.GeoSeries([Point(1, 1), Point(2, 2), Point(3, 3)])
+        >>> s.y
+        0    1.0
+        1    2.0
+        2    3.0
+        dtype: float64
+
+        See Also
+        --------
+
+        GeoSeries.x
+        GeoSeries.z
+        GeoSeries.m
+
+        """
+        return self._process_geometry_column("ST_Y", 
rename="y").to_spark_pandas()
 
     @property
     def z(self) -> pspd.Series:
-        raise NotImplementedError("GeoSeries.z() is not implemented yet.")
+        """Return the z location of point geometries in a GeoSeries
+
+        Returns
+        -------
+        pandas.Series
+
+        Examples
+        --------
+
+        >>> from shapely.geometry import Point
+        >>> s = geopandas.GeoSeries([Point(1, 1, 1), Point(2, 2, 2), Point(3, 
3, 3)])
+        >>> s.z
+        0    1.0
+        1    2.0
+        2    3.0
+        dtype: float64
+
+        See Also
+        --------
+
+        GeoSeries.x
+        GeoSeries.y
+        GeoSeries.m
+
+        """
+        return self._process_geometry_column("ST_Z", 
rename="z").to_spark_pandas()
 
     @property
     def m(self) -> pspd.Series:
diff --git a/python/tests/geopandas/test_geoseries.py 
b/python/tests/geopandas/test_geoseries.py
index 0c13e92673..cc1b3338b3 100644
--- a/python/tests/geopandas/test_geoseries.py
+++ b/python/tests/geopandas/test_geoseries.py
@@ -15,6 +15,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
+import numpy as np
 import pytest
 import pandas as pd
 import geopandas as gpd
@@ -77,13 +78,28 @@ class TestGeoSeries(TestBase):
         )
 
     def test_x(self):
-        pass
+        geoseries = sgpd.GeoSeries(
+            [Point(0, -1, 2.5), Point(2.5, 0, -1), Point(-1, 2.5, 0), 
Point(-1, 0)]
+        )
+        result = geoseries.x.to_pandas()
+        expected = pd.Series([0, 2.5, -1, -1])
+        assert_series_equal(result, expected)
 
     def test_y(self):
-        pass
+        geoseries = sgpd.GeoSeries(
+            [Point(0, -1, 2.5), Point(2.5, 0, -1), Point(-1, 2.5, 0), 
Point(-1, 0)]
+        )
+        result = geoseries.y.to_pandas()
+        expected = pd.Series([-1, 0, 2.5, 0])
+        assert_series_equal(result, expected)
 
     def test_z(self):
-        pass
+        geoseries = sgpd.GeoSeries(
+            [Point(0, -1, 2.5), Point(2.5, 0, -1), Point(-1, 2.5, 0), 
Point(-1, 0)]
+        )
+        result = geoseries.z.to_pandas()
+        expected = pd.Series([2.5, -1, 0, np.nan])
+        assert_series_equal(result, expected)
 
     def test_m(self):
         pass
@@ -204,7 +220,17 @@ class TestGeoSeries(TestBase):
         pass
 
     def test_has_z(self):
-        pass
+        s = sgpd.GeoSeries(
+            [
+                Point(0, 1),
+                Point(0, 1, 2),
+                Polygon([(0, 0, 1), (0, 1, 2), (1, 1, 3), (0, 0, 1)]),
+                Polygon([(0, 0), (0, 1), (1, 1), (0, 0)]),
+            ]
+        )
+        result = s.has_z
+        expected = pd.Series([False, True, True, False])
+        assert_series_equal(result.to_pandas(), expected)
 
     def test_get_precision(self):
         pass
diff --git a/python/tests/geopandas/test_match_geopandas_series.py 
b/python/tests/geopandas/test_match_geopandas_series.py
index fee2fa565d..c55db097db 100644
--- a/python/tests/geopandas/test_match_geopandas_series.py
+++ b/python/tests/geopandas/test_match_geopandas_series.py
@@ -213,13 +213,25 @@ class TestMatchGeopandasSeries(TestBase):
             self.check_sgpd_equals_gpd(sgpd_result, gpd_result)
 
     def test_x(self):
-        pass
+        for pt in self.points:
+            sgpd_result = GeoSeries(pt).x
+            assert isinstance(sgpd_result, ps.Series)
+            gpd_result = gpd.GeoSeries(pt).x
+            self.check_pd_series_equal(sgpd_result, gpd_result)
 
     def test_y(self):
-        pass
+        for pt in self.points:
+            sgpd_result = GeoSeries(pt).y
+            assert isinstance(sgpd_result, ps.Series)
+            gpd_result = gpd.GeoSeries(pt).y
+            self.check_pd_series_equal(sgpd_result, gpd_result)
 
     def test_z(self):
-        pass
+        for pt in self.points:
+            sgpd_result = GeoSeries(pt).z
+            assert isinstance(sgpd_result, ps.Series)
+            gpd_result = gpd.GeoSeries(pt).z
+            self.check_pd_series_equal(sgpd_result, gpd_result)
 
     def test_m(self):
         pass
@@ -328,7 +340,10 @@ class TestMatchGeopandasSeries(TestBase):
         pass
 
     def test_has_z(self):
-        pass
+        for _, geom in self.geoms:
+            sgpd_result = GeoSeries(geom).has_z
+            gpd_result = gpd.GeoSeries(geom).has_z
+            self.check_pd_series_equal(sgpd_result, gpd_result)
 
     def test_get_precision(self):
         pass

Reply via email to