Repository: Zeroto521/my-data-toolkit

Issue:
ENH: New geoaccessor for GeoSeries to return tuple of coordinates `(x, y)`
<!--
Thanks for contributing a pull request!

Please follow these standard acronyms to start the commit message:

- ENH: enhancement
- BUG: bug fix
- DOC: documentation
- TYP: type annotations
- TST: addition or modification of tests
- MAINT: maintenance commit (refactoring, typos, etc.)
- BLD: change related to building
- REL: related to releasing
- API: an (incompatible) API change
- DEP: deprecate something, or remove a deprecated object
- DEV: development tool or utility
- REV: revert an earlier commit
- PERF: performance improvement
- BOT: always commit via a bot
- CI: related to CI or CD
- CLN: Code cleanup
-->

- [ ] closes #xxxx
- [x] whatsnew entry

as title

```python
    >>> import dtoolkit.geoaccessor
    >>> import geopandas as gpd
    >>> from shapely.geometry import Point
    >>> s = geopandas.GeoSeries([Point(1, 1), Point(2, 2), Point(3, 3)])
    >>> s.xy
    0    (1.0, 1.0)
    1    (2.0, 2.0)
    2    (3.0, 3.0)
    dtype: object
```


Discussion:
# [Codecov](https://codecov.io/gh/Zeroto521/my-data-toolkit/pull/711?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=40%25) Report
> Merging [#711](https://codecov.io/gh/Zeroto521/my-data-toolkit/pull/711?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=40%25) (54db4cf) into [main](https://codecov.io/gh/Zeroto521/my-data-toolkit/commit/0fee1cd4216762f49d47f0c5993923cb6127b93a?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=40%25) (0fee1cd) will **decrease** coverage by `0.13%`.
> The diff coverage is `100.00%`.

```diff
@@            Coverage Diff             @@
##             main     #711      +/-   ##
==========================================
- Coverage   99.52%   99.39%   -0.14%     
==========================================
  Files         120      121       +1     
  Lines        1489     1496       +7     
  Branches      140      140              
==========================================
+ Hits         1482     1487       +5     
- Misses          1        2       +1     
- Partials        6        7       +1     
```


| [Impacted Files](https://codecov.io/gh/Zeroto521/my-data-toolkit/pull/711?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=40%25) | Coverage Δ | |
|---|---|---|
| [dtoolkit/geoaccessor/geoseries/\_\_init\_\_.py](https://codecov.io/gh/Zeroto521/my-data-toolkit/pull/711/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=40%25#diff-ZHRvb2xraXQvZ2VvYWNjZXNzb3IvZ2Vvc2VyaWVzL19faW5pdF9fLnB5) | `100.00% <100.00%> (ø)` | |
| [dtoolkit/geoaccessor/geoseries/xy.py](https://codecov.io/gh/Zeroto521/my-data-toolkit/pull/711/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=40%25#diff-ZHRvb2xraXQvZ2VvYWNjZXNzb3IvZ2Vvc2VyaWVzL3h5LnB5) | `100.00% <100.00%> (ø)` | |
| [dtoolkit/transformer/sklearn/OneHotEncoder.py](https://codecov.io/gh/Zeroto521/my-data-toolkit/pull/711/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=40%25#diff-ZHRvb2xraXQvdHJhbnNmb3JtZXIvc2tsZWFybi9PbmVIb3RFbmNvZGVyLnB5) | `92.30% <0.00%> (-7.70%)` | :arrow_down: |

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=40%25)


Resolving patch:
diff --git a/dtoolkit/geoaccessor/geoseries/xy.py b/dtoolkit/geoaccessor/geoseries/xy.py
--- a/dtoolkit/geoaccessor/geoseries/xy.py
+++ b/dtoolkit/geoaccessor/geoseries/xy.py
@@ -5,14 +5,19 @@
 
 
 @register_geoseries_method
-def xy(s: gpd.GeoSeries, /) -> pd.Series:
+def xy(s: gpd.GeoSeries, /, reverse: bool = False) -> pd.Series:
     """
     Return the x and y location of Point geometries in a GeoSeries.
 
+    Parameters
+    ----------
+    reverse : bool, default False
+        If True, return (y, x) instead.
+
     Returns
     -------
     Series
-        tuple of x and y coordinates.
+        tuple of coordinate.
 
     See Also
     --------
@@ -24,17 +29,26 @@ def xy(s: gpd.GeoSeries, /) -> pd.Series:
     >>> import dtoolkit.geoaccessor
     >>> import geopandas as gpd
     >>> from shapely.geometry import Point
-    >>> s = gpd.GeoSeries([Point(1, 1), Point(2, 2), Point(3, 3)])
+    >>> s = gpd.GeoSeries([Point(0, 1), Point(0, 2), Point(0, 3)])
     >>> s
-    0    POINT (1.00000 1.00000)
-    1    POINT (2.00000 2.00000)
-    2    POINT (3.00000 3.00000)
+    0    POINT (0.00000 1.00000)
+    1    POINT (0.00000 2.00000)
+    2    POINT (0.00000 3.00000)
     dtype: geometry
     >>> s.xy()
-    0    (1.0, 1.0)
-    1    (2.0, 2.0)
-    2    (3.0, 3.0)
+    0    (0.0, 1.0)
+    1    (0.0, 2.0)
+    2    (0.0, 3.0)
+    dtype: object
+
+    Set ``reverse=True`` to return (y, x).
+
+    >>> s.xy(True)
+    0    (1.0, 0.0)
+    1    (2.0, 0.0)
+    2    (3.0, 0.0)
     dtype: object
     """
 
-    return pd.concat((s.x, s.y), axis=1).apply(tuple, axis=1)
+    coordinates = (s.y, s.x) if reverse else (s.x, s.y)
+    return pd.concat(coordinates, axis=1).apply(tuple, axis=1)


Test patch: