Skip to content

Add coregister=True to .xrs.rasterize accessor (#3492)#3493

Merged
brendancol merged 3 commits into
mainfrom
issue-3492
Jun 25, 2026
Merged

Add coregister=True to .xrs.rasterize accessor (#3492)#3493
brendancol merged 3 commits into
mainfrom
issue-3492

Conversation

@brendancol

Copy link
Copy Markdown
Contributor

Closes #3492

Gives .xrs.rasterize the same coregister flag the interpolation accessors got in #3481.

  • coregister=False (default) keeps current behavior: a GeoDataFrame whose CRS differs from the caller raster still raises through rasterize's own check_crs.
  • coregister=True reprojects a GeoDataFrame's geometries from their CRS into the caller raster's CRS (via GeoDataFrame.to_crs) before rasterizing, so the burn lands on the caller grid. It needs a CRS on both the geometries (.crs) and the caller (detected the same way check_crs detects the template CRS), and raises a clear error otherwise.
  • Added on both accessor classes (DataArray and Dataset) through a shared _rasterize_on_accessor helper that mirrors _interp_on_accessor.
  • The standalone rasterize() function is untouched; coregister is accessor-only, the same split Accept GeoDataFrames in interpolation + expose on .xrs accessor with coregister #3481 used.

Backends

Input-parsing only: the coregister branch runs before backend dispatch and just reprojects the GeoDataFrame, then hands off to the unchanged rasterize. numpy and dask+numpy verified directly; cupy / dask+cupy inherit the unchanged rasterize dispatch.

Test plan

  • coregister round-trip (4326 points onto a 3857 grid) burns the same pixels as rasterizing the native-CRS points (numpy + dask)
  • coregister output inherits the caller grid; five points burn five finite cells
  • Dataset accessor coregister matches the DataArray path
  • CRS mismatch raises without coregister; matching CRS passes
  • coregister with a missing CRS on either side raises
  • coregister with a non-GeoDataFrame input raises
  • existing test_accessor.py / test_rasterize.py / test_interpolate_vector.py pass unchanged

@brendancol brendancol left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

PR Review: Add coregister=True to .xrs.rasterize accessor

Blockers (must fix before merge)

None.

Suggestions (should fix, not blocking)

  • dask_geopandas gap: is_geodataframe recognizes plain geopandas only, so a dask_geopandas frame with coregister=True raises "requires a GeoDataFrame", even though standalone rasterize._parse_input accepts one. This mirrors the interpolation accessor (#3481) on purpose. Addressed by a code comment so the gap is intentional and discoverable; reprojecting a dask_geopandas frame under coregister can be a follow-up.

Nits (optional improvements)

  • The missing-CRS error message said (attrs['crs']), but _like_crs also reads crs_wkt, a spatial_ref coord, or rio.crs. Reworded to "(its detected raster CRS)".

What looks good

  • Using _like_crs(obj) for the reprojection target (rather than only attrs['crs']) matches how rasterize's own check_crs finds the template CRS, so the reprojected frame compares equal and the default guard passes cleanly.
  • coregister is accessor-only; the standalone rasterize() signature is untouched, the same split #3481 used for interpolation.
  • Shared _rasterize_on_accessor helper keeps the DataArray and Dataset accessors in sync.

Checklist

  • Reprojection path defers to the unchanged rasterize (algorithm unaffected)
  • Backend dispatch unchanged; coregister runs before dispatch (numpy/dask verified, cupy inherits)
  • NaN/fill handled by rasterize as before
  • Edge cases covered: missing CRS, mismatch, non-GeoDataFrame, Dataset accessor
  • No premature materialization; dask template stays lazy until output
  • Benchmark not needed (input-parsing glue, no new kernel)
  • README feature matrix not applicable (no new function, no backend change)
  • Docstrings present on both accessor methods and the helper

@brendancol brendancol left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Follow-up review (after 3a6ae84)

Re-read the full changed files at head. The two findings from the first pass are resolved:

  • Suggestion (dask_geopandas gap) — fixed: added a code comment in _rasterize_on_accessor marking the geopandas-only gate as intentional parity with #3481, with the dask_geopandas case noted as a follow-up.
  • Nit (error message) — fixed: the missing-CRS message now reads "(its detected raster CRS)" instead of "(attrs['crs'])", matching _like_crs's broader detection.

No new issues. Tests still green (8 passed locally). Nothing blocking.

@brendancol brendancol merged commit 7f41c3c into main Jun 25, 2026
12 checks passed
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.

Add coregister=True to .xrs.rasterize to reproject GeoDataFrame geometries onto the caller grid

1 participant