jiayuasu opened a new pull request, #1184: URL: https://github.com/apache/sedona-db/pull/1184
The unblocked half of #1142, split out so it can move forward while the spatial-join engine issues are being fixed. `sjoin` stays in #1142, which is blocked on #1165 (`ST_Touches`/`ST_Within` boundary misclassification) and #1166 (empty preserved side fails in the spatial join executor); nothing here touches those code paths. ```python gdf = sgpd.from_geopandas(points) gdf["density"] = gdf["pop"] / gdf["area"] # assignment + true division zones = gdf.dissolve(by="region") # group and union geometry ``` ## What is added - **`__setitem__`** — assign a `Series` from the same frame, or a scalar (a geometry included). Frame provenance is enforced: a `Series` from another frame, a bare expression (which records no origin), and multi-element values are rejected with focused errors. Replacing the active geometry with a non-geometry clears it; assigning geometry to a frame without one activates it; a geometry scalar or missing sentinel (`None`, NaN, `pandas.NA`) keeps the column's type and CRS, and a literal carrying its own CRS keeps that rather than being relabeled. - **Arithmetic on `Series`** — `+`, `-`, `*`, `/` and the reflected forms. `/` is true division as in pandas: integer-typed expressions are cast to double (decided from the projected schema, a plan build) so SQL integer division does not truncate, while decimals stay exact and durations stay durations. `//` is deliberately not implemented, since SQL division truncates toward zero where Python floors. `Series` opts out of NumPy ufunc dispatch so an array operand is rejected whole instead of being broadcast element-by-element into an object array. - **`dissolve(by, aggfunc="first", dropna=True)`** — unions each group's geometry via collect + unary union, which handles every geometry type (`ST_Union_Agg` only initializes for polygonal input, #1093). `dropna` covers IEEE NaN as well as SQL null, including dictionary-encoded float keys. A group whose geometries are all null yields an empty geometry collection carrying the source CRS, matching GeoPandas. - **Shared scalar machinery** — one classification used by operators and assignment so they cannot disagree, with normalization: 0-d NumPy arrays unwrap to their value, `pandas.NA` becomes SQL null, NaN stays a float value. - **Stale-mask guard** — boolean indexing rejects a mask built from another frame, including a mask captured before an assignment rebound this one; previously that could silently filter against the wrong frame state. ## Documented differences from GeoPandas - `aggfunc="first"` is an unordered aggregate: it returns some value from the group and does not skip missing values. - Dissolving an empty frame without a key returns one row (empty geometry collection, null attributes) rather than zero rows — a grouping-free SQL aggregate's shape. - A group mixing 2D and 3D geometries raises rather than being promoted to 3D. ## Tests 73 tests, asserted against GeoPandas where a comparison exists (dissolve geometry equality across point/line/polygon groups, aggregation values, CRS propagation, division exactness for decimals, and the full assignment matrix including every missing-value sentinel). `ruff format` and `ruff check` clean. -- 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]
