CRS handling

RasterIndex composes with xproj to provide CRS handling.

Hide code cell source

%xmode minimal

import xarray as xr

import rasterix

xr.set_options(display_expand_indexes=True)

Hide code cell output

Exception reporting mode: Minimal
<xarray.core.options.set_options at 0x7fdc497bc410>
source = "../data/S_20240101_concentration_v4.0.tif"

To enable CRS-handling, start by assigning a CRS using the .proj.assign_crs function from xproj.

da = xr.open_dataarray(source, engine="rasterio")
da = da.proj.assign_crs(spatial_ref=da.spatial_ref.attrs["crs_wkt"])
da = da.pipe(rasterix.assign_index)
da
<xarray.DataArray 'band_data' (band: 1, y: 332, x: 316)> Size: 420kB
[104912 values with dtype=float32]
Coordinates:
  * band         (band) int64 8B 1
  * y            (y) float64 3kB 4.338e+06 4.312e+06 ... -3.912e+06 -3.938e+06
  * x            (x) float64 3kB -3.938e+06 -3.912e+06 ... 3.912e+06 3.938e+06
  * spatial_ref  int64 8B ...
Indexes:
    spatial_ref  CRSIndex (crs=EPSG:3412)
  ┌ x            RasterIndex (crs=EPSG:3412)
  └ y
Attributes:
    AREA_OR_POINT:  Area

Note how the x variable has appropriate attributes!

da.x.attrs
{'axis': 'X',
 'long_name': 'Easting',
 'standard_name': 'projection_x_coordinate',
 'units': 'metre'}

Alignment

For demo purposes we’ll create a second copy with a different CRS.

diffcrs = da.copy(deep=True).drop_vars("spatial_ref").drop_indexes(["x", "y"])
diffcrs = diffcrs.proj.assign_crs(spatial_ref="epsg:4326").pipe(rasterix.assign_index)
diffcrs
<xarray.DataArray 'band_data' (band: 1, y: 332, x: 316)> Size: 420kB
[104912 values with dtype=float32]
Coordinates:
  * band         (band) int64 8B 1
  * y            (y) float64 3kB 4.338e+06 4.312e+06 ... -3.912e+06 -3.938e+06
  * x            (x) float64 3kB -3.938e+06 -3.912e+06 ... 3.912e+06 3.938e+06
  * spatial_ref  int64 8B 0
Indexes:
  ┌ x            RasterIndex (crs=EPSG:4326)
  └ y
    spatial_ref  CRSIndex (crs=EPSG:4326)
Attributes:
    AREA_OR_POINT:  Area

Again note that the attributes on x have changed appropriately. This is enabled by RasterIndex’s integration with xproj

diffcrs.x.attrs
{'standard_name': 'longitude',
 'long_name': 'longitude coordinate',
 'units': 'degrees_east',
 'axis': 'X'}

Attempting to add the two raises an error (as it should)!

diffcrs + da
ValueError: raster indexes on objects to align do not have the same CRS
first index:
RasterIndex(crs=EPSG:4326)
    AxisAffineTransformIndex(AxisAffineTransform(a=2.5e+04, b=0, c=-3.938e+06, d=0, e=-2.5e+04, f=4.338e+06, axis=X, dim='x'))
    AxisAffineTransformIndex(AxisAffineTransform(a=2.5e+04, b=0, c=-3.938e+06, d=0, e=-2.5e+04, f=4.338e+06, axis=Y, dim='y'))

second index:
RasterIndex(crs=EPSG:3412)
    AxisAffineTransformIndex(AxisAffineTransform(a=2.5e+04, b=0, c=-3.938e+06, d=0, e=-2.5e+04, f=4.338e+06, axis=X, dim='x'))
    AxisAffineTransformIndex(AxisAffineTransform(a=2.5e+04, b=0, c=-3.938e+06, d=0, e=-2.5e+04, f=4.338e+06, axis=Y, dim='y'))