|
| 1 | +```{eval-rst} |
| 2 | +.. currentmodule:: rasterix |
| 3 | +``` |
| 4 | + |
| 5 | +# Design Choices |
| 6 | + |
| 7 | +In designing {py:class}`RasterIndex`, we faced a few thorny questions. Below we discuss these considerations, and the approach we've taken. |
| 8 | +Ultimately, there are no easy answers and tradeoffs to be made. |
| 9 | + |
| 10 | +## CRS handling |
| 11 | + |
| 12 | +{py:class}`xproj.CRSIndex` is an attempt at providing a building block for CRS handling in the Xarray ecosystem. |
| 13 | + |
| 14 | +How might {py:class}`RasterIndex` fit with that vision? Our options are: |
| 15 | + |
| 16 | +1. fully encapsulate {py:class}`xproj.CRSIndex`, or |
| 17 | +1. satisfy the ["CRS-aware" protocol](https://xproj.readthedocs.io/en/latest/integration.html) provided by `xproj`, or |
| 18 | +1. simply handle the affine transform and ignore the CRS altogether. |
| 19 | + |
| 20 | +Why do we want CRS handling? We want Xarray to disallow alignment of two Xarray objects with different CRS e.g. `da1 + da2` should fail if `da1`, and `da2` have different CRS. This is enabled by assigning {py:class}`xproj.CRSIndex` to the `spatial_ref` variable. |
| 21 | + |
| 22 | +### Why should `RasterIndex` be aware of the CRS? |
| 23 | + |
| 24 | +RasterIndex handles indexing and the creation of coordinate variables. With CRS information handy, this would allow us to |
| 25 | + |
| 26 | +1. Support wraparound indexing along the `longitude` dimension ({issue}`26`) |
| 27 | +1. Assign appropriate attributes to the created coordinate variables ({issue}`22`). (e.g. choose between `standard_name: latitude` and `standard_name: projection_y_coordinate`) |
| 28 | +1. more? |
| 29 | + |
| 30 | +### Why not encapsulate CRSIndex? |
| 31 | + |
| 32 | +If RasterIndex must track CRS in some form, one way to do that would be to have RasterIndex internally build a `CRSIndex` for the `spatial_ref` variable. |
| 33 | +Thus, `RasterIndex` would be associated with 3 variables instead of 2: `x`, `y`, and `spatial_ref`, for example. |
| 34 | + |
| 35 | +The downside of this approach is that it doesn't compose well with any other Index that would also like to handle the CRS (e.g. {py:class}`xvec.GeometryIndex`). |
| 36 | +The reason is that the Xarray model enforces that one variable is only associated with one Index. |
| 37 | +This restriction is needed because Indexes are responsible for creating associated variables, so we don't want two Indexes to have the ability to modify the same variable. |
| 38 | +For example, `xr.merge([geometries, raster])` where `geometries` has `xvec.GeometryIndex[geometry, spatial_ref]` (square brackets list associated coordinate variable names) and `raster` has `RasterIndex[x, y, spatial_ref]`, would fail because the variable `spatial_ref` is associated with two Indexes of different types. |
| 39 | + |
| 40 | +### CRS-aware Index |
| 41 | + |
| 42 | +Therefore, we have chosen to experiment with the "CRS-aware" approach described in the [xproj docs](https://xproj.readthedocs.io/en/latest/integration.html). |
| 43 | +Here `RasterIndex` tracks it's own _optional_ copy of a CRS object (not an Index) and defines the hooks needed for `CRSIndex` to communicate with `RasterIndex`. |
| 44 | +The downside here is that CRS information is duplicated in two places explicitly, and requires explicit handling to ensure consistency |
| 45 | + |
| 46 | +### Don't like it? |
| 47 | + |
| 48 | +We chose this approach to enable experimentation. It is entirely possible to experiment with other approaches. Please reach out if you have opinions on this topic. |
| 49 | + |
| 50 | +## Preserving RasterIndex after indexing |
| 51 | + |
| 52 | +A RasterIndex is only preserved when indexing with slices. |
| 53 | + |
| 54 | +Address |
| 55 | + |
| 56 | +1. `ds.isel(x=0, y=0)` |
| 57 | +1. `ds.isel(x=0)` |
| 58 | +1. `ds.isel(x=[0], y=[0])` |
| 59 | +1. `ds.isel(x=[0])` |
0 commit comments