Search code examples
juliaraster

Is there a way to rename the bands of a Raster in Rasters.jl?


This is the Raster I am using:

 30097×19617×4 Raster{UInt8,3} │
├───────────────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────── dims ┐
  ↓ X    Projected{Float64} LinRange{Float64}(12.996604689820469, 13.00021446808493, 30097) ForwardOrdered Regular Intervals{Start},
  → Y    Projected{Float64} LinRange{Float64}(51.65934139687541, 51.657878092285806, 19617) ReverseOrdered Regular Intervals{Start},
  ↗ Band Categorical{Int64} 1:4 ForwardOrdered

I want to change the values of Band from 1 to "Red", 2 to "Green", 3 to "Blue" and 4 to "Alpha".

Any suggestions?


Solution

  • The Raster struct and its dims tuple is not mutable, so a Raster's dimensions cannot be modified in place.

    It is possible to rebuild a Raster with a differently indexed dimension around the same data, such as Bands created with modify.

    An example raster with numbered bands:

    using DimensionalData, Rasters
    
    xCount = 9   # 30097
    yCount = 7   # 19617
    
    data = rand(UInt8, xCount, yCount, 4)
    
    xRange = LinRange(12.996604689820469, 13.00021446808493, xCount)
    yRange = LinRange(51.65934139687541, 51.657878092285806, yCount)
    bandRange = 1:4
    
    dimData = DimArray(data, (X=xRange, Y=yRange, Bands=bandRange))
    
    rasterWithNumberedBands = Raster(dimData)
    

    Rebuild as raster with symbol names of Bands, keeping the same data:

    bandSymbols = [:Red, :Green, :Blue, :Alpha]
    
    @assert length(bandRange) == length(bandSymbols)
    
    rasterWithSymbolNamedBands =
        rebuild(rasterWithNumberedBands,
                dims = map(rasterWithNumberedBands.dims) do dim
                         if :Bands == name(dim)
                           modify(dimRange -> bandSymbols, dim)
                         else
                           dim
                         end
                       end)
    

    Compare indexing by integer and indexing by a symbol

    rasterWithNumberedBands[:, :, 3] == rasterWithSymbolNamedBands[:, :, At(:Blue)]
    

    (The Bands of rasterWithSymbolNamedBands can still be indexed with an integer or integer range.)

    rasterWithSymbolNamedBands[:, :, 3]
    rasterWithSymbolNamedBands[:, :, 1:3]