Skip to content

[GH-3017] Implement rotate#3018

Open
oglego wants to merge 3 commits into
apache:masterfrom
oglego:feature/implement-rotate
Open

[GH-3017] Implement rotate#3018
oglego wants to merge 3 commits into
apache:masterfrom
oglego:feature/implement-rotate

Conversation

@oglego

@oglego oglego commented May 31, 2026

Copy link
Copy Markdown

Did you read the Contributor Guide?

Is this PR related to a ticket?

What changes were proposed in this PR?

Implement rotate

How was this patch tested?

Added tests, verified success of all tests with:

pytest -v tests/geopandas/test_geoseries.py

117 passed, 44108 warnings in 140.69s (0:02:20)

Verified formatting with:

make check

Did this PR include necessary documentation updates?

  • Yes, I have updated the documentation.

@oglego oglego requested a review from jiayuasu as a code owner May 31, 2026 17:37
@oglego

oglego commented May 31, 2026

Copy link
Copy Markdown
Author

Hey @petern48,

I have tried to follow along with the instructions on ticket 2230 and PR example 2231 but if I missed anything on this please let me know! Thank you for putting those instructions together they were very helpful!

@petern48 petern48 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this. I've done an initial scan and left some feedback

Comment thread python/sedona/spark/geopandas/base.py Outdated
Examples
--------
>>> from shapely.geometry import Point, LineString, Polygon
>>> s = geopandas.GeoSeries(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
>>> s = geopandas.GeoSeries(
>>> from sedona.spark.geopandas import GeoSeries
>>> s = GeoSeries(

we should update the import for sedona instead of geopandas

Comment on lines +966 to +967
sgpd_result = GeoSeries(geom).rotate(45, origin=(0, 0))
gpd_result = gpd.GeoSeries(geom).rotate(45, origin=(0, 0))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we update these to an origin other than (0, 0), just to make sure it works? maybe something like (1, 2).

can we also add add a case for testing "centroid" and a Point() object as input for origin field to make sure they work?

gpd_s = gpd.GeoSeries(geoms)

# Test default (degrees, origin='center')
self.check_sgpd_equals_gpd(s.rotate(90), gpd_s.rotate(90))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_geoseries.py should be testing the hard-coded expected outputs instead of comparing it directly to the result of what geopandas returns (that's what test_match_geopandas_series.py` is for. Could you update all of these examples to compare to the hard-coded expected output geometries?

@oglego

oglego commented Jun 2, 2026

Copy link
Copy Markdown
Author

@petern48 thank you for reviewing this and for the feedback on it I really appreciate it! I've gone back through the tests and have tried to update them using the suggestions you have provided - if I missed anything on them or need to be more explicit in some of the expected results just let me know. Thanks again!

@jiayuasu jiayuasu left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review notes on the rotate implementation and coverage.

def test_rotate(self, angle, origin_kwargs):
for geom in self.geoms:
# Sedona converts empty geometries to None, skip them
if not gpd.GeoSeries(geom).is_empty.any():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition skips every fixture group because each list in self.geoms starts with at least one empty geometry, so the parametrized cases pass without running any rotate comparisons. Could we filter empty geometries within each group, or build non-empty rotate fixtures, and replace origin="point" with an actual Point origin or an explicit invalid-origin case?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahhh, thank you for reviewing this and catching that! I'll get that updated and fixed!

raise ValueError(
f"origin must be 'center', 'centroid', a Point, or (x, y) tuple, got {origin!r}"
)
elif isinstance(origin, tuple) and len(origin) == 2:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GeoPandas/Shapely also accepts a two-element list for origin, for example origin=[0, 0], but this branch only accepts tuples. Since this wrapper is matching GeoPandas semantics, can we accept any two-element coordinate sequence here and add a list-origin regression test?

@oglego

oglego commented Jun 10, 2026

Copy link
Copy Markdown
Author

@jiayuasu I looked around at the other tests and noticed that test_union_all used a list comprehension to help with filtering so I ended up doing something similar with filtering out the empty geometries, let me know if there is a better way of doing this! I think I've got everything updated now with your feedback, thanks again for reviewing this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Geopandas: Implement rotate

3 participants