GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Raster File Processing

GRASS Raster File Processing

TODO: this sections needs to be cleaned up. The upper GRASS 4.x and the lower GRASS 5.x/6.x parts need to me merged.

Raster files are the heart and soul of GRASS (update 2005: meanwhile also vector data processing entered GRASS' heart). Because of this, a suite of routines which process raster file data has been provided. The processing of raster files consists of determining which raster file or files are to be processed (either by prompting the user or as specified on the module command line), locating the raster file in the database, opening the raster file, dynamically allocating i/o buffers, reading or writing the raster file, closing the raster file, and creating support files for newly created raster files.

Raster file data can be of type CELL, FCELL or DCELL, they are defined in "gis.h". CELL is a 32-bit signed integer, FCELL is an IEEE single-precision floating-point, and DCELL is an IEEE double-precision floating-point. G3D (GRID3D) is treated as DCELL.

Prompting for Raster Files

The following routines interactively prompt the user for a raster file name. In each, the prompt string will be printed as the first line of the full prompt which asks the user to enter a raster file name. If prompt is the empty string "" then an appropriate prompt will be substituted. The name that the user enters is copied into the name buffer (The size of name should be large enough to hold any GRASS file name. Most systems allow file names to be quite long. It is recommended that name be declared char name.) These routines have a built-in 'list' capability which allows the user to get a list of existing raster files.

The user is required to enter a valid raster file name, or else hit the RETURN key to cancel the request. If the user enters an invalid response, a message is printed, and the user is prompted again. If the user cancels the request, the NULL pointer is returned. Otherwise the mapset where the raster file lives or is to be created is returned. Both the name and the mapset are used in other routines to refer to the raster file.

char * G_ask_cell_old(char *prompt, char *name) prompt for existing raster file

Asks the user to enter the name of an existing raster file in any mapset in the database.

char * G_ask_cell_in_mapset(char *prompt, char *name) prompt for existing raster file

Asks the user to enter the name of an existing raster file in the current mapset.

char * G_ask_cell_new(char *prompt, char *name) prompt for new raster file

Asks the user to enter a name for a raster file which does not exist in the current mapset.

Here is an example of how to use these routines. Note that the programmer must handle the NULL return properly:

char *mapset;
char name[GNAME_MAX];

mapset = G_ask_cell_old("Enter raster file to be processed", name);

if (mapset == NULL)
  return(0);

Finding Raster Files

in the Database

Noninteractive modules cannot make use of the interactive prompting routines described above. For example, a command line driven module may require a raster file name as one of the command arguments. GRASS allows the user to specify raster file names (or any other database file) either as a simple unqualified name, such as "soils", or as a fully qualified name, such as "soils@<I>mapset</I>", where mapset is the mapset where the raster file is to be found. Often only the unqualified raster file name is provided on the command line.

The following routines search the database for raster files:

char * G_find_cell(char *name, char *mapset) find a raster file

Looks for the raster file name in the database. The mapset parameter can either be the empty string "", which means search all the mapsets in the user's current mapset search path, or it can be a specific mapset name, which means look for the raster file only in this one mapset (for example, in the current mapset) . If found, the mapset where the raster file lives is returned. If not found, the NULL pointer is returned.

If the user specifies a fully qualified raster file which exists, then G_find_cell() modifies name by removing the "@<I>mapset</I>".

For example, to find a raster file anywhere in the database:

char name[GNAME_MAX];
char *mapset;

if ((mapset = G_find_cell(name,"")) == NULL)
  /* not found */

To check that the raster file exists in the current mapset:

char name[GNAME_MAX];

if (G_find_cell(name,G_mapset()) == NULL)
  /* not found */

Opening an Existing Raster File

The following routine opens the raster file name in mapset for reading.

The raster file name and mapset can be obtained interactively using G_ask_cell_old() or G_ask_cell_in_mapset(), and noninteractively using G_find_cell().

int G_open_cell_old(char *name, char *mapset) open an existing raster file

This routine opens the raster file name in mapset for reading. A nonnegative file descriptor is returned if the open is successful. Otherwise a diagnostic message is printed and a negative value is returned. This routine does quite a bit of work. Since GRASS users expect that all raster files will be resampled into the current region, the resampling index for the raster file is prepared by this routine after the file is opened. The resampling is based on the active module region. Preparation required for reading the various raster file formats is also done.

Creating and Opening New Raster Files

The following routines create the new raster file name in the current mapset [footnote] and open it for writing. The raster file name should be obtained interactively using G_ask_cell_new. If obtained noninteractively (e.g., from the command line) , G_legal_filename should be called first to make sure that name is a valid GRASS file name.

Note. It is not an error for name to already exist. New raster files are actually created as temporary files and moved into the cell directory when closed. This allows an existing raster file to be read at the same time that it is being rewritten. The interactive routine G_ask_cell_new guarantees that name will not exist, but if name is obtained from the command line, name may exist. In this case G_find_cell could be used to see if name exists.

Warning. However, there is a subtle trap. The temporary file, which is created using G_tempfile, is named using the current process id. If the new raster file is opened by a parent process which exits after creating a child process using fork(), [footnote] the raster file may never get created since the temporary file would be associated with the parent process, not the child. GRASS management automatically removes temporary files associated with processes that are no longer running. If fork() must be used, the safest course of action is to create the child first, then open the raster file. (See the discussion under G_tempfile() for more details.)

FILE * G_open_cell_new(char *name) open a new raster file (sequential) Creates and opens the raster file name for writing by G_put_map_row which writes the file row by row in sequential order. The raster file data will be compressed as it is written.

A nonnegative file descriptor is returned if the open is successful. Otherwise a diagnostic message is printed and a negative value is returned.

FILE * G_open_cell_new_random(char *name) open a new raster file (random) Creates and opens the raster file name for writing by G_put_map_row_random which allows writing the raster file in a random fashion. The file will be created uncompressed. [footnote]

A nonnegative file descriptor is returned if the open is successful. Otherwise a diagnostic message is printed and a negative value is returned.

FILE * G_open_cell_new_uncompressed(char *nameopen a new raster file (uncompressed) Creates and opens the raster file name for writing by G_put_map_row which writes the file row by row in sequential order. The raster file will be in uncompressed format when closed.

A nonnegative file descriptor is returned if the open is successful. Otherwise a warning message is printed on stderr and a negative value is returned.

General use of this routine is not recommended. [footnote] This routine is provided so the r.compress module can create uncompressed raster files.

Allocating Raster I/O Buffers

Since there is no predefined limit for the number of columns in the region,[footnote] buffers which are used for reading and writing raster data must be dynamically allocated.

CELL * G_allocate_cell_buf(void) allocate a raster buffer This routine allocates a buffer of type CELL just large enough to hold one row of raster data (based on the number of columns in the active region).

CELL *cell;
cell = G_allocate_cell_buf(void) ;

If larger buffers are required, the routine G_malloc can be used.

If sufficient memory is not available, an error message is printed and exit() is called.

int G_zero_cell_buf(CELL *buf) zero a raster buffer This routines assigns each member of the raster buffer array buf to zero. It assumes that buf has been allocated using G_allocate_cell_buf.

Reading Raster Files

Needs updating for GRASS 5!! See later in this file.

Raster data can be thought of as a two-dimensional matrix. The routines described below read one full row of the matrix. It should be understood, however, that the number of rows and columns in the matrix is determined by the region, not the raster file itself. Raster data is always read resampled into the region. [footnote] This allows the user to specify the coverage of the database during analyses. It also allows databases to consist of raster files which do not cover exactly the same area, or do not have the same grid cell resolution. When raster files are resampled into the region, they all "look" the same.

Note. The rows and columns are specified "C style", i.e., starting with 0.


THIS FUNCTION IS DEPRECATED IN GRASS 5! SEE NEXT CHAPTER!

int G_get_map_row (int fd, CELL *cell, int row) read a raster file This routine reads the specified row from the raster file open on file descriptor fd (as returned by G_open_cell_old) into the cell buffer. The cell buffer must be dynamically allocated large enough to hold one full row of raster data. It can be allocated using G_allocate_cell_buf.

This routine prints a diagnostic message and returns -1 if there is an error reading the raster file. Otherwise a nonnegative value is returned.

int G_get_map_row_nomask (int fd, CELL *cell, int row) read a raster file (without masking) This routine reads the specified row from the raster file open on file descriptor fd into the cell buffer like G_get_map_row() does. The difference is that masking is suppressed. If the user has a mask set, G_get_map_row() will apply the mask but G_get_map_row_nomask() will ignore it.

This routine prints a diagnostic message and returns -1 if there is an error reading the raster file. Otherwise a nonnegative value is returned.

Note. Ignoring the mask is not generally acceptable. Users expect the mask to be applied. However, in some cases ignoring the mask is justified. For example, the GRASS modules r.describe, which reads the raster file directly to report all data values in a raster file, and r.slope.aspect, which produces slope and aspect from elevation, ignore both the mask and the region. However, the number of GRASS modules which do this should be minimal. See Mask for more information about the mask.

Writing Raster Files

Needs updating for GRASS 5!! See later in this file.

The routines described here write raster file data.

int G_put_map_row (int fd, CELL *buf) write a raster file (sequential) This routine writes one row of raster data from buf to the raster file open on file descriptor fd. The raster file must have been opened with G_open_cell_new.

The cell buf must have been allocated large enough for the region, perhaps using G_allocate_cell_buf.

If there is an error writing the raster file, a warning message is printed and -1 is returned. Otherwise 1 is returned.

Note. The rows are written in sequential order. The first call writes row 0, the second writes row 1, etc. The following example assumes that the raster file name is to be created:

int fd, row, nrows, ncols;

CELL *buf;

fd = G_ope... /*...data for the row */

G_put_map_row(fd, buf) ;

int G_put_map_row_random (int fd, CELL *buf, int row, int col, int ncells) write a raster file (random) This routine allows random writes to the raster file open on file descriptor fd. The raster file must have been opened using G_open_cell_new_random. The raster buffer buf contains ncells columns of data and is to be written into the raster file at the specified row, starting at column col.

Closing Raster Files

All raster files are closed by one of the following routines, whether opened for reading or for writing.

int G_close_cell (int fd) close a raster file The raster file opened on file descriptor fd is closed. Memory allocated for raster processing is freed. If open for writing, skeletal support files for the new raster file are created as well.

Note. If a module wants to explicitly write support files (e.g., a specific color table) for a raster file it creates, it must do so after the raster file is closed. Otherwise the close will overwrite the support files. See Raster Map Layer Support Routines for routines which write raster support files.

int G_unopen_cell (int fd) unopen a raster file The raster file opened on file descriptor fd is closed. Memory allocated for raster processing is freed. If open for writing, the raster file is not created and the temporary file created when the raster file was opened is removed (see Creating_and_Opening_New_Raster_Files) .

This routine is useful when errors are detected and it is desired to not create the new raster file. While it is true that the raster file will not be created if the module exits without closing the file, the temporary file will not be removed at module exit. GRASS database management will eventually remove the temporary file, but the file can be quite large and will take up disk space until GRASS does remove it. Use this routine as a courtesy to the user.

Raster Map Layer Support Routines

GRASS map layers have a number of support files associated with them. These files are discussed in detail in Raster_Maps. The support files are the raster header, the category file, the color table, the history file, and the range file. Each support file has its own data structure and associated routines.

Raster Header File

The raster header file contains information describing the geographic extent of the map layer, the grid cell resolution, and the format used to store the data in the raster file. The format of this file is described in Raster_Header_Format. The routines described below use the Cell_head structure which is shown in detail in GIS_Library_Data_Structures.

int G_get_cellhd(char *name, char *mapset, struct Cell_Head cellhd) read the raster headerThe raster header for the raster file name in the specified mapset is read into the cellhd structure.

If there is an error reading the raster header file, a diagnostic message is printed and -1 is returned. Otherwise, 0 is returned.

Note. If the raster file is a reclass file, the raster header for the referenced raster file is read instead. See Reclass_Format for information about reclass files, and G_is_reclass for distinguishing reclass files from regular raster files.

Note. It is not necessary to get the raster header for a map layer in order to read the raster file data. The routines which read raster file data automatically retrieve the raster header information and use it for resampling the raster file data into the active region. [footnote] If it is necessary to read the raster file directly without resampling into the active region, [footnote] then the raster header can be used to set the active region using G_set_window.

char * G_adjust_Cell_head(struct Cell_Head *cellhd, int rflag, int cflag) adjust cell headerThis function fills in missing parts of the input cell header (or region) . It also makes projection-specific adjustments. The cellhd structure must have its north, south, east, west, and proj fields set. If rflag is true, then the north-south resolution is computed from the number of rows in the cellhd structure. Otherwise the number of rows is computed from the north-south resolution in the structure, similarly for cflag and the number of columns and the east-west resolution. This routine returns NULL if execution occurs without error, otherwise it returns an error message.

char * G_put_cellhd(char *name, struct Cell_Head *cellhd) write the raster header This routine writes the information from the cellhd structure to the raster header file for the map layer name in the current mapset.

If there was an error creating the raster header, -1 is returned. No diagnostic is printed. Otherwise, 1 is returned to indicate success.

Note. Programmers should have no reason to use this routine. It is used by G_close_cell to giv e new raster files correct header files, and by the r.support module to give users a means of creating or modifying raster headers.

int G_is_reclass(char *name, char *mapset, char r_name, char r_mapset) reclass file?This function determines if the raster file name in mapset is a reclass file. If it is, then the name and mapset of the referenced raster file are copied into the r_name and r_mapset buffers.

Returns 1 if name is a reclass file, 0 if it is not, and -1 if there was a problem reading the raster header for name.

int G_is_reclassed_to(char *name, char *mapset, int *nrmaps, char ***rmaps) get child reclass maps listThis function generates a child reclass maps list from the cell_misc/reclassed_to file which stores this list. The cell_misc/reclassed_to file is written by G_put_reclass() .

G_is_reclassed_to() is used by g.rename, g.remove and r.reclass to prevent accidentally deleting the parent map of a reclassed raster map.

Raster Category File

GRASS map layers have category labels associated with them. The category file is structured so that each category in the raster file can have a one-line description. The format of this file is described in Raster_Category_File_Format.

The routines described below manage the category file. Some of them use the Categories structure which is described in GIS_Library_Data_Structures.

Reading and Writing the Raster Category File

The following routines read or write the category file itself:

int G_read_cats(char *name, char *mapset, struct Categories cats) read raster category fileThe category file for raster file name in mapset is read into the cats structure. If there is an error reading the category file, a diagnostic message is printed and -1 is returned. Otherwise, 0 is returned.

int G_write_cats(char *name, struct Categories *cats) write raster category fileWrites the category file for the raster file name in the current mapset from the cats structure.

Returns 1 if successful. Otherwise, -1 is returned (no diagnostic is printed) .

char * G_get_cell_title(char *name, char *mapset) get raster map titleIf only the map layer title is needed, it is not necessary to read the entire category file into memory. This routine gets the title for raster file name in mapset directly from the category file, and returns a pointer to the title. A legal pointer is always returned. If the map layer does not have a title, then a pointer to the empty string "" is returned.

char * G_put_cell_title(char *name, char *title) change raster map titleIf it is only desired to change the title for a map layer, it is not necessary to read the entire category file into memory, change the title, and rewrite the category file. This routine changes the title for the raster file name in the current mapset directly in the category file. It returns a pointer to the title.

Querying and Changing the Categories Structure

The following routines query or modify the information contained in the category structure:

char * G_get_cat(CELL n, struct Categories *cats) get a category labelThis routine looks up category n in the cats structure and returns a pointer to a string which is the label for the category. A legal pointer is always returned. If the category does not exist in cats, then a pointer to the empty string "" is returned.

Warning. The pointer that is returned points to a hidden static buffer. Successive calls to G_get_cat() overwrite this buffer.

char * G_get_cats_title (Categories *cats) get title from category structure structMap layers store a one-line title in the category structure as well. This routine returns a pointer to the title contained in the cats structure. A legal pointer is always returned. If the map layer does not have a title, then a pointer to the empty string "" is returned.

int G_init_cats(CELL n, char *title, struct Categories cats) initialize category structureTo construct a new category file, the structure must first be initialized. This routine initializes the cats structure, and copies the title into the structure. The number of categories is set initially to n.

For example:

struct Categories cats;

G_init_cats ((CELL) 0, '''', &cats) ;

int G_set_cat(CELL n, char *label, struct Categories *cats) set a category labelThe label is copied into the cats structure for category n.

int G_set_cats_title(char *title, struct Categories *cats) set title in category structureThe title is copied into the cats structure.

int G_free_cats(struct Categories *cats) free category structure memoryFrees memory allocated byG_read_cats, G_init_cats and G_set_cat.

Raster Color Table

GRASS map layers have colors associated with them. The color tables are structured so that each category in the raster file has its own color. The format of this file is described in Raster_Color_Table_Format.

The routines that manipulate the raster color file use the Colors structure which is described in detail in GIS_Library_Data_Structures.

Reading and Writing the Raster Color File

The following routines read, create, modify, and write color tables.

int G_read_colors(char *name, char *mapset, struct Colors colors) read map layer color tableThe color table for the raster file name in the specified mapset is read into the colors structure.

If the data layer has no color table, a default color table is generated and 0 is returned. If there is an error reading the color table, a diagnostic message is printed and -1 is returned. If the color table is read ok, 1 is returned.

int G_write_colors(char *name, char *mapset, struct Colors colors) write map layer color tableThe color table is written for the raster file name in the specified mapset from the colors structure.

If there is an error, -1 is returned. No diagnostic is printed. Otherwise, 1 is returned.

The colors structure must be created properly, i.e., G_init_colors to initialize the structure and G_add_color_rule to set the category colors. [footnote]

Note. The calling sequence for this function deserves special attention. The mapset parameter seems to imply that it is possible to overwrite the color table for a raster file which is in another mapset. However, this is not what actually happens. It is very useful for users to create their own color tables for raster files in other mapsets, but without overwriting other users' color tables for the same raster file. If mapset is the current mapset, then the color file for name will be overwritten by the new color table. But if mapset is not the current mapset, then the color table is actually written in the current mapset under the colr2 element as: colr2/mapset/name.

Lookup Up Raster Colors

These routines translates raster values to their respective colors.

int G_lookup_colors(CELL *raster, unsigned char *red, unsigned char green, unsigned char *blue, set, int n, struct Colors *colors) lookup an array of colorsExtracts colors for an array of raster values. The colors for the n values in the raster array are stored in the red, green, and blue arrays. The values in the set array will indicate if the corresponding raster value has a color or not (1 means it does, 0 means it does not) . The programmer must allocate the red, green, blue, and set arrays to be at least dimension n.

Note. The red, green, and blue intensities will be in the range 0 -­ 255.

int G_get_color(CELL cat, int *red, int *green, int *blue, struct Colors *colors) get a category colorThe red, green, and blue intensities for the color associated with category cat are extracted from the colors structure. The intensities will be in the range 0 ­- 255.

Creating and/or Modifying the Color Table

These routines allow the creation of customized color tables as well as the modification of existing tables.

int G_init_colors(struct Colors *colors) initialize color structureThe colors structure is initialized for subsequent calls to G_add_color_rule andG_set_color.

int G_add_color_rule(CELL cat1, int r1, int g1, int b1, CELL cat2, int r2, int g2, int b2, struct Colors *colors) set colorsThis is the heart and soul of the new color logic. It adds a color rule to the colors structure. The colors defined by the red, green, and blue values r1,g1,b1 and r2,g2,b2 are assigned to cat1 and cat2 respectively. Colors for data values between cat1 and cat2 are not stored in the structure but are interpolated when queried by G_lookup_colors and G_get_color. The color components r1,g1,b1 and r2,g2,b2 must be in the range 0 - 255.

For example, to create a linear grey scale for the range 200 - 1000:

struct Colors colr;

G_init_colors (&colr) ;

G_add_color_rule ((CELL) 200, 0,0,0,(CELL) 1000, 255,255,255) ;

The programmer is encouraged to review Raster_Color_Table_Format how this routine fits into the 5.x raster color logic.

Note. The colors structure must have been initialized by G_init_colors. See Predefined Color Tables for routines to build some predefined color tables.

int G_set_color(CELL cat, int red, int green, int blue, struct Colors *colors) set a category colorThe red, green, and blue intensities for the color associated with category cat are set in the colors structure. The intensities must be in the range 0 -­ 255. Values below zero are set as zero, values above 255 are set as 255.

Use of this routine is discouraged because it defeats the new color logic. It is provided only for backward compatibility. Overuse can create large color tables. G_add_color_rule should be used whenever possible.

Note. The colors structure must have been initialized by G_init_color.

int G_get_color_range(CELL *min, CELL *max, struct Colors colors) get color rangeGets the minimum and maximum raster values that have colors associated with them.

int G_free_colors(struct Colors *colors) free color structure memoryThe dynamically allocated memory associated with the colors structure is freed.

Note. This routine may be used after G_read_colors as well as after G_init_colors.

Predefined Color Tables

The following routines generate entire color tables. The tables are loaded into a colors structure based on a range of category values from min to max. The range of values for a raster map can be obtained, for example, using G_read_range. Note. The color tables are generated without information about any particular raster file.

These color tables may be created for a raster file, but they may also be generated for loading graphics colors.

These routines return -1 if min is greater than max, 1 otherwise.

int G_make_aspect_colors(struct Colors *colors, CELL min, CELL max) make aspect colorsGenerates a color table for aspect data.

int G_make_ramp_colors(struct Colors *colors, CELL min, CELL max) make color rampGenerates a color table with 3 sections: red only, green only, and blue only, each increasing from none to full intensity. This table is good for continuous data, such as elevation.

int G_make_wave_colors(struct Colors *colors, CELL min, CELL max) make color waveGenerates a color table with 3 sections: red only, green only, and blue only, each increasing from none to full intensity and back down to none. This table is good for continuous data like elevation.

int G_make_grey_scale_colors(struct Colors *colors, CELL min, CELL max) make linear grey scaleGenerates a grey scale color table. Each color is a level of grey, increasing from black to white.

int G_make_rainbow_colors(struct Colors *colors, CELL min, CELL max) make rainbow colorsGenerates a "shifted" rainbow color table - yellow to green to cyan to blue to magenta to red. The color table is based on rainbow colors. (Normal rainbow colors are red, orange, yellow, green, blue, indigo, and violet.) This table is good for continuous data, such as elevation.

int G_make_random_colors(struct Colors *colors, CELL min, CELL max) make random colorsGenerates random colors. Good as a first pass at a color table for nominal data.

int G_make_ryg_colors(struct Colors *colors, CELL min, CELL max) make red,yellow,green colorsGenerates a color table that goes from red to yellow to green.

int G_make_gyr_colors(struct Colors *colors, CELL min, CELL max) make green,yellow,red colorsGenerates a color table that goes from green to yellow to red.

int G_make_histogram_eq_colors(struct Colors *colors, struct Cell_stats *s) make histogram-stretched grey colorsGenerates a histogram contrast-stretched grey scale color table that goes from the ,histogram information in the Cell_stats structure s. (See Raster_Histograms) .

Raster History File

The history file contains documentary information about the raster file: who created it, when it was created, what was the original data source, what information is contained in the raster file, etc. This file is discussed in Raster_History_File_Format

The following routines manage this file. They use the History structure which is described in GIS_Library_Data_Structures.

Note. This structure has existed relatively unmodified since the inception of GRASS. It is in need of overhaul. Programmers should be aware that future versions of GRASS may no longer support either the routines or the data structure which support the history file.

int G_read_history(char *name, char *mapset, struct History history) read raster history fileThis routine reads the history file for the raster file name in mapset into the history structure.

A diagnostic message is printed and -1 is returned if there is an error reading the history file. Otherwise, 0 is returned.

int G_write_history(char *name, struct History *history) write raster history fileThis routine writes the history file for the raster file name in the current mapset from the history structure.

A diagnostic message is printed and -1 is returned if there is an error writing the history file. Otherwise, 0 is returned.

Note. The history structure should first be initialized using G_short_history.

int G_short_history(char *name, char *type, struct History history) initialize history structureThis routine initializes the history structure, recording the date, user, module name and the raster file name structure. The type is an anachronism from earlier versions of GRASS and should be specified as "raster".

Note. This routine only initializes the data structure. It does not write the history file.

Raster Range File

The following routines manage the raster range file. This file contains the minimum and maximum values found in the raster file. The format of this file is described in Raster_Range_File_Format.

The routines below use the Range data structure which is described in GIS_Library_Data_Structures.

int G_read_range(char *name, char *mapset, struct Range range) read raster rangeThis routine reads the range information for the raster file name in mapset into the range structure.

A diagnostic message is printed and -1 is returned if there is an error reading the range file. Otherwise, 0 is returned.

int G_write_range(char *name, struct Range *range) write raster range fileThis routine writes the range information for the raster file name in the current mapset from the range structure.

A diagnostic message is printed and -1 is returned if there is an error writing the range file. Otherwise, 0 is returned.

The range structure must be initialized and updated using the following routines:

int G_init_range(struct Range *range) initialize range structureInitializes the range structure for updates by G_update_range and G_row_update_range.

int G_update_range(CELL cat, struct Range *range) update range structureCompares the cat value with the minimum and maximum values in the range structure, modifying the range if cat extends the range.

int G_row_update_range(CELL *cell, int n, struct Range range) update range structureThis routine updates the range data just like G_update_range, but for n values from the cell array.

The range structure is queried using the following routine:

int G_get_range_min_max(struct Range *range, CELL *min, CELL max) get range min and maxThe mininum and maximum CELL values are extracted from the range structure.

Raster Histograms

The following routines provide a relatively efficient mechanism for computing and querying a histogram of raster data. They use the Cell_stats structure to hold the histogram information. The histogram is a count associated with each unique raster value representing the number of times each value was inserted into the structure.

These next two routines are used to manage the Cell_stats structure:

int G_init_cell_stats(struct Cell_stats *s) initialize cell statsThis routine, which must be called first, initializes the Cell_stats structure s.

int G_free_cell_stats(struct Cell_stats *s) free cell statsThe memory associated with structure s is freed. This routine may be called any time after callingG_init_cell_stats.

This next routine stores values in the histogram:

int G_update_cell_stats(CELL *data, int n, struct Cell_stats s) add data to cell statsThe n CELL values in the data array are inserted (and counted) in the Cell_stats structure s.

Once all values are stored, the structure may be queried either randomly (ie. search for a specific raster value) or sequentially (retrieve all raster values, in ascending order, and their related count) :

int G_find_cell_stat(CELL cat, long *count, struct Cell_stats s) random query of cell statsThis routine allows a random query of the Cell_stats structure s. The count associated with the raster value cat is set. The routine returns 1 if cat was found in the structure, 0 otherwise.

Sequential retrieval is accomplished using these next 2 routines:

int G_rewind_cell_stats(struct Cell_stats *s) reset/rewind cell statsThe structure s is rewound (i.e., positioned at the first raster category) so that sorted sequential retrieval can begin.

int G_next_cell_stat(CELL *cat, long *count, struct Cell_stats s) retrieve sorted cell stats Retrieves the next cat,count combination from the structure s. Returns 0 if there are no more items, non-zero if there are more.

For example:

struct Cell_stats s;
CELL cat;
long count;

.
. /* updating s occurs here */
.

G_rewind_cell_stats(&s);

while (G_next_cell_stat(&cat,&count,&s)
  fprintf(stdout, "%ld %ld\n", (long) cat, count);

GRASS 5 raster API [needs to be merged

into above sections]

The CELL Data Type

GRASS integer raster map data is defined to be of type CELL. This data type is defined in the "gis.h" header file. Programmers must declare all variables and buffers which will hold raster data or category codes as type CELL. Under GRASS the CELL data type is declared to be int, but the programmer should not assume this. What should be assumed is that CELL is a signed integer type. It may be changed sometime to short or long. This implies that use of CELL data with routines which do not know about this data type (e.g., fprintf(stdout, ...), sscanf(), etc.) must use an intermediate variable of type long. To print a CELL value, it must be cast to long. For example:

CELL c; /* raster value to be printed */

/* some code to get a value for c */
fprintf(stdout, "%ld\n", (long) c); /* cast c to long to print */

To read a CELL value, for example from user typed input, it is necessary to read into a long variable, and then assign it to the CELL variable. For example (this example does not check for valid inputs, EOF, etc., which good code must do):

char userbuf[128];
CELL c; long x;

fprintf (stdout, "Which category? "); /* prompt user */
gets(userbuf); /* get user response * /
sscanf (userbuf,"%ld", &x); /* scan category into long variable */
c = (CELL) x; /* assign long value to CELL value */

Of course, with GRASS library routines that are designed to handle the CELL type, this problem does not arise. It is only when CELL data must be used in routines which do not know about the CELL type, that the values must be cast to or from long.

The "gis.h" contains 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" contains 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. It was 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.

NULL-value functions

int G_set_null_value(void *rast, int count, RASTER_MAP_TYPE data_type) Set NULL valueIf 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) ;

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

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

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

int G_insert_null_values(void *rast, char *flags, int count, RASTER_MAP_TYPE data_type) Insert NULL valueIf 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) ;

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

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

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

int 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) ;

int 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.

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) ;

int 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.

int 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.

Floating-point and type-independent functions

int G_maskfd(void) test for current maskreturns file descriptor number if MASK is in use and -1 if no MASK is in use.

int 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.

int 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) .

int 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) .

int 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.

int 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,q 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 values q into p. If q is null value, sets q to null value.

int 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.

int 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.

int 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.

int 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) ;

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

int 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) .

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

int 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.

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

int 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.

int G_get_c_raster_row_nomask (int fd, CELL buf, int row) Same as G_get_c_raster_row() except no masking occurs.

int 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) ;

int 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.

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

int 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.)

int 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.

double G_get_raster_sample(int, struct Cell_head *, struct Categories *, double, double, int, INTERP_TYPE) extracts a cell value from raster map at given position with INTERP_TYPE 0:UNKNOWN; 1: nearest neighbor interpolation; 2: bilinear interpolation; 3: cubic interpolation.

Upgrades to Raster Functions (comparing to GRASS 4.x)

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

Changes to GISLIB:

int 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.

int 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/she should call G_set_quant_rules() after the call to G_open_cell_old() .

int 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!!

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

This routine is deprecated!!

Changes to D_LIB:

int 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().

NULL (no data) handling

The null file is stored in cell_misc/name/null file.

-2^31 (= 0x80000000 = -2147483648) is the null value for the CELL type, so you'll never see that value in a map.

The FP nulls are the all-ones bit patterns. These corresponds to NaN according to the IEEE-754 formats, although it isn't the "default" NaN pattern generated by most architectures (which is usually 7fc00000 or ffc00000 for float and 7ff8000000000000 or fff8000000000000 for double, i.e. an all-ones exponent, the top-bit of the mantissa set, and either sign).

So far as arithmetic is concerned, any value with an all-ones exponent and a non-zero mantissa is treated as NaN. But the GRASS G_is_[fd]_null_value() functions only consider the all-ones bit pattern to be null. I intend to change this in 7.x so that all FP NaN values are treated as null. This will mean that code which can generate NaNs doesn't have to explicitly convert them to the GRASS null value.

Presence or absence of null file: For an integer map, any cells which were null will become zero, but any zeroes (cells which were previously either null or zero) will be treated as nulls (this is for compatibility with GRASS 4.x, which didn't have a null file, but typically used zero to indicate a null value).

For a floating-point map, any cells which were null will become zero (when writing FP data, a null has a zero written to the fcell/<map> file, and the corresponding bit is set in the null file).

Color Functions (new and upgraded)

Upgraded Colors structures

struct _Color_Rule_

{

struct

{
    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;
};

New functions to support colors for floating-point

Changes to GISLIB:

int G_lookup_raster_colors(void *rast, char *r, char *g, char *b, char *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) ;

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

int G_lookup_f_raster_colors(FCELL *fcell, char *r, char *g, char b, char *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.

int G_lookup_d_raster_colors(DCELL *dcell, char *r, char *g, char b, char *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.

int G_add_raster_color_rule(void *v1, int r1, int g1, int b1, void *v2, int r2, int g2, int 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) ;

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

int G_add_f_raster_color_rule(FCELL *v1, int r1, int g1, int b1, FCELL *v2, int r2, int g2, int 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)

int G_add_d_raster_color_rule(DCELL *v1, int r1, int g1, int b1, DCELL *v2, int r2, int g2, int 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)

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

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

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

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

int G_set_raster_color(void *v, int r, int g, int 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) ;

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

int G_set_f_raster_color(FCELL *v, int r, int g, int 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) ;

int G_set_d_raster_color(DCELL *v, int r, int g, int 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) ;

int 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&#94;3 and max=255&#94;3.


These routines are in the DISPLAYLIB:

int D_raster_of_type(void *rast, int ncols, int 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) ;

int D_f_raster(FCELL *fcell, int ncols, int 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.

int D_d_raster(DCELL *dcell, int ncols, int 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.

int D_color_of_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) ;

int D_f_color(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.

int D_d_color(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.

int D_lookup_raster_colors(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) ;

int D_lookup_c_raster_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) .

int D_lookup_f_raster_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) .

int D_lookup_d_raster_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) .

int D_draw_cell_of_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) ;

int D_draw_f_cell (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().

int D_draw_d_cell (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().

New functions to support a color for the NULL-value

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

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

New functions to support a default color

int G_set_default_color (int r, int g, int 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.

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

New functions to support treating a raster layer as a color image

int G_get_raster_row_colors(int fd, int row, struct Colors *colors, unsigned char *red, unsigned char *grn, unsigned char *blu, unsigned char *nul) Reads a row of raster data and converts it to red, green and blue components according to the colors parameter.

This provides a convenient way to treat a raster layer as a color image without having to explicitly cater for each of CELL, FCELL and DCELL types

Upgraded color functions

int 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().

int 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.

int G_get_colors_min_max() If the color table is marked as "float", then return the minimum as -(255&#94;3 * 128) and the maximum as (255&#94;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.

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

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

Changes to the <TT>Colors</TT> 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.

Changes to the <TT>colr</TT> 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
    

Range functions (new and upgraded)

Modified range functions

int 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().

int 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.

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

int 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.

int 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.

New range functions

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

int G_read_raster_range(void *r, char *name, char *mapset, RASTER_MAP_TYPEmap_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) ;

int 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().

int 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) ;

int 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.

int 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.

int 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.

int 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.

int 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.

New and Upgraded Cell_stats functions

Modified Cell_stats functions to handle NULL-values:

int G_init_cell_stats() Set the count for NULL-values to zero.

int G_update_cell_stats() Look for NULLs and update the NULL-value count.

int G_next_cell_stat() Do not return a record for the NULL-value

int G_find_cell_stat() Allow finding the count for the NULL-value

int 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.

New Quantization Functions

New functions to support quantization of floating-point to integer:

int 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&#64;mapset being read using quant rules stored in q from G_mapset() . See G_read_quant() for detailes.

int 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.

int 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.

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

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

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

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

int 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.

int G_quant_add_rule(struct Quant *q, DCELL dmin, DCELL dmax, CELL cmin, CELL 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.

int G_quant_set_positive_infinite_rule(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().

int G_quant_get_positive_infinite_rule(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.

int G_quant_set_negative_infinite_rule(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().

int G_quant_get_negative_infinite_rule(struct Quant *q, DCELL dmin, 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.

int G_quant_get_limits(struct Quant *q, DCELL *dmin, DCELL *dmax, CELL *cmin, CELL *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.

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

int G_quant_get_rule(struct Quant *q, int n, DCELL *dmin, DCELL dmax, CELL *cmin, CELL *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()

int G_quant_perform_d(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.

int G_quant_perform_f(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:

int 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].

int G_quantize_fp_map_range(char *name, DCELL dmin, DCELL dmax, 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 [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].

Categories Labeling Functions (new and upgraded)

Upgraded Categories structure

All the new programs which are using Categories structure directly have to be modified to use API functions to update and retrieve 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 modules 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  ;
} ;

Changes to the <TT>cats</TT> 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.

Range functions (new and upgraded)

New Functions to read/write access and modify Categories structure

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

int 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(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(CELL *val, struct Categories *pcats) given a CELL value val Returns pointer to a string describing category.

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

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

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

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

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

int G_set_d_raster_cat(DCELL *rast1, DCELL *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(struct Categories *pcats, int i, void rast1, void *rast2, 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(struct Categories *pcats, int i, CELL *rast1, CELL *rast2) 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(struct Categories *pcats, int i, FCELL *rast1, FCELL *rast2) 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(struct Categories *pcats, int i, DCELL *rast1, DCELL *rast2) 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.

int 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.

int G_get_next_marked_raster_cat(struct Categories *pcats, void rast1, void *rast2, 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 () .

int G_get_next_marked_c_raster_cat(struct Categories *pcats, CELL rast1, CELL *rast2, 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 () .

int G_get_next_marked_f_raster_cat(struct Categories *pcats, FCELL *rast1, FCELL *rast2, 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 () .

int G_get_next_marked_d_raster_cat(struct Categories *pcats, DCELL *rast1, DCELL *rast2, 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 () .

int G_mark_raster_cats(void *rast_row, int ncols, struct Categories *pcats, RASTER_MAP_TYPE data_type) Looks up the category label for each raster value in the rast_row (row of raster cell value) 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.

int G_mark_c_raster_cats(CELL *rast_row, int ncols, struct Categories *pcats) 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.

int G_mark_f_raster_cats(FCELL *rast_row, int ncols, struct Categories *pcats) 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.

int G_mark_d_raster_cats(DCELL *rast_row, int ncols, struct Categories *pcats) 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.

int G_rewind_raster_cats(struct Categories *pcats) after call to this function G_get_next_marked_raster_cat() returns the first marked cat label.

int 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.

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

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

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

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

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.

Guidelines for upgrading GRASS 4.x Modules

  • Modules that process raster maps as continuous data should read raster maps as floating-point. Modules that process raster maps as nominal data should read raster maps as integer.

    Exception: Modules that process raster colors or the modules which report on raster categories labels should either always read the maps as floating-point, or read the maps as integer if the map is integer and floating-point if the map is floating-point.

  • The quantization of floating-point to integer should NOT change the color table. The color lookup should have its own separate quantization.
  • The quantization of floating-point to integer should NOT change the Categories table. The Categories structure should have its own separate quantization.
  • Modules that read or write floating-point raster maps should use double (DCELL) arrays instead of float (FCELL) arrays.
  • Modues should process NULL values in a well defined (consistent) manner. Modules that processed zero as the pseudo NULL-value should be changed to use the true NULL-value for this and process zero as normal value.
  • Modules should process non-NULL values as normal numbers and not treat any particular numbers (e.g. zero) as special.

Important hints for upgrades to raster modules

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

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