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]

Reply via email to