jiayuasu opened a new issue, #3143:
URL: https://github.com/apache/sedona/issues/3143

   Part of #2230.
   
   ## Summary
   
   Implement `GeoSeries.scale(xfact=1.0, yfact=1.0, zfact=1.0, 
origin="center")` and GeoDataFrame active-geometry delegation.
   
   The implementation must remain fully distributed: resolve per-geometry 
origins and construct a Spark column expression for every row. It must not call 
`to_geopandas()`, `collect()`, `toLocalIterator()`, or a Python row UDF.
   
   Use the existing `ST_Affine` Spark SQL function rather than `ST_Scale` or 
`ST_ScaleGeom`. The latter functions only scale X/Y and cannot reproduce 
GeoPandas' default per-geometry origin or `zfact` behavior.
   
   ## API and transformation
   
   GeoPandas scales each dimension around an origin `(x0, y0, z0)`:
   
   ```text
   x' = x0 + xfact * (x - x0)
   y' = y0 + yfact * (y - y0)
   z' = z0 + zfact * (z - z0)
   ```
   
   This is a 3D affine transformation with diagonal factors and offsets:
   
   ```text
   xoff = x0 - x0 * xfact
   yoff = y0 - y0 * yfact
   zoff = z0 - z0 * zfact
   ```
   
   Supported origins:
   
   - `"center"`: each geometry's 2D bounding-box center, computed independently 
per row;
   - `"centroid"`: each geometry's 2D centroid, computed independently per row;
   - a local 2D or 3D Shapely `Point`;
   - a numeric coordinate tuple containing two or three values.
   
   The Z origin is `0.0` for `"center"`, `"centroid"`, and 2D explicit origins. 
A 3D Point or tuple supplies `z0`.
   
   Sedona's Python `ST_Affine` wrapper lists the mandatory 2D arguments before 
its optional 3D arguments. The implementation must explicitly map the diagonal 
matrix to this wrapper order rather than passing a GeoPandas-style matrix 
directly.
   
   ## Requirements
   
   - Accept operation-wide numeric scalar values for `xfact`, `yfact`, and 
`zfact`; normalize valid values to Python floats.
   - Reject `None`, strings, array-like values, distributed Series, and other 
non-scalar factors with clear errors.
   - Validate origin keywords, Point dimensionality, tuple length, and numeric 
tuple values before constructing the Spark expression.
   - Resolve `"center"` and `"centroid"` using Spark/Sedona column expressions 
on executors.
   - Use the 3D `ST_Affine` overload so Z geometries honor `zfact`; 2D 
geometries must remain 2D.
   - Preserve index, CRS metadata, geometry SRID, nulls, typed empty 
geometries, geometry types, and existing Z coordinates when `zfact=1.0`.
   - Guard empty geometries before evaluating computed-origin expressions so an 
empty geometry does not become null.
   - Provide GeoDataFrame behavior through the existing `base.py` 
geometry-column delegation.
   - Add no driver-side materialization, Python row UDF, JVM change, or new 
mandatory dependency.
   
   ## Tests
   
   Add direct and GeoPandas parity coverage for:
   
   - default identity factors and custom X/Y/Z factors;
   - positive, negative, and zero factors;
   - `"center"` versus `"centroid"` on an asymmetric geometry;
   - 2D and 3D tuple origins;
   - 2D and 3D Shapely Point origins;
   - 2D inputs with a non-default `zfact` remaining 2D;
   - Z inputs scaled around implicit and explicit Z origins;
   - the regression `POINT Z (1 2 3)` with factors `(2, 3, 4)` and default 
origin producing `POINT Z (1 2 12)`;
   - points, lines, polygons, multi-geometries, and homogeneous geometry 
collections;
   - nulls and typed empty geometries with keyword and explicit origins;
   - invalid factors and origins;
   - index, CRS, and SRID preservation;
   - GeoSeries and GeoDataFrame delegation.
   
   Document rather than emulate driver-side behavior for mixed 2D/3D geometry 
collections, M/ZM ordinates, NaN-Z inputs, and non-finite factors where JTS and 
Shapely may differ.
   
   ## 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
   
   - Homogeneous 2D and 3D results match GeoPandas for supported factors and 
origins.
   - 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
   
   - Accepting a different factor or origin per row.
   - Changing `ST_Scale`, `ST_ScaleGeom`, or `ST_Affine` in Sedona's JVM or SQL 
layers.
   - Implementing `skew` or `translate` in the same pull request.
   


-- 
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]

Reply via email to