corteva / rioxarray

geospatial xarray extension powered by rasterio
https://corteva.github.io/rioxarray
Other
526 stars 83 forks source link

Add ability to describe color interpretation #191

Open atharen opened 3 years ago

atharen commented 3 years ago

Ability to handle color interpretation as enabled by Rasterio

Primarily ability to read existing color with Dataset.colorinterp, return the sequence of ColorInterp.<enum>, and the modify a Dataset by overriding it, similar to how descriptions work.

Put example of opening a dataset in r+ just to change description of bands and their respective color implementations:

with rasterio.open(dataset_path, 'r+') as src:
    src.descriptions = band_descriptions
    src.colorinterp = [rasterio.enums.ColorInterp.gray] * len(band_descriptions)

Probably a minor priority issue given that if you have rioxarray you have rasterio as well, but combining them both might be more readable/polished.

To be honest, have not looked as the source code to see if it is easy to implement, but would consider doing it if relatively minor.

For reference, I assume it would be similar for how descriptions work, by modifying the xarray attrs['long_name'].

Not sure if an alternative approach exists (recently started using rioxarray).

Could not find a related issue in either the issues page nor on gis stackexchange

snowman2 commented 3 years ago

When reading the raster, the photometric option might be available in the profile and you could add that to the attributes. Then, you could add a method to convert the rasterio.enums.ColorInterp to a photometric option and write that attribute to the xarray object's attributes and update to_raster to look for that.

Without modifying rioxarray, you can use the photometric option when writing to raster.

rds.rio.to_raster(...,photometric="RGB")

Otherwise, you will have to use rasterio to update the colorinterp as rioxarray doesn't support the update mode.

snowman2 commented 3 years ago

Another option would be to add a colorinterp kwarg to to_raster:

rds.rio.to_raster(...,colorinterp=[rasterio.enums.ColorInterp.gray] * len(band_descriptions))
weiji14 commented 3 years ago

Hi there :wave:, I'm interested in adding the color interpretation feature too. We're thinking of integrating rioxarray in PyGMT (see thread at https://github.com/GenericMappingTools/pygmt/issues/1555) and would be keen to help out :smile:

If it's just a matter of applying https://github.com/pydata/xarray/pull/3136 to the _get_rasterio_attrs function, I could probably open a quick PR for this

But to open a can of worms, is it ok to just store the color table in the xarray.DataArray's attr? Or should the RGB colors be read as separate bands? Just thinking how it will work with plotting the image later using .plot.imshow() (e.g. with the https://corteva.github.io/rioxarray/latest/examples/COG.html example).

snowman2 commented 3 years ago

Hi @weiji14, it would definitely be great if you would like to add the functionality.

The main changes that need to happen are:

  1. Load in the attributes when reading a file from rasterio ref. These will need to be converted into string/numeric types as necessary. This is so you can call .to_netcdf() without serialization issues.
  2. Write the attributes to the file ref. These will need to be converted to rasterio types as necessary.

If you are feeling extra motivated, you could add methods to the rio accessor to read/write color interpretation to the xarray object.

snowman2 commented 3 years ago

Side note, to plot RGB bands, here is an example ref

rds.astype("int").plot.imshow(rgb="band")