Floating-Point / NULL Values in GRASS 5 Raster Maps

[small typo correction 21.Sept. 1999 MN]

STATUS: I am presently working on defining the upgrades to existing GRASS programs and any input would be very helpful. Please email suggestions to olga@zorro.

Contents

Objectives
Design decisions
C-API
Upgrades to existing programs
New programs

1. Objectives

2. Design decisions

This section describes some of the design decisions that have been made so far.

2.1 Floating-point maps

2.2 NULL-values

3. C-API

Contents of this section
Changes to "gis.h"
New NULL-value functions
New floating-point and type independant functions
Upgrades to raster functions
Color functions (new and upgraded)
Range functions (new and upgraded)
Upgraded Cell_stats functions
New Quantization functions
New and upgraded struct Categories interface functions
Deprecated functions

3.1. Changes to "gis.h"

The "gis.h" will contain 5 new items
	typedef float FCELL
	typedef double DCELL

	typedef int RASTER_MAP_TYPE;
	#define CELL_TYPE 0
	#define FCELL_TYPE 1
	#define DCELL_TYPE 2

Also gis.h will contain the definitions for new structures:
      struct FPReclass;
      struct FPRange;
      struct Quant;
Some of the old structures such as
      struct Categories
      struct Cell_stats;
      struct Range;
      struct _Color_Rule_;
      struct _Color_Info_;
      struct Colors;
were modified, so it is very important to use functional interface to access and set elements of these structures instead of accessing elements of the structures directly. Because some former elements such as for example (struct Range range.pmin ) do not exist anymore. I made sure non of the former elements have different meaning, so that the programs which do access the old elements directly either do not compile or work exactly the same way as prior to change.

3.2. New NULL-value functions

G_set_null_value (void *rast, int count, RASTER_MAP_TYPE data_type)
If the data_type is CELL_TYPE, calls G_set_c_null_value((CELL *) rast, count);

If the data_type is FCELL_TYPE, calls G_set_f_null_value((FCELL *) rast, count);

If the data_type is DCELL_TYPE, calls G_set_d_null_value((DCELL *) rast, count);

G_set_c_null_value (CELL *cell, int count)
Set the count elements in the cell array to the NULL value (the largest positive integer).

G_set_f_null_value (FCELL *fcell, int count)
Set the count elements in the fcell array to the NULL value (a bit pattern for a float NaN - 32 bits of 1's).

G_set_d_null_value (DCELL *dcell, int count)
Set the count elements in the dcell array to the NULL value - which (a bit pattern for a double NaN - 64 bits of 1's).

G_insert_null_values (rast, flags, count, data_type)
void *rast;
char *flags;
int count;
RASTER_MAP_TYPE data_type;
If the data_type is CELL_TYPE, calls G_insert_c_null_values ((CELL *) rast, flags, count);

If the data_type is FCELL_TYPE, calls G_insert_f_null_values ((FCELL *) rast, flags, count);

If the data_type is DCELL_TYPE, calls G_insert_d_null_values ((DCELL *) rast, flags, count);

G_insert_c_null_values (cell, flags, count)
CELL *cell;
char *flags;
int count;
For each of the count flags which is true(!=0), set the corresponding cell to the NULL value.

G_insert_f_null_values (fcell, flags, count)
FCELL *fcell;
char *flags;
int count;
For each of the count flags which is true(!=0), set the corresponding fcell to the NULL value.

G_insert_d_null_values (dcell, flags, count)
DCELL *dcell;
char *flags;
int count;
For each for the count flag which is true(!=0), set the corresponding dcell to the NULL value.

G_is_null_value (void *rast, RASTER_MAP_TYPE data_type)
If the data_type is CELL_TYPE, calls G_is_c_null_value ((CELL *) rast);

If the data_type is FCELL_TYPE, calls G_is_f_null_value (*(FCELL *) rast);

If the data_type is DCELL_TYPE, calls G_is_d_null_value ((DCELL *) rast);

G_is_c_null_value (CELL *cell)
Returns 1 if cell is NULL, 0 otherwise. This will test if the value cell is the largest int.

G_is_f_null_value (FCELL *fcell)
Returns 1 if fcell is NULL, 0 otherwise. This will test if the value fcell is a NaN. It isn't good enough to test for a particular NaN bit pattern since the machine code may change this bit pattern to a different NaN. The test will be

	if(fcell==0.0) return 0;
        if(fcell>0.0) return 0;
	if(fcell<0.0) return 0;
        return 1;
	
or (as suggested by Mark Line)
        return (fcell != fcell);
	

G_is_d_null_value (DCELL *dcell)
Returns 1 if dcell is NULL, 0 otherwise. This will test if the value dcell is a NaN. Same test as in G_is_f_null_value().

char *G_allocate_null_buf()
Allocate an array of char based on the number of columns in the current region.

G_get_null_value_row (int fd, char *flags, int row)
Reads a row from NULL value bitmap file for the raster map open for read on fd. If there is no bitmap file, then this routine simulates the read as follows: non-zero values in the raster map correspond to non-NULL; zero values correspond to NULL. When MASk exists, masked cells are set to null. flags is a resulting array of 0's and 1's where 1 corresponds to "no data" cell.

3.2. New Floating-point and type-independant functions

G_raster_map_is_fp(char *name, char *mapset)
Returns true(1) if raster map name in mapset is a floating-point dataset; false(0) otherwise

G_raster_map_type(char *name, char *mapset)
Returns the storage type for raster map name in mapset: CELL_TYPE (int); FCELL_TYPE (float); or DCELL_TYPE (double)

G_open_raster_new[_uncompressed](char *name, RASTER_MAP_TYPE map_type)
If map_type == CELL_TYPE, calls G_open_map_new[_uncompressed](name);

If map_type == FCELL_TYPE, calls G_set_fp_type (FCELL_TYPE); G_open_fp_map_new[_uncompressed](name);

If map_type == DCELL_TYPE, calls G_set_fp_type (DCELL_TYPE); G_open_fp_map_new[_uncompressed](name);

The use of this routine by applications is discouraged since its use would override user preferences (what precision to use).

G_set_fp_type (RASTER_MAP_TYPE type)
This controls the storage type for floating-point maps. It affects subsequent calls to G_open_fp_map_new(). The type must be one of FCELL_TYPE (float) or DCELL_TYPE (double). The use of this routine by applications is discouraged since its use would override user preferences.

G_open_fp_map_new (char *name)
Opens a new floating-point raster map (in .tmp) and returns a file descriptor. The storage type (float or double) is determined by the last call to G_set_fp_type() or the default (float - unless the Unix env variable GRASS_FP_DOUBLE is set).

void *G_allocate_raster_buf(RASTER_MAP_TYPE data_type)
Allocate an array of CELL, FCELL, or DCELL (depending on data_type) based on the number of columns in the current region.

CELL *G_allocate_c_raster_buf()
Allocate an array of CELL based on the number of columns in the current region.

FCELL *G_allocate_f_raster_buf()
Allocate an array of FCELL based on the number of columns in the current region.

DCELL *G_allocate_d_raster_buf()
Allocate an array of DCELL based on the number of columns in the current region.

void *G_incr_void_ptr (void *ptr, int size)
Advances void pointer by n bytes. returns new pointer value. Usefull in raster row processing loops, substitutes CELL *cell; cell += n; Now rast = G_incr_void_ptr(rast, G_raster_size(data_type)) (where rast is void* and data_type is RASTER_MAP_TYPE can be used instead of rast++.) very usefull to generalize the row processing - loop (i.e. void * buf_ptr += G_raster_size(data_type)

int G_raster_size (RASTER_MAP_TYPE data_type)
If data_type is CELL_TYPE, returns sizeof(CELL)

If data_type is FCELL_TYPE, returns sizeof(FCELL)

If data_type is DCELL_TYPE, returns sizeof(DCELL)

int G_raster_cmp (void *p, *q, RASTER_MAP_TYPE data_type)
compares raster vlues p and q. Returns 1 if p > q or only q is null value -1 if p < q or only p is null value 0 if p == q or p==q==null value

int G_raster_cpy (void *p, void *q, int n, RASTER_MAP_TYPE data_type)
copies raster vlues q into p. If q is null value, sets q to null value.

G_set_raster_value_c (void *p, CELL val, RASTER_MAP_TYPE data_type)
If G_is_c_null_value(val) is true, sets p to null value. Converts CELL val to data_type (type of p) and stores result in p. Used for assigning CELL values to raster cells of any type.

G_set_raster_value_f (void *p, FCELL val, RASTER_MAP_TYPE data_type)
If G_is_f_null_value(val) is true, sets p to null value. Converts FCELL val to data_type (type of p) and stores result in p. Used for assigning FCELL values to raster cells of any type.

G_set_raster_value_d (void *p, DCELL val, RASTER_MAP_TYPE data_type)
If G_is_d_null_value(val) is true, sets p to null value. Converts DCELL val to data_type (type of p) and stores result in p. Used for assigning DCELL values to raster cells of any type.

CELL G_get_raster_value_c (void *p, RASTER_MAP_TYPE data_type)
Retrieves the value of type data_type from pointer p, converts it to CELL type and returns the result. If null value is stored in p, returns CELL null value. Used for retreiving CELL values from raster cells of any type. NOTE: when data_type != CELL_TYPE, no quantization is used, only type conversion.

FCELL G_get_raster_value_f (void *p, RASTER_MAP_TYPE data_type)
Retrieves the value of type data_type from pointer p, converts it to FCELL type and returns the result. If null value is stored in p, returns FCELL null value. Used for retreiving FCELL values from raster cells of any type.

DCELL G_get_raster_value_d (void *p, RASTER_MAP_TYPE data_type)
Retrieves the value of type data_type from pointer p, converts it to DCELL type and returns the result. If null value is stored in p, returns DCELL null value. Used for retreiving DCELL values from raster cells of any type.

G_get_raster_row (int fd, void *rast, int row, RASTER_MAP_TYPE data_type)
If data_type is CELL_TYPE, calls G_get_c_raster_row(fd, (CELL *) rast, row);

If data_type is FCELL_TYPE, calls G_get_f_raster_row(fd, (FCELL *) rast, row);

If data_type is DCELL_TYPE, calls G_get_d_raster_row(fd, (DCELL *) rast, row);

G_get_raster_row_nomask (fd, fcell, row, map_type)
int fd;
FCELL *fcell;
int row;
RASTER_MAP_TYPE map_type;
Same as G_get_f_raster_row() except no masking occurs.

G_get_f_raster_row (int fd, FCELL fcell, int row)
Read a row from the raster map open on fd into the float array fcell performing type conversions as necessary based on the actual storage type of the map. Masking, resampling into the current region. NULL-values are always embedded in fcell (never converted to a value).

G_get_f_raster_row_nomask (fd, fcell, row)
int fd;
FCELL *fcell;
int row;
Same as G_get_f_raster_row() except no masking occurs.

G_get_d_raster_row (int fd, DCELL dcell, int row)
Same as G_get_f_raster_row() except that the array dcell is double.

G_get_d_raster_row_nomask (fd, dcell, row)
int fd;
DCELL *dcell;
int row;
Same as G_get_d_raster_row() except no masking occurs.

G_get_c_raster_row (int fd, CELL buf, int row)

Reads a row of raster data and leaves the NULL values intact. (As opposed to the deprecated function G_get_map_row() which converts NULL values to zero.) NOTE: when the raster map is old and null file doesn't exist, it is assumed that all 0-cells are no-data. When map is floating point, uses quant rules set explicitly by G_set_quant_rules or stored in map's quant file to convert floats to integers.

G_get_c_raster_row_nomask (int fd, CELL buf, int row)

Same as G_get_c_raster_row() except no masking occurs.

G_put_raster_row (int fd, void *rast, RASTER_MAP_TYPE data_type)
If data_type is CELL_TYPE, calls G_put_c_raster_row(fd, (CELL *) rast);

If data_type is FCELL_TYPE, calls G_put_f_raster_row(fd, (FCELL *) rast);

If data_type is DCELL_TYPE, calls G_put_d_raster_row(fd, (DCELL *) rast);

G_put_f_raster_row (int fd, FCELL *fcell)
Write the next row of the raster map open on fd from the float array fcell, performing type conversion to the actual storage type of the resultant map. Keep track of the range of floating-point values. Also writes the NULL-value bitmap from the NULL-values embedded in the fcell array.

G_put_d_raster_row (int fd, DCELL *dcell)
Same as G_put_f_raster_row() except that the array dcell is double.

G_put_c_raster_row (int fd, CELL buf)
Writes a row of raster data and a row of the null-value bitmap, only treating NULL as NULL. (As opposed to the deprecated function G_put_map_row() which treats zero values also as NULL.)

G_zero_raster_row (void *rast, RASTER_MAP_TYPE data_type)
Depending on data_type zeroes out G_window_cols() CELLs, FCELLs, or DCELLs stored in cell buffer.

3.3. Upgrades to Raster Functions

These routines will be modified (internally) to work with floating-point and NULL-values.

These routines are in the GISLIB.

G_close_cell()
If the map is a new floating point, move the .tmp file into the fcell element, create an empty file in the cell directory; write the floating-point range file; write a default quantization file quantization file is set here to round fp numbers (this is a default for now). create an empty category file, with max cat = max value (for backwards compatibility). Move the .tmp NULL-value bitmap file to the cell_misc directory.

G_open_cell_old()
Arrange for the NULL-value bitmap to be read as well as the raster map. If no NULL-value bitmap exists, arrange for the production of NULL-values based on zeros in the raster map.

If the map is floating-point, arrange for quantization to integer for G_get_c_raster_row(), et. al., by reading the quantization rules for the map using G_read_quant().

If the programmer wants to read the floating point map using uing quant rules other than the ones stored in map's quant file, he should call G_set_quant_rules() after the call to G_open_cell_old().

G_get_map_row()
If the map is floating-point, quantize the floating-point values to integer using the quantization rules established for the map when the map was opened for reading (this quantization is read from cell_misc/name/f_quant file, but can be reset after opening raster map by G_set_quant_rules()).

NULL values are converted to zeros.

This routine is deprecated .

G_put_map_row()
Zero values are converted to NULLs. Write a row of the NULL value bit map.

This routine is deprecated .

These routines are in the D_LIB.

Dcell()
If the map is a floating-point map, read the map using G_get_d_map_row() and plot using D_draw_d_cell(). If the map is an integer map, read the map using G_get_c_raster_row() and plot using D_draw_cell().

3.4. Color Functions (new and upgraded)

3.4.0 Upgraded Colors structures

struct _Color_Rule_
{
    struct
    {
	DCELL value;
	unsigned char red,grn,blu;
    } low, high;
    struct _Color_Rule_ *next;
    struct _Color_Rule_ *prev;
};

struct _Color_Info_
{
    struct _Color_Rule_ *rules;
    int n_rules;
    struct
    {
	unsigned char *red;
	unsigned char *grn;
	unsigned char *blu;
	unsigned char *set;
	int nalloc;
	int active;
    } lookup;
    struct
    {
        DCELL *vals;
	/* pointers to color rules corresponding to the intervals btwn vals */
	struct _Color_Rule_ **rules;
	int nalloc;
	int active;
    } fp_lookup;
    DCELL min, max;
};

struct Colors
{
    int version;	/* set by read_colors: -1=old,1=new */
    DCELL shift;
    int invert;
    int is_float;             /* defined on floating point raster data? */
    int null_set; /* the colors for null are set? */
    unsigned char null_red, null_grn, null_blu;
    int undef_set; /* the colors for cells not in range are set? */
    unsigned char undef_red, undef_grn, undef_blu;
    struct _Color_Info_ fixed, modular;
    DCELL cmin, cmax;
};

3.4.1 New functions to support colors for floating-point.

These routines are in the GISLIB.

G_lookup_raster_colors (rast, r, g, b, set, n, colors, cell_type)
void *rast;
char *r, *g, *b, *set;
int n;
struct Colors *colors;
RASTER_MAP_TYPE cell_type;
If the cell_type is CELL_TYPE, calls G_lookup_colors((CELL *)cell, r, g, b, set, n, colors);

If the cell_type is FCELL_TYPE, calls G_lookup_f_raster_colors(FCELL *)cell, r, g, b, set, n, colors);

If the cell_type is DCELL_TYPE, calls G_lookup_d_raster_colors(DCELL *)cell, r, g, b, set, n, colors);

G_lookup_c_raster_colors (cell, r, g, b, set, n, colors)
CELL *cell;
char *r, *g, *b, *set;
int n;
struct Colors *colors;
The same as G_lookup_colors(cell, r, g, b, set, n, colors).

G_lookup_f_raster_colors (fcell, r, g, b, set, n, colors)
FCELL *fcell;
char *r, *g, *b, *set;
int n;
struct Colors *colors;
Converts the n floating-point values in the fcell array to their r,g,b color components. Embedded NULL-values are handled properly as well.

G_lookup_d_raster_colors (dcell, r, g, b, set, n, colors)
DCELL *dcell;
char *r, *g, *b, *set;
int n;
struct Colors *colors;
Converts the n floating-point values in the dcell array to their r,g,b color components. Embedded NULL-values are handled properly as well.

G_add_raster_color_rule (v1, r1, g1, b1, v2, r2, g2, b2, colors, map_type)
void *v1, *v2;
int r1, g1, b1;
int r2, g2, b2;
struct Colors *colors;
RASTER_MAP_TYPE map_type;
If map_type is CELL_TYPE, calls G_add_c_raster_color_rule ((CELL *) v1, r1, g1, b1, (CELL *) v2, r2, g2, b2, colors);

If map_type is FCELL_TYPE, calls G_add_f_raster_color_rule ((FCELL *) v1, r1, g1, b1, (FCELL *) v2, r2, g2, b2, colors);

If map_type is DCELL_TYPE, calls G_add_d_raster_color_rule ((DCELL *) v1, r1, g1, b1, (DCELL *) v2, r2, g2, b2, colors);

G_add_c_raster_color_rule (v1, r1, g1, b1, v2, r2, g2, b2, colors)
CELL *v1, *v2;
int r1, g1, b1;
int r2, g2, b2;
struct Colors *colors;
Calls G_add_color_rule(*v1, r1, g1, b1, *v2, r2, g2, b2, colors).

G_add_f_raster_color_rule (v1, r1, g1, b1, v2, r2, g2, b2, colors)
FCELL *v1, *v2;
int r1, g1, b1;
int r2, g2, b2;
struct Colors *colors;
Adds the floating-point rule that the range [v1,v2] gets a linear ramp of colors from [r1,g1,b1] to [r2,g2,b2].

If either v1 or v2 is the NULL-value, this call is converted into G_set_null_value_color (r1, g1, b1, colors)

G_add_d_raster_color_rule (v1, r1, g1, b1, v2, r2, g2, b2, colors)
DCELL *v1, *v2;
int r1, g1, b1;
int r2, g2, b2;
struct Colors *colors;
Adds the floating-point rule that the range [v1,v2] gets a linear ramp of colors from [r1,g1,b1] to [r2,g2,b2].

If either v1 or v2 is the NULL-value, this call is converted into G_set_null_value_color (r1, g1, b1, colors)

G_get_raster_color (v, r, g, b, colors, data_type)
void *v;
int *r, *g, *b;
struct Colors *colors;
RASTER_MAP_TYPE data_type;
Looks up the rgb colors for v in the color table colors

G_get_c_raster_color (v, r, g, b, colors)
CELL *v;
int *r, *g, *b;
struct Colors *colors;
Calls G_get_color(*v, r, g, b, colors).

G_get_f_raster_color (v, r, g, b, colors)
FCELL *v;
int *r, *g, *b;
struct Colors *colors;
Looks up the rgb colors for v in the color table colors

G_get_d_raster_color (v, r, g, b, colors)
DCELL *v;
int *r, *g, *b;
struct Colors *colors;
Looks up the rgb colors for v in the color table colors

G_set_raster_color (v, r, g, b, colors, data_type)
void *v;
int r, g, b;
struct Colors *colors;
RASTER_MAP_TYPE data_type;
calls G_add_raster_color_rule (v, r, g, b, v, r, g, r, colors, data_type);

G_set_c_raster_color (v, r, g, b, colors)
CELL *v;
int r, g, b;
struct Colors *colors;
Calls G_set_color(*v, r, g, b, colors).

G_set_f_raster_color (v, r, g, b, colors)
FCELL *v;
int r, g, b;
struct Colors *colors;
Inserts a rule that assigns the color r,g,b to v. It is implemented as:

G_add_f_raster_color_rule (v, r, g, b, v, r, g, r, colors);

G_set_d_raster_color (v, r, g, b, colors)
DCELL *v;
int r, g, b;
struct Colors *colors;
Inserts a rule that assigns the color r,g,b to v. It is implemented as:

G_add_d_raster_color_rule (v, r, g, b, v, r, g, r, colors);

G_mark_colors_as_fp (struct Colors *colors)
Sets a flag in the colors structure that indicates that these colors should only be looked up using floating-point raster data (not integer data).

In particular if this flag is set, the routine G_get_colors_min_max() should return min=-255^3 and max=255^3.

These routines are in the DISPLAYLIB.

D_raster_of_type (rast, ncols, nrows, colors, data_type)
void *rast;
int ncols, nrows;
struct Colors *colors;
RASTER_MAP_TYPE data_type;
If map_type is CELL_TYPE, calls D_raster((CELL *) rast, ncols, nrows, colors);

If map_type is FCELL_TYPE, calls D_f_raster((FCELL *) rast, ncols, nrows, colors);

If map_type is DCELL_TYPE, calls D_d_raster((DCELL *) rast, ncols, nrows, colors);

D_f_raster (fcell, ncols, nrows, colors)
FCELL *fcell;
int ncols, nrows;
struct Colors *colors;
Same functionality as D_raster() except that the fcell array is type FCELL. This implies that the floating-point interfaces to the colors are used by this routine.

D_d_raster (dcell, ncols, nrows, colors)
DCELL *dcell;
int ncols, nrows;
struct Colors *colors;
Same functionality as D_raster() except that the dcell array is type DCELL. This implies that the floating-point interfaces to the colors are used by this routine.

D_color_of_type (value, colors, data_type)
void *value;
struct Colors *colors;
RASTER_MAP_TYPE data_type;
If the data_type is CELL_TYPE, calls D_color((CELL *value, colors);

If the data_type is FCELL_TYPE, calls D_f_color((FCELL *value, colors);

If the data_type is DCELL_TYPE, calls D_d_color((DCELL *value, colors);

D_f_color (value, colors)
FCELL *value;
struct Colors *colors;
Same functionality as D_color() except that the value is type FCELL. This implies that the floating-point interfaces to the colors are used by this routine.

D_d_color (value, colors)
DCELL *value;
struct Colors *colors;
Same functionality as D_color() except that the value is type DCELL. This implies that the floating-point interfaces to the colors are used by this routine.

D_lookup_raster_colors (rast, colornum, n, colors, data_type)
void *rast;
int *colornum;
int n;
struct Colors *colors;
RASTER_MAP_TYPE data_type;
If the data_type is CELL_TYPE, calls D_lookup_c_raster_colors((CELL *) rast, colornum, n, colors);

If the data_type is FCELL_TYPE, calls D_lookup_f_raster_colors((FCELL *) rast, colornum, n, colors);

If the data_type is DCELL_TYPE, calls D_lookup_d_raster_colors((DCELL *) rast, colornum, n, colors);

D_lookup_c_raster_colors (dcell, colornum, n, colors)
CELL *cell;
int *colornum;
int n;
struct Colors *colors;
Same functionality as D_lookup_colors() except that the resultant color numbers are placed into a separate colornum array (which the caller must allocate).

D_lookup_f_raster_colors (fcell, colornum, n, colors)
FCELL *fcell;
int *colornum;
int n;
struct Colors *colors;
Same functionality as D_lookup_colors() except that the fcell array is type FCELL and that the resultant color numbers are placed into a separate colornum array (which the caller must allocate).

D_lookup_d_raster_colors (dcell, colornum, n, colors)
DCELL *dcell;
int *colornum;
int n;
struct Colors *colors;
Same functionality as D_lookup_colors() except that the dcell array is type DCELL and that the resultant color numbers are placed into a separate colornum array (which the caller must allocate).

D_draw_cell_of_type(A_row, xarray, colors, map_type)
int A_row;
DCELL *xarray;
struct Colors *colors;
RASTER_MAP_TYPE map_type;
If map_type is CELL_TYPE, calls D_draw_cell (A_row, (CELL *) xarray, colors);

If map_type is FCELL_TYPE, calls D_draw_f_cell (A_row, (FCELL *) xarray, colors);

If map_type is DCELL_TYPE, calls D_draw_d_cell (A_row, (DCELL *) xarray, colors);

D_draw_f_cell (A_row, xarray, colors)
int A_row;
FCELL *xarray;
struct Colors *colors;
Same functionality as D_draw_cell() except that the xarray array is type FCELL which implies a call to D_f_raster() instead of a call to D_raster().

D_draw_d_cell (A_row, xarray, colors)
int A_row;
DCELL *xarray;
struct Colors *colors;
Same functionality as D_draw_cell() except that the xarray array is type DCELL which implies a call to D_d_raster() instead of a call to D_raster().

3.4.2. New functions to support a color for the NULL-value.

G_set_null_value_color (r, g, b, colors)
int r, g, b;
struct Colors *colors;
Sets the color (in colors) for the NULL-value to r,g,b.

G_get_null_value_color (r, g, b, colors)
int *r, *g, *b;
struct Colors *colors;
Puts the red, green, and blue components of the color for the NULL-value into r,g,b.

3.4.3. New functions to support a default color.

G_set_default_color (r, g, b, colors)
int r, g, b;
struct Colors *colors;
Sets the default color (in colors) to r,g,b. This is the color for values which do not have an explicit rule.

G_get_default_color (r, g, b, colors)
int *r, *g, *b;
struct Colors *colors;
Puts the red, green, and blue components of the "default" color into r,g,b.

3.4.4. Upgraded color functions

G_read_colors()
This routine reads the rules from the color file. If the input raster map is is a floating-point map it calls G_mark_colors_as_fp().

G_write_colors()
The rules are written out using floating-point format, removing trailing zeros (possibly producing integers). The flag marking the colors as floating-point is not written.

G_get_colors_min_max()
If the color table is marked as "float", then return the minimum as -(255^3 * 128) and the maximum as (255^3 * 128). This is to simulate a very large range so that GRASS doesn't attempt to use colormode float to allow interactive toggling of colors.

G_lookup_colors()
Modified to return a color for NULL-values.

G_get_color()
Modified to return a color for the NULL-value.

3.4.5. Changes to the Colors structure

Modifications to the Colors structure to support colors for floating-point data and the NULL-value consist of

  • the _Color_Rule_ struct was changed to have DCELL value (instead of CELL cat) to have the range be floating-point values instead of integer cats.
  • a color for NULL was added
  • the special color for zero was eliminated
  • a default color for values which have no assigned color was added
  • a flag was added to the Colors structure to indicate if either the map itself is floating-point (If the map is integer and the floating point functions are used to lookup colors, the values are checked to see if they are integer, and if they are, the integer mechanism is used)
  • fp_lookup - a lookup table for floating point numbers is added. It orders the end points of fp intervals into array with a pointer to a color rule for each inteval, and the binary search is then used when looking up colors instead of linearly searching through all color rules.

3.4.6. Changes to the colr file

  • The rules are written out using floating-point format, removing trailing zeros (possibly producing integers). For example, to ramp from red to green for the range [1.3,5.0]:

               1.3:255:0:0  5:0:255:0
    
  • The NULL-value color is written as:
               nv:red:grn:blu
    
  • The default color (for values that don't have an explicit rule) is written as:
               *:red:grn:blu
    

3.5. Range functions (new and upgraded)

3.5.1. Modified range functions

G_read_range()
Old range file (those with 4 numbers) should treat zeros in this file as NULL-values. New range files (those with just 2 numbers) should treat these numbers as real data (zeros are real data in this case).

An empty range file indicates that the min, max are undefined. This is a valid case, and the result should be an initialized range struct with no defined min/max.

If the range file is missing and the map is a floating-point map, this function will create a default range by calling G_construct_default_range().

G_init_range()
Must set a flag in the range structure that indicates that no min/max have been defined - probably a "first" boolean flag.

G_update_range()
NULL-values must be detected and ignored.

G_get_range_min_max()
If the range structure has no defined min/max (first!=0) there will not be a valid range. In this case the min and max returned must be the NULL-value.

G_write_range()
This routine only writes 2 numbers (min,max) to the range file, instead of the 4 (pmin,pmax,nmin,nmax) previously written. If there is no defined min,max, an empty file is written.

3.5.2. New range functions

G_construct_default_range (struct Range *r)
Sets the integer range r to [1,255]

G_read_raster_range (void *r, char *name, char *mapset, RASTER_MAP_TYPE map_type)
If map_type is CELL_TYPE, calls G_read_range((struct Range *) r, name, mapset); otherwise calls G_read_fp_range((struct FPRange *) r, name, mapset);

G_read_fp_range (struct FPRange *r, char *name, char *mapset)
Read the floating point range file f_range. This file is written in binary using XDR format. If there is no defined min/max in r, an empty f_rangefile is created.

An empty range file indicates that the min, max are undefined. This is a valid case, and the result should be an initialized range struct with no defined min/max.

If the range file is missing and the map is a floating-point map, this function will create a default range by calling G_construct_default_range().

G_init_raster_range (FPRange *r, RASTER_MAP_TYPE map_type)
If map_type is CELL_TYPE, calls G_init_range(struct Range *) r); otherwise calls G_init_fp_range((struct FPRange *) r);

G_init_fp_range (FPRange *r)
Must set a flag in the range structure that indicates that no min/max have been defined - probably a "first" boolean flag.

G_update_f_range (FPRange *r, FCELL *fcell, int n)
Updates the floating-point range r from the n FCELL values in fcell NULL-values must be detected and ignored.

G_update_d_range (FPRange *r, DCELL *dcell, int n)
Updates the floating-point range r from the n DCELL values in dcell NULL-values must be detected and ignored.

G_get_fp_range_min_max (FPRange *r, DCELL *min, DCELL *max)
Extract the min/max from the range structure r.

If the range structure has no defined min/max (first!=0) there will not be a valid range. In this case the min and max returned must be the NULL-value.

G_write_fp_range (FPRange *r)
Write the floating point range file f_range. This file is written in binary using XDR format. If there is no defined min/max in r, an empty f_rangefile is created.

3.6. New and Upgraded Cell_stats functions

Modified Cell_stats functions to handle NULL-values:
G_init_cell_stats()
Set the count for NULL-values to zero.
G_update_cell_stats()
Look for NULLs and update the NULL-value count.
G_next_cell_stat()
Do not return a record for the NULL-value
G_find_cell_stat()
Allow finding the count for the NULL-value
G_get_stats_for_null_value(int *count, struct Cell_stats *s)
Get a number of null values from stats structure. Note: when reporting values which appear in a map using G_next_cell_stats(), to get stats for null, call G_get_stats_for_null_value() first, since G_next_cell_stats() does not report stats for null.

3.7. New Quantization Functions

New functions to support quantization of floating-point to integer.
G_write_quant (char *name, char *mapset, struct Quant *q)
Writes the f_quant file for the raster map name from q.

if mapset==G_mapset() i.e. the map is in current mapset, then the original quant file in cell_misc/map/f_quant is written. Otherwise q is written into quant2/mapset/name (much like colr2 element). This results in map@mapset being read using quant rules stored in q from G_mapset(). Seee G_read_quant() for detailes.

G_set_quant_rules (int fd, struct Quant *q)
Sets quant translation rules for raster map opened for reading. fd is a file descriptor returned by G_open_cell_old(). After calling this function, G_get_c_raster_row() and G_get_map_row() will use rules defined by q (instead of using rules defined in map's quant file) to convert floats to ints.

G_read_quant (char *name, char *mapset, struct Quant *q)
reads quantization rules for "name" in "mapset" and stores them in the quantization structure "quant". If the map is in another mapset, first checks for quant2 table for this map in current mapset.

Return codes:

-2 if raster map is of type integer

-1 if (! G__name_is_fully_qualified ())

0 if quantization file does not exist, or the file is empty or has wrong format.

1 if non-empty quantization file exists.

G_quant_init (struct Quant *q)
Initializes the q struct.

G_quant_free (struct Quant *q)
Frees any memory allocated in q and re-initializes q by calling G_quant_init().

G_quant_truncate (struct Quant *q)
sets the quant for q rules to perform simple truncation on floats.

G_quant_truncate (struct Quant *q)
sets the quant for q rules to perform simple rounding on floats.

G_quant_organize_fp_lookup (struct Quant *quant)
Organizes fp_lookup table for faster (logarithmic) lookup time G_quant_organize_fp_lookup() creates a list of min and max for each quant rule, sorts this list, and stores the pointer to quant rule that should be used inbetween any 2 numbers in this list Also it stores extreme points for 2 infinite rules, if exist After the call to G_quant_organize_fp_lookup() instead of linearly searching through list of rules to find a rule to apply, quant lookup will perform a binary search to find an interval containing floating point value, and then use the rule associated with this interval. when the value doesn't fall within any interval, check for the infinite rules.

G_quant_add_rule (q, dmin, dmax, cmin, cmax)
struct Quant *q;
DCELL dmin, dmax;
CELL cmin, cmax;
Add the rule that the floating-point range [dmin,dmin] produces an integer in the range [cmin,cmax] by linear interpolation.

Rules that are added later have higher precedence when searching.

If any of of dmin, dmax cmin, or cmax is the NULL-value, this rule is not added and 0 is returned. Otherwise return 1. if the fp_lookup is organized, destroy it.

G_quant_set_positive_infinite_rule (q, dmax, c)
struct Quant *q;
DCELL dmax;
CELL c;
Set the rule that values greater than or equal to dmax produce the integer c. If dmax or c is the NULL-value, return 0 and don't set the rule. Otherwise return 1.

This rule has lower precedence than rules added with G_quant_add_rule().

G_quant_get_positive_infinite_rule (q, dmax, c)
struct Quant *q;
DCELL *dmax;
CELL *c;
Sets dmax and c to the positive "infinite" rule in q if there is one and returns 1. If there is no such rule, it just returns 0. if the fp_lookup is organized, updates infinite limits.

G_quant_set_negative_infinite_rule (q, dmin, c)
struct Quant *q;
DCELL dmin;
CELL c;
Set the rule that values less than or equal to dmin produce the integer c. If dmin or c is the NULL-value, return 0 and don't set the rule. Otherwise return 1. if the fp_lookup is organized, updates infinite limits.

This rule has lower precedence than rules added with G_quant_add_rule().

G_quant_get_negative_infinite_rule (q, dmin, c)
struct Quant *q;
DCELL *dmax;
CELL *c;
Sets dmin and c to the negative "infinite" rule in q if there is one and returns 1. If there is no such rule, it just returns 0.

G_quant_get_limits (q, dmin, dmax, cmin, cmax)
struct Quant *q;
DCELL *dmin, *dmax;
CELL *cmin, *cmax;
Extracts the minimum and maximum floating-point and integer values from all the rules (except the "infinite" rules) in q into dmin, dmax, cmin, and cmax. Returns 1 if there are any explicit rules. If there are no explicit rules, (this includes cases when q is set to truncate or round map), it returns 0 and sets dmin, dmax, cmin, and cmax to NULL.

G_quant_nrules (struct Quant *q)
Returns the number of rules in q, excluding the negative and positive "infinite" rules.

G_quant_get_rule (q, n, dmin, dmax, cmin, cmax)
struct Quant *q;
int n;
DCELL *dmin, *dmax;
CELL *cmin, *cmax;
Get the nth rule from q. If 0 <= n < nrules(q), extract the rule and return 1. Otherwise return 0. This function can't be used to get the "infinite" rules.

The order of the rules returned by increasing n is the order in which the rules are applied when quantizing a value - the first rule applicable is used.

CELL G_quant_get_cell_value (struct Quant *q, DCELL value)
Returns a CELL category for the floating-point value based on the quantization rules in q. The first rule found that applies is used. The rules are searched in the reverse order they are added to q. If no rule is found, the value is first tested against the negative infinite rule, and finally against the positive infinite rule. if none of these rules apply, the NULL-value is returned.

NOTE: see G_quant_organize_fp_lookup() for details on how the values are looked up from fp_lookup table when it is active. (Right now fp_lookup is automatically organized during the first call to G_quant_get_cell_value()

G_quant_perform_d (q, dcell, cell, n)
struct Quant *q;
DCELL *dcell;
CELL *cell;
int n;
Performs a quantization of the n DCELL values in the dcell array and puts the results into the cell array.

G_quant_perform_f (q, fcell, cell, n)
struct Quant *q;
FCELL *fcell;
CELL *cell;
int n;
Performs a quantization of the n FCELL values in the fcell array and puts the results into the cell array.

These next two functions are convenience functions to allow applications to easily create quantization rules other than the defaults.
G_quantize_fp_map (char *name, CELL cmin, CELL cmax)
Writes the f_quant file for the raster map name with one rule. The rule is generated using the floating-point range in f_range producing the integer range [cmin,cmax].

G_quantize_fp_map_range (name, dmin, dmax, cmin, cmax)
char *name;
DCELL dmin, dmax;
CELL cmin, cmax;
Writes the f_quant file for the raster map name with one rule. The rule is generated using the floating-point range [dmin,dmax] and the integer range [min,max].

This routine differs from the one above in that the application controls the floating-point range. For example, r.slope.aspect will use this routine to quantize the slope map from [0.0, 90.0] to [0, 90] even if the range of slopes is not 0-90. The aspect map would be quantized from [0.0, 360.0] to [0, 360].

3.8. Categories Labeling Functions (new and upgraded)

3.8.0 Upgraded Categories structure

All the new programs which are using Categories structure directly have to be modified to use API functions to update and retreive info from Categories structure. Both new and old API function can be used, since old functions still have exact same functionality (even though internally they are implemented very differently). New function names end with raster_cats(); old function names end with _cats().

We made sure that all old fields in Categories structure are either missing in new Categories structure or have exactly the same meaning. We did it so that the programs using Categories structure directly either do not compile with new gis library or work exactly the same as bnefore. A programmer might want to read the data in a floating point map in a way that each cell value stores index of it's category label and data range. The way to do it is to call G_set_quant_rules(fd, &pcats->q) after openning the map.

This is helpful when trying to collect statistics (how many cells of each category are in the map. (although there is another new mechanism to collect such stats - see G_mark_raster_cats()). Another reason to get a category index instead of fp values is that this index will be the FID into GRASS-DBMS link. Also he can use G_get_ith_raster_cat() to get the category information for each cell using this index.

Here is the new Categories structure defined in gis.h:

struct Categories
{
    CELL ncats            ;   /* total number of categories              */
    CELL num              ;   /* the highest cell values. Only exists    
				 for backwards compatibility = (CELL)
				 max_fp_values in quant rules            */
    char *title           ;   /* name of data layer                      */ 
    char *fmt             ;   /* printf-like format to generate labels   */
    float m1              ;   /* Multiplication coefficient 1            */
    float a1              ;   /* Addition coefficient 1                  */
    float m2              ;   /* Multiplication coefficient 2            */
    float a2              ;   /* Addition coefficient 2                  */
    struct Quant q        ;   /* rules mapping cell values to index in
				 list of labels                          */
    char **labels         ;   /* array of labels of size num             */	
    int * marks           ;   /* was the value with this label was used? */
    int nalloc;
    int last_marked_rule  ;
} ;

3.4.6. Changes to the cats file

The format of explicit label entries is the same for integer maps.

   cat:description
In addition label entries of new format is supported for floating point maps.

   val:descr (where val is a floating point number)
or

   val1:val2:descr (where val1, val2 is a floating point range)
Internally the labels are stored for fp ranges of data. However when the cats file is written, all the decimal zeros are stripped so that integer values appear as integers in the file. Also if values are the same, only 1 value is written (i.e. first format).

This way even though the old cats files will be processed differently internally, the user or application programmer will not notice this difference as long as the proper api is used and the elements of Categories structure are not accessed directly without API calls.

3.5. Range functions (new and upgraded)

3.8.1 New Functions to read/write access and modify Categories structure.

G_read_raster_cats (char *name, *mapset, struct Categories *pcats)
Is the same as existing G_read_cats()

G_copy_raster_cats (struct Categories *pcats_to, struct Categories *pcats_from)
Allocates NEW space for quant rules and labels n pcats_to and copies all info from pcats_from cats to pcats_to cats.

returns: 0 if successful -1 on fail

char *G_get_raster_cat (val, pcats, data_type)
void *val;
struct Categories *pcats;
RASTER_MAP_TYPE data_type;
given a raster value val of type data_type Returns pointer to a string describing category.

char *G_get_c_raster_cat (val, pcats)
CELL *val;
struct Categories *pcats;
given a CELL value val Returns pointer to a string describing category.

char *G_get_d_raster_cat (val, pcats)
DCELL *val;
struct Categories *pcats;
given a DCELL value val Returns pointer to a string describing category.

char *G_get_f_raster_cat (val, pcats)
FCELL *val;
struct Categories *pcats;
given a FCELL value val Returns pointer to a string describing category.

G_set_raster_cat (rast1, rast2, pcats, data_type)
void *rast1, *rast2;
struct Categories *pcats;
RASTER_MAP_TYPE data_type;
Adds the label for range rast1 through rast2 in category structure pcats.

G_set_c_raster_cat (rast1, rast2, pcats)
CELL *rast1, *rast2;
struct Categories *pcats;
Adds the label for range rast1 through rast2 in category structure pcats.

G_set_f_raster_cat (rast1, rast2, pcats)
FCELL *rast1, *rast2;
struct Categories *pcats;
Adds the label for range rast1 through rast2 in category structure pcats.

G_set_d_raster_cat (rast1, rast2, pcats)
DCELL *rast1, *rast2;
struct Categories *pcats;
Adds the label for range rast1 through rast2 in category structure pcats.

int *G_number_of_raster_cats (pcats)
Returns the number of labels. DO NOT use G_number_of_cats() (it returns max cat number)

char *G_get_ith_raster_cat (pcats, i, rast1, rast2, data_type)
void *rast1, *rast2; /* value range */
struct Categories *pcats;
int i;
RASTER_MAP_TYPE data_type;
Returns i-th description and i-th data range from the list of category descriptions with corresponding data ranges. Stores end points of data interval in rast1 and rast2 (after converting them to data_type.

char *G_get_ith_c_raster_cat (pcats, i, rast1, rast2)
CELL *rast1, *rast2; /* value range */
struct Categories *pcats;
int i;
Returns i-th description and i-th data range from the list of category descriptions with corresponding data ranges. end points of data interval in rast1 and rast2.

char *G_get_ith_d_raster_cat (pcats, i, rast1, rast2)
DCELL *rast1, *rast2; /* value range */
struct Categories *pcats;
int i;
Returns i-th description and i-th data range from the list of category descriptions with corresponding data ranges. end points of data interval in rast1 and rast2.

char *G_get_ith_f_raster_cat (pcats, i, rast1, rast2)
FCELL *rast1, *rast2; /* value range */
struct Categories *pcats;
int i;
Returns i-th description and i-th data range from the list of category descriptions with corresponding data ranges. end points of data interval in rast1 and rast2.

char *G_get_raster_cats_title (struct Categories *pcats)
Returns pointer to a string with title.

G_unmark_raster_cats (struct Categories *pcats)
Sets marks for all categories to 0. This initializes Categories structure for subsequest calls to G_mark_raster_cats (rast_row,...) for each row of data, where non-zero mark for i-th label means that some of the cells in rast_row are labeled with i-th label and fall into i-th data range.

These marks help determine from the Categories structure which labels were used and which weren't.

G_get_next_marked_raster_cat(pcats, rast1, rast2, stats, data_type)
void *rast1, *rast2; /* value range */
struct Categories *pcats;
long *stats;
RASTER_MAP_TYPE data_type;
Finds the next label and corresponding data range in the list of marked categories. The category (label + data range) is marked by G_mark_raster_cats (). End points of the data range are converted to data_type and returned in rast1, rast2. the number of times value from i-th cat. data range appeared so far is returned in stats. See G_unmark_raster_cats(), G_rewind_raster_cats() and G_mark_raster_cats ().

G_get_next_marked_c_raster_cat(pcats, rast1, rast2, stats)
CELL *rast1, *rast2; /* value range */
struct Categories *pcats;
long *stats;
Finds the next label and corresponding data range in the list of marked categories. The category (label + data range) is marked by G_mark_raster_cats (). End points of the data range are converted to data_type and returned in rast1, rast2. the number of times value from i-th cat. data range appeared so far is returned in stats. See G_unmark_raster_cats(), G_rewind_raster_cats() and G_mark_raster_cats ().

G_get_next_marked_f_raster_cat(pcats, rast1, rast2, stats)
FCELL *rast1, *rast2; /* value range */
struct Categories *pcats;
long *stats;
Finds the next label and corresponding data range in the list of marked categories. The category (label + data range) is marked by G_mark_raster_cats (). End points of the data range are converted to data_type and returned in rast1, rast2. the number of times value from i-th cat. data range appeared so far is returned in stats. See G_unmark_raster_cats(), G_rewind_raster_cats() and G_mark_raster_cats ().

G_get_next_marked_d_raster_cat(pcats, rast1, rast2, stats)
DCELL *rast1, *rast2; /* value range */
struct Categories *pcats;
long *stats;
Finds the next label and corresponding data range in the list of marked categories. The category (label + data range) is marked by G_mark_raster_cats (). End points of the data range are converted to data_type and returned in rast1, rast2. the number of times value from i-th cat. data range appeared so far is returned in stats. See G_unmark_raster_cats(), G_rewind_raster_cats() and G_mark_raster_cats ().

G_mark_raster_cats (rast_row, ncols, pcats, data_type)
void *rast_row; /* row of rtaster cell values */
struct Categories *pcats;
int ncols;
RASTER_MAP_TYPE data_type;
Looks up the category label for each raster value in the rast_row and updates the marks for labels found.

NOTE: non-zero mark for i-th label stores the number of of raster cells read so far which are labeled with i-th label and fall into i-th data range.

G_mark_c_raster_cats (rast_row, ncols, pcats)
CELL *rast_row; /* row of rtaster cell values */
struct Categories *pcats;
int ncols;
Looks up the category label for each raster value in the rast_row and updates the marks for labels found.

NOTE: non-zero mark for i-th label stores the number of of raster cells read so far which are labeled with i-th label and fall into i-th data range.

G_mark_f_raster_cats (rast_row, ncols, pcats)
FCELL *rast_row; /* row of rtaster cell values */
struct Categories *pcats;
int ncols;
Looks up the category label for each raster value in the rast_row and updates the marks for labels found.

NOTE: non-zero mark for i-th label stores the number of of raster cells read so far which are labeled with i-th label and fall into i-th data range.

G_mark_d_raster_cats (rast_row, ncols, pcats)
DCELL *rast_row; /* row of rtaster cell values */
struct Categories *pcats;
int ncols;
Looks up the category label for each raster value in the rast_row and updates the marks for labels found.

NOTE: non-zero mark for i-th label stores the number of of raster cells read so far which are labeled with i-th label and fall into i-th data range.

G_rewind_raster_cats ( struct Categories *pcats)
after calll to this function G_get_next_marked_raster_cat() returns rhe first marked cat label.

G_init_raster_cats (char *title, struct Categories *pcats)
Same as existing G_init_raster_cats() only ncats argument is missign. ncats has no meaning in new Categories structure and only stores (int) largets data value for backwards compatibility.

G_set_raster_cats_fmt (char *fmt, float m1, a1, m2, a2, struct Categories *pcats)
Same as existing G_set_cats_fmt()

G_set_raster_cats_title (char *title, struct Categories *pcats)
Same as existing G_set_cats_title()

G_write_raster_cats (char *name, struct Categories *pcats)
Same as existing G_write_cats()

G_free_raster_cats (struct Categories *pcats)
Same as existing G_free_cats()

3.9. Library Functions that are Deprecated

These functions are deprecated, since they imply that the application that uses them has not been upgraded to handle NULL-values and should be eliminated from GRASS code.

These functions are deprecated, since they can not be upgraded to support NULL-values, and should be eliminated from GRASS code.

Also, no support for random writing of floating-point rasters will be provided.

4. Upgrades to existing GRASS programs [status: 1995]

Contents of this section
Upgrades to raster programs
Upgrades to vector programs
Upgrades to sites programs
Upgrades to display programs
Upgrades to hardcopy output programs
Upgrades to g.* programs
Upgrades to m.* programs
Upgrades to imagery programs
Upgrades to shell scripts
This section provides guidelines for upgrading GRASS programs to process floating-point values and NULL-values. It also provides specific recommendations for many of the GRASS programs regarding user-interface and functional changes.

NOTE: There will be programs for which there is no recommedation given. This is because I didn't have time to examine these programs. The lack of specific recommendations should not be taken to mean that no upgrades are necessary, but that someone should examine the program and make recommendations.

4.1. Guidelines for upgrading GRASS programs

4.2. Upgrades to raster programs

In general programs that use G_get_map_row(). should use G_get_c_raster_row() instead.

Programs that use G_put_map_row(). should use G_put_c_raster_row() instead.


r.allocate
r.average
r.basins.fill
r.binfer
r.buffer
r.cats
r.clump
r.coin
r.colors
r.colors.paint
r.combine
r.compress
r.contour
r.cost
r.covar
r.cross
r.describe
r.digit
r.distance
r.drain
r.flow
r.gdbase
r.grow This code needs attention. It seems to me that it is not coded correctly.
r.in.ascii
r.in.elas
r.in.ll
r.in.poly
r.in.sunrast
r.infer
r.info
r.kappa
r.line
r.los
r.mask
r.mapcalc
r.mask.points
r.median
r.mfilter
r.mode
r.neighbors
r.out.ascii
r.out.elas
r.out.mpeg
r.out.tga
r.patch
r.poly
r.profile
r.random
r.reclass
r.report
r.resample
r.resample.tps.float
r.rescale
r.rescale.eq
r.slope.aspect
r.stats
r.support
r.surf.contour
r.surf.idw
r.surf.idw2
r.surf.voronoi
r.thin
r.transect
r.volume
r.watershed
r.watershed4.0
r.weight
r.weight.new
r.what
r.what.new

4.2. Upgrades to vector programs


v.to.rast
v.digit
xdigit

4.3. Upgrades to sites programs

General Guidelines: The conversion of sites to raster should be modified in all sites programs as follows:
s.menu
s.gdbase
s.in.ascii
s.out.ascii
s.reclass
s.surf.2d.float
s.surf.2d.float.alt
s.surf.2df
s.surf.idw
s.surf.tps
s.to.rast

4.4. Upgrades to display programs


d.3d
d.colors
d.colortable
d.display
d.his
d.histogram
d.legend
d.paint.labels
d.profile
d.rast
d.rast.arrow
d.rast.edit
d.rast.num
d.rgb
d.what.rast

4.5. Upgrades to hardcopy output programs


p.map
ps.map
p.colors

4.5. Upgrades to g.* programs


g.copy
g.list
g.remove
g.rename

g.region

4.6. Upgrades to m.* programs


m.clump
m.dem.extract
m.dmaUSGSread
m.dted.extract
m.lulc.USGS
m.lulc.read

4.7. Upgrades to imagery programs

General Guidelines:
i.cca
i.class
i.cluster
i.colors
i.composite
i.fft
i.gensig

These changes are for the cmd version.


i.gensigset

The comments for i.gensig apply here since i.gensigset shares a lot of code with i.gensig. The principle difference is that all the data is read into memory before processing.

In read_data.c test for NULLs and do not count them or insert them into the Data array. The same Warning! applies as for i.gensig.


i.grey.scale
i.his.rgb
i.ifft
i.in.erdas
i.kappa
i.maxlik
i.ortho.photo
i.pca
i.points
i.points3 I can't find it
i.vpoints

i.quantize
i.rectify
i.rectify2
i.rectify3 I can't find

i.rgb.his
i.smap
i.tape.mss
i.tape.other
i.tape.spot
i.tape.tm
i.tape.tm.fast
i.tape.tm3 I can't find

i.zc

4.8. Upgrades to shell scripts


3d.view.sh
blend.sh
dcorrelate.sh
demo.scripts
demo.sh
hsv.rgb.sh
intens.sh
rgb.hsv.sh
shade.clr.sh
shade.rel.sh

4.9. New Programs

These are programs that have been identified as needed to support the upgrade to floating-point raster maps as well is the introduction of a NULL-value.
r.null
r.null -fincr maps=name[,name...] [setnull=val[-val][,val[-val],...]] [null=value]

The function of r.null is to explicitly create the NULL-value bitmap file. The intended usage is to fix "old" maps that don't have a NULL-value bitmap file (i.e. to indicate if zero is valid value or is to be converted to NULL).

The design is flexible. Ranges of values can be set to NULL and/or the NULL value can be eliminated and replace with a specified value.

-f
Only do the work if the map is floating-point.
-i
Only do the work if the map is integer.
-n
Only do the work if the map doesn't have a NULL-value bitmap file.

-c
create NULL-value bitmap file which validates all data cells.

-r
remoe NULL-value bitmap file.

setnull=val[-val][,val[-val],...]]
The values specified in the ranges are to be set to NULL. A range is either a single value (e.g., 5.3), or a pair of values (e.g., 4.76-34.56). Existing NULL-values are left NULL, unless the null argument is requested.
null=value
Eliminate the NULL value and replace it with value This argument is applied only to existing NULL values, and not to the NULLs created by the setnull argument.

Note that value is restricted to integer if the map is an integer map.

r.in.rowcol
r.in.rowcol map=name [input=name]

This program would create a raster map with cells set to values for input row/col pairs (based on the current region). This program would be used by other programs that produce raster maps from site data. The input file format would be:

column row value [label]
The input would be from stdin if not specified or specified as input=-.

This program should be implemented using a paging scheme like that used by v.to.rast to allow the row/col lines to be unordered, yet write the resultant map using sequential raster writes.

If the input is from stdin, it would be copied to a tempfile first and then process from the tempfile. This is due to the above sequential-write requirement. The input may have to be read more than once.

If all the values in the input are integers, the map should be create as integer and the optional labels put into the category file. Missing labels do not update the catgeory label. This allows the input to have one label for the one occurrence of a value without having to label every occurrence

If any of the values are non-integer, the map should be created as floating-point and the optional labels ignored. No explicit category file would created for the resultant floating-point map.

r.recode
r.recode input=name output=name title=name [-a] Creates a new map in which cell values are results of applying user specified rules to the corresponding values in the input map. User is asked to enter the rules interactively. If some values on the right-hand side of the rules are floating point, the new map is double, otherwise it is integer.

r.quant
r.quant map=name[,map...] [basemap=map] [-tr] [fprange=dmin,dmax] [range=min,max]

This routine produces the quantization file for a floating-point map

map=name
The map for which the rules be to be created. If more than one map is specified, then this implies that the floating-point range is the miniumum and maximum of all the maps together, unless either basemap=map or fprange=dmin,dmax is specified.
basemap=map
The quant rules of this map set the quantization.
fprange=dmin,dmax
This sets the floating-point range for the quantization.
-t flag
Truncate the map.
-r flag
Round the map.
range=min,max
This sets the integer range for the quantization. Otherwise a default of 1-255 is used.
quant rules
The quant rules have to be entered interactively

If rules is specified, the input has the form:

value1:value2:cat1:[cat2]
where value1 and value2 are floating point values and cat1 cand cat2 are integers. If cat2 is missing, it is taken to be equal to cat1. All values can be "*" which means infinity.
NOTE: it is an error for both basemap and fprange to be specified.


Michael Shapiro <shapiro@zorro.cecer.army.mil>
Olga Waupotitcsh <olga@zorro.cecer.army.mil>