Raster Data

Raster Data

In this section, we revisit the gdalworkshop/world.tif dataset.

dataset = AG.read("gdalworkshop/world.tif")
GDAL Dataset (Driver: GTiff/GeoTIFF)
File(s): 

Dataset (width x height): 2048 x 1024 (pixels)
Number of raster bands: 3
  [GA_ReadOnly] Band 1 (Red): 2048 x 1024 (UInt8)
  [GA_ReadOnly] Band 2 (Green): 2048 x 1024 (UInt8)
  [GA_ReadOnly] Band 3 (Blue): 2048 x 1024 (UInt8)

A description of the display is available in Raster Datasets.

Raster Bands

We can examine an individual raster band

band = ArchGDAL.getband(dataset, 1)
[GA_ReadOnly] Band 1 (Red): 2048 x 1024 (UInt8)
    blocksize: 256×256, nodata: -1.0e10, units: 1.0px + 0.0
    overviews: (0) 1024x512 (1) 512x256 (2) 256x128 
               (3) 128x64 (4) 64x32 (5) 32x16 
               (6) 16x8 

You can programmatically retrieve the information in the header using

You can get additional attribute information using

Note

GDAL contains a concept of the natural block size of rasters so that applications can organized data access efficiently for some file formats. The natural block size is the block size that is most efficient for accessing the format. For many formats this is simple a whole scanline. However, for tiled images this will typically be the tile size.

Finally, you can obtain overviews:

ArchGDAL.getoverview(band, 2)
[GA_ReadOnly] Band 1 (Red): 256 x 128 (UInt8)
    blocksize: 128×128, nodata: -1.0e10, units: 1.0px + 0.0
    overviews: 

Raster I/O

Reading Raster Values

The general operative method for reading in raster values from a dataset or band is to use ArchGDAL.read().

Note

The array returned by read has (cols, rows, bands) dimensions.

To convert to a format used by the Images.jl ecosystem, you can either create a view using PermutedDimsArray(A, (3,2,1)) or create a permuted copy using permutedims(A, (3,2,1)). The resulting arrays will have (bands, rows, cols) dimensions.

You can also specify the subset of rows and columns (provided as UnitRanges like 2:9) to read:

On other occasions, it might be easier to first specify a position (xoffset,yoffset) to read from, and the size (xsize, ysize) of the window to read:

You might have an existing buffer that you wish to read the values into. In such cases, the general API for doing so is to write ArchGDAL.read!(source, buffer, args...) instead of ArchGDAL.read(source, args...).

Writing Raster Values

For writing values from a buffer to a raster dataset or band, the following methods are available:

Note

ArchGDAL expects the dimensions of the buffer to be (cols, rows, bands) or (cols, rows).

Windowed Reads and Writes

Following the description in mapbox/rasterio's documentation, a window is a view onto a rectangular subset of a raster dataset. This is useful when you want to work on rasters that are larger than your computers RAM or process chunks of large rasters in parallel.

For that purpose, we have a method called ArchGDAL.windows(band) which iterates over the windows of a raster band, returning the indices corresponding to the rasterblocks within that raster band for efficiency:

using Base.Iterators: take  # to prevent showing all blocks
windows = ArchGDAL.windows(band)

for (cols, rows) in take(windows, 5)
    @info "Window" cols rows
end
┌ Info: Window
│   cols = 1:256
└   rows = 1:256
┌ Info: Window
│   cols = 1:256
└   rows = 257:512
┌ Info: Window
│   cols = 1:256
└   rows = 513:768
┌ Info: Window
│   cols = 1:256
└   rows = 769:1024
┌ Info: Window
│   cols = 257:512
└   rows = 1:256

Alternatively, we have another method called ArchGDAL.blocks(band) which iterates over the windows of a raster band, returning the offset and size corresponding to the rasterblocks within that raster band for efficiency:

blocks = ArchGDAL.blocks(band)
for (xyoffset, xysize) in take(blocks, 5)
    @info "Window offset" xyoffset xysize
end
┌ Info: Window offset
│   xyoffset = (0, 0)
└   xysize = (256, 256)
┌ Info: Window offset
│   xyoffset = (1, 0)
└   xysize = (256, 256)
┌ Info: Window offset
│   xyoffset = (2, 0)
└   xysize = (256, 256)
┌ Info: Window offset
│   xyoffset = (3, 0)
└   xysize = (256, 256)
┌ Info: Window offset
│   xyoffset = (0, 1)
└   xysize = (256, 256)
Note

These methods are often used for reading/writing a block of image data efficiently, as it accesses "natural" blocks from the raster band without resampling, or data type conversion.