libral - Raster Algebra Library

1.0

Preface

NOTE: this document reflects the current SVN version and not any distribution version. However, the current grid API (mainly the functions here) is intended to be very stable. The visualization API (this and this) may change and it may even be separated into another library. The Cairo library may be used more in the future.

Libral is a part of the Geoinformatica stack.

Introduction

libral is a C library for raster algebra. libral contains also a system for rendering geospatial data on a pixel buffer. Mainly for the latter purpose libral also contains a system for vector data (points, lines, rectangles, and polygons). Lastly, libral contains a set of functions for hydrological analysis.

libral has support for importing data from GDAL and OGR into libral data structures.

The central C struct in libral is ral_grid, which contains pointer to a grid/raster data and its basic meta data (data type, size, value, which is used, if it exists, to denote cells without data, and the size of a cell and the location of the grid in a coordinate system). A libral grid contains either integer or real numbers. In the future there may be support for boolean, complex number, or other conceptually different data type grids. The actual C data type of RAL_INTEGER and RAL_REAL is up to the user to define in the configuration step, when libral is configured and compiled for a particular system. The cells of libral grids are square.

The cell coordinate system of a libral grid is (i,j), where (0,0) is up left and (grid->M-1,grid->N-1) (denoting with grid a pointer to a libral grid) is down right. Thus, i denotes the row and j the column. The world coordinate system of a libral grid is (x,y) where (grid->world.min.x,grid->world.min.y) is down left and (grid->world.max.x,grid->world.max.y) is up right. grid->data_type is the data type of the cell values (currently either RAL_INTEGER or RAL_REAL).

Return values and error handling

If an exception (error condition) happens during the processing of a function. libral returns a NULL instead of the object that was requested or zero if the function returns an integer. Exceptions are raised either because (i) memory allocation failed, (ii) the programmer (you) submitted bad data or something that you could and should have avoided, or (iii) something else went wrong. In the second case (assertion failed) an error message is printed to stderr and in the first and third cases the error message is stored in a global buffer. The error message may be checked and retrieved using two functions:

int ral_has_error_msg();
char *ral_get_error_msg();

Naming

Everything libral declares starts with ral_ or RAL_. Most libral functions are methods on libral classes and class method names start with prefix ral_something_ (denoting the classname with something).

Undefined (no data) values

Undefined values in computations or comparisons cause the result to be undefined. For example in grid1 plus grid2, if a cell in grid1 has undefined value, the resulting value in that cell is undefined. Note: by default a grid does not have a specific nodata value.

In the construct "if a then b = c" for grids. b is assigned c only if a is data and c is data.

int ral_grid_has_nodata_value(ral_grid *gd)
int ral_grid_get_integer_nodata_value(ral_grid *gd, RAL_INTEGER *nodata_value)
int ral_grid_get_real_nodata_value(ral_grid *gd, RAL_REAL *nodata_value)
int ral_grid_set_integer_nodata_value(ral_grid *gd, RAL_INTEGER nodata_value)
int ral_grid_set_real_nodata_value(ral_grid *gd, RAL_REAL nodata_value)
void ral_grid_remove_nodata_value(ral_grid *gd)

NOTE: getting and setting the nodata value of an integer grid with a real value is not a good idea

The method

int ral_grid_data(ral_grid *gd)

makes the grid into an integer grid, which has 0 where there were nodata values and 1 where there were data.

In-place changes

Usually a new grid is not returned when a method computes a new grid, instead the first argument which is grid, is changed in-place.

Conversion from integer to real valued grid and vice versa

If the method requires, for example when an integer grid is multiplied by a real value, the grid is silently converted into a real valued grid. All comparisons silently change the first grid argument into an integer grid because of the in-place operation.

Structures (classes)

libral defines many structures (classes) using the C syntax:

typedef struct {
    members;
} ral_something

If the structure has an associated constructor and a destructor their syntaxes are:

ral_something *ral_something_create(<parameter list>);
void ral_something_destroy(ral_something **object);

The destroy takes a pointer to a pointer to the object since it sets it to NULL to avoid usage of non-valid pointers.

or

int ral_something_init(ral_something object, <parameter list>);
void ral_something_finish(ral_something object);

Setting and getting the cell values of grids

For single cell values use one of:

RAL_INTEGER_GRID_CELL(grid, cell)
RAL_REAL_GRID_CELL(grid, cell)
int ral_grid_set_nodata(ral_grid *grid, ral_cell cell)

for setting and getting the value of the cell, except the last one, which cannot be used as a lvalue. The last one may fail since a grid does not have a specific value to denote cells with no data.

For a focal area use:

void ral_grid_set_focal(ral_grid *gd, ral_cell c, void *x, int *mask, int d)
void *ral_grid_get_focal(ral_grid *gd, ral_cell c, int d)

The focal area is defined by d and, when setting, the mask. The focal area is a square, whose side is 2*d + 1. The binary mask can be used to limit the area. The mask, x, and the returned value contain the cells of the focal area (square) raster left to right, top to down. x and the returned value are pointers to RAL_INTEGER or RAL_REAL depending on the type of the grid.

For a zonal area use:

void ral_integer_grid_floodfill(ral_grid *gd, ral_grid *done, ral_cell c, RAL_INTEGER pen, int connectivity)
void ral_real_grid_floodfill(ral_grid *gd, ral_grid *done, ral_cell c, RAL_REAL pen, int connectivity)

The zone in gd is defined as a continuous area of cells, whose value is pen. The connectivity is either 4 or 8. The zone is recorded in done if it exists (is non-NULL).

Global methods are:

int ral_grid_set_all_integer(ral_grid *gd, RAL_INTEGER x)
int ral_grid_set_all_real(ral_grid *gd, RAL_REAL x)
int ral_grid_set_all_nodata(ral_grid *gd)

For geometric areas use:

void ral_real_grid_line(ral_grid *gd, ral_cell c1, ral_cell c2, RAL_REAL pen)
void ral_integer_grid_line(ral_grid *gd, ral_cell c1, ral_cell c2, RAL_INTEGER pen)
void ral_real_grid_filled_rect(ral_grid *gd, ral_cell c1, ral_cell c2, RAL_REAL pen)
void ral_integer_grid_filled_rect(ral_grid *gd, ral_cell c1, ral_cell c2, RAL_INTEGER pen)
RAL_FILLED_CIRCLE(grid, cell, r, pen, assignment)
ral_cell_integer_values *ral_integer_grid_get_line(ral_grid *gd, ral_cell c1, ral_cell c2)
ral_cell_real_values *ral_real_grid_get_line(ral_grid *gd, ral_cell c1, ral_cell c2)
ral_cell_integer_values *ral_integer_grid_get_rect(ral_grid *gd, ral_cell c1, ral_cell c2)
ral_cell_real_values *ral_real_grid_get_rect(ral_grid *gd, ral_cell c1, ral_cell c2)
ral_cell_integer_values *ral_integer_grid_get_circle(ral_grid *gd, ral_cell c, int r)
ral_cell_real_values *ral_real_grid_get_circle(ral_grid *gd, ral_cell c, int r)

For assignment in RAL_FILLED_CIRCLE use either RAL_INTEGER_GRID_SET_CELL or RAL_REAL_GRID_SET_CELL.

Basic statistics of grids

Focal methods:

These are for single cells:

int ral_integer_grid_focal_sum(ral_grid *gd, ral_cell cell, int *mask, int delta, int *sum)
int ral_real_grid_focal_sum(ral_grid *gd, ral_cell cell, int *mask, int delta, double *sum)
int ral_grid_focal_mean(ral_grid *gd, ral_cell cell, int *mask, int delta, double *mean)
int ral_grid_focal_variance(ral_grid *gd, ral_cell cell, int *mask, int delta, double *variance)
int ral_grid_focal_count(ral_grid *gd, ral_cell cell, int *mask, int delta)
int ral_grid_focal_count_of(ral_grid *gd, ral_cell cell, int *mask, int delta, RAL_INTEGER value)
int ral_integer_grid_focal_range(ral_grid *gd, ral_cell cell, int *mask, int delta, ral_integer_range *r)
int ral_real_grid_focal_range(ral_grid *gd, ral_cell cell, int *mask, int delta, ral_real_range *r)

... and these affect the whole grid:

ral_grid *ral_grid_focal_sum_grid(ral_grid *grid, int *mask, int delta);
ral_grid *ral_grid_focal_mean_grid(ral_grid *grid, int *mask, int delta);
ral_grid *ral_grid_focal_variance_grid(ral_grid *grid, int *mask, int delta);
ral_grid *ral_grid_focal_count_grid(ral_grid *grid, int *mask, int delta);
ral_grid *ral_grid_focal_count_of_grid(ral_grid *grid, int *mask, int delta, RAL_INTEGER value);

Zonal methods:

ral_hash *ral_grid_zonal_sum(ral_grid *gd, ral_grid *zones)
ral_hash *ral_grid_zonal_mean(ral_grid *gd, ral_grid *zones)
ral_hash *ral_grid_zonal_variance(ral_grid *gd, ral_grid *zones)
ral_hash *ral_grid_zonal_count(ral_grid *gd, ral_grid *zones)
ral_hash *ral_grid_zonal_count_of(ral_grid *gd, ral_grid *zones, RAL_INTEGER value)
ral_hash *ral_grid_zonal_range(ral_grid *gd, ral_grid *zones)

Global methods:

double ral_grid_sum(ral_grid *gd)
double ral_grid_mean(ral_grid *gd)
double ral_grid_variance(ral_grid *gd)
long ral_grid_count(ral_grid *gd)
long ral_grid_count_of(ral_grid *gd, RAL_INTEGER value)
int ral_integer_grid_get_value_range(ral_grid *gd, ral_integer_range *range)
int ral_real_grid_get_value_range(ral_grid *gd, ral_real_range *range)

More raster methods

Reclassification and query of contents:

void ral_integer_grid_reclassify(ral_grid *gd, ral_hash *h)
ral_grid *ral_real_grid_reclassify(ral_grid *gd, RAL_REAL *x, RAL_INTEGER *y, int n)
ral_hash *ral_grid_contents(ral_grid *gd)
int ral_grid_zonal_contents(ral_grid *gd, ral_grid *zones, ral_hash ***table, ral_hash *index)
void ral_grid_histogram(ral_grid *gd, double *bins, int *counts, int n)

Generated on Thu May 17 00:13:55 2012 for libral by  doxygen 1.4.7