wiki:rfc62_raster_algebra

Version 4 (modified by Ari Jolma, 8 years ago) ( diff )

Clarify the approach and show code

RFC 62 : Raster algebra

Author: Ari Jolma

Contact: ari.jolma at gmail.com

Status: Development

Implementation in version:

Summary

It is proposed that a set of functions or methods for raster band object are written to support "raster algebra", i.e., a set of operations, which modify bands or compute values from bands. An example of a modification is adding a value to all the cells of the band. An example of a computation is the maximum cell value in the band. Operations may or may not take arguments, in addition to the band itself, and if they take, the argument may be a numeric value, a data structure, or another band. Similarly, the computed value may be a simple numeric value, a data structure, or another band.

Rationale

Raster algebra is a well known branch of geospatial science and technology and an often needed tool. Currently GDAL does not have comprehensive support for raster algebra in core.

Approach

GDAL presents a few problems to raster algebra implementation: 1) the access to data is based on blocks, 2) GDAL supports several datatypes, even complex values, and 3) there is no immediate support for the not-simple data structures needed by some methods (by "method" I refer to functions of raster algebra in this text). In the development version of raster algebra for GDAL (see below the github link) these problems are solved as follows.

1) The code is organized into two levels: the first one, which loops through all blocks in band(s) and maintains a cache of needed blocks, and the second one, which loops through all cells in a block. The first level is generic one and the method and its arguments just pass through it. The method is passed as a callback and arguments as a void pointer. The second one is method specific, it is where the method is really implemented. The method callbacks must have similar prototype and their return value is used to, e.g., determine whether the block needs to be written to disk etc.

2) C++ templates are used to convey to the method functions the cell datatype. There is a problem of deducing the datatype (as type) from RasterBand objects. This is solved currently with switches. The switches become rather large in case of two bands and even more so since some methods can only be fed integer bands. Type traits can be used to test against templated types.

3) An interface class structure is used for arguments and return values (non-band). The interface classes are not templated, they shadow actual classes, which are templated and use STL as much as possible.

// the API:

// a function to create an argument
gma_object_t *gma_new_object(GDALRasterBand *b, gma_class_t klass);

// the next two could also be one if arg is null by default
void gma_simple(GDALRasterBand *b, gma_method_t method);
void gma_with_arg(GDALRasterBand *b, gma_method_with_arg_t method, gma_object_t *arg);

gma_object_t *gma_compute_value(GDALRasterBand *b, gma_method_compute_value_t method, gma_object_t *arg = NULL);
gma_object_t *gma_two_bands(GDALRasterBand *b1, gma_two_bands_method_t method, GDALRasterBand *b2, gma_object_t *arg = NULL);

// errors are logged with CPLError, so the error status should be checked after every call to these functions

// arguments can be created into these classes (the list is tentative)

typedef enum {
    gma_number,
    gma_integer, // not a real class, used to create a number, which is integer
    gma_pair,
    gma_range,  // not a real class, used to create a pair of two numbers of band datatype
    gma_bins,
    gma_histogram,
    gma_reclassifier,
    gma_cell,
    gma_logical_operation
} gma_class_t;

// the public classes contain only virtual methods
// and they shadow the real classes which are template classes

// class introspection
// after the class is known, it is legal to cast gma_object_t* to the returned class
virtual gma_class_t get_class() {return gma_XXX;};

// each class will have methods to build it / retrieve data from it

// methods are organized into groups according to the API

// these do not take any arguments and operate on the band in-place
typedef enum { 
    gma_method_print, 
    gma_method_rand,
    gma_method_abs,
    gma_method_exp,
    gma_method_exp2,
    gma_method_log,
    gma_method_log2,
    gma_method_log10,
    gma_method_sqrt,
    gma_method_sin,
    gma_method_cos,
    gma_method_tan,
    gma_method_ceil,
    gma_method_floor,
    gma_method_set_border_cells
} gma_method_t;

// these take optionally an argument and compute a value from the band
typedef enum { 
    gma_method_histogram,
    gma_method_zonal_neighbors,
    gma_method_get_min,
    gma_method_get_max,
    gma_method_get_range,
    gma_method_get_cells
} gma_method_compute_value_t;

// these take an argument and operate on the band in-place
typedef enum { 
    gma_method_assign,
    gma_method_add,
    gma_method_subtract,
    gma_method_multiply,
    gma_method_divide,
    gma_method_modulus,
    gma_method_map
} gma_method_with_arg_t;

// these take an argument band and optionally another argument and operate on the band in-place
typedef enum { 
    gma_method_assign_band,
    gma_method_add_band,
    gma_method_subtract_band,
    gma_method_multiply_by_band,
    gma_method_divide_by_band,
    gma_method_modulus_by_band,
    gma_method_zonal_min,
    gma_method_zonal_max,
    gma_method_set_zonal_min,
    gma_method_rim_by8,
    gma_method_depression_pour_elevation,
    gma_method_fill_dem,
    gma_method_D8,
    gma_method_route_flats,
    gma_method_depressions,
    gma_method_upstream_area,
    gma_method_catchment
} gma_two_bands_method_t;


Changes

The RFC can be implemented as methods in the RasterBand class or as a set of C callable functions. This needs to be decided.

Drivers

Drivers are not affected.

Bindings

The functionality will be added to the bindings.

Utilities

A new utility will be written to take advantage of the functionality.

Documentation

Will be written.

Test Suite

Will be written.

Compatibility Issues

Related tickets

Implementation

The implementation will be done by Ari Jolma.

The proposed implementation will be in https://github.com/ajolma/gdal

Voting history

Note: See TracWiki for help on using the wiki.