jiayuasu opened a new issue, #3134: URL: https://github.com/apache/sedona/issues/3134
Part of #2230. ## Summary Implement `GeoSeries.affine_transform(matrix)` and GeoDataFrame delegation using Sedona's existing `ST_Affine` Spark SQL function. The implementation must remain fully distributed: it should construct a Spark column expression for every geometry row and must not call `to_geopandas()`, `collect()`, `toLocalIterator()`, or a Python row UDF. ## API and coefficient mapping GeoPandas accepts either of these matrix layouts: - 2D: `[a, b, d, e, xoff, yoff]` - 3D: `[a, b, c, d, e, f, g, h, i, xoff, yoff, zoff]` They represent: ```text x' = a*x + b*y + c*z + xoff y' = d*x + e*y + f*z + yoff z' = g*x + h*y + i*z + zoff ``` Sedona's 2D wrapper call accepts the six GeoPandas values directly. The 3D Python wrapper has this positional signature instead: ```text ST_Affine(geometry, a, b, d, e, xOff, yOff, c, f, g, h, i, zOff) ``` The 12-value implementation must therefore pass the optional 3D coefficients by name or explicitly reorder them. Passing `*matrix` directly would produce incorrect coordinates. Coefficients should also be normalized to Python floats because the current wrapper validation rejects integer arguments. ## Requirements - Accept one operation-wide sequence containing exactly 6 or 12 numeric coefficients. - Validate invalid lengths and non-numeric values with clear errors. - Reject `None` coefficients before calling `ST_Affine`; otherwise its optional-argument handling can silently select the 2D overload. - Normalize valid numeric coefficients to Python floats. - Route 6-value matrices to the 2D `ST_Affine` overload. - Explicitly map 12-value matrices to the 3D `ST_Affine` wrapper arguments. - Preserve GeoSeries index and CRS metadata. - Preserve geometry SRID, nulls, empty geometries, mixed geometry types, and existing Z values under a 2D transform. - Provide GeoDataFrame behavior through the existing `base.py` geometry-column delegation. - Add no driver-side materialization or new mandatory dependency. ## Tests Add direct and GeoPandas parity coverage for: - identity, translation, scale, rotation, and shear matrices; - integer and floating-point coefficients; - 6-value 2D and 12-value 3D matrices; - a 12-value ordering regression: `range(1, 13)` applied to `POINT Z (1 2 3)` must produce `POINT Z (24 43 62)`; - 2D matrices applied to Z geometries; - 3D matrices applied to 2D and Z geometries; - null and empty geometries; - points, lines, polygons, multi-geometries, and geometry collections; - invalid matrix lengths and non-numeric coefficients; - index, CRS, and SRID preservation; - GeoSeries and GeoDataFrame delegation. Document rather than emulate driver-side behavior for mixed 2D/3D geometry collections, M ordinates, and NaN-Z inputs where the underlying JTS and Shapely engines differ. Homogeneous 2D and 3D geometries must match GeoPandas. ## Likely files - `python/sedona/spark/geopandas/base.py` - `python/sedona/spark/geopandas/geoseries.py` - `python/tests/geopandas/test_geoseries.py` - `python/tests/geopandas/test_match_geopandas_series.py` No JVM, Scala, or SQL wrapper changes should be necessary. ## Acceptance criteria - Output matches GeoPandas for supported 2D and 3D matrices. - Execution remains a Spark expression over distributed geometry rows. - No driver collection, local iteration, or Python row UDF is introduced. - Focused tests and the relevant Python matrix pass. - The implementation PR references `Part of #2230` and does not close the epic. ## Non-goals - Implementing `scale`, `skew`, or `translate` in the same pull request. - Accepting a different matrix per row. - Adding new affine functionality to Sedona's JVM or SQL layers. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
