This chapter is divided in the following pages:
The GIS Library is the primary programming library provided with the GRASS system. Programs must use this libary to access the database. It contains the routines which locate, create, open, rename, and remove GRASS database files. It contains the routines which read and write raster files. It contains routines which interface the user to the database, including prompting the user, listing available files, validating user access, etc. It also has some general purpose routines (string manipulation, user information, etc.) which are not tied directly to database processing.
It is assumed that the reader has read Database_Structure for a general description of GRASS databases, Raster_Maps for details about raster map layers in GRASS, and Region_and_Mask which discusses regions and masks. The routines in the GIS Library are presented in functional groupings, rather than in alphabetical order. The order of presentation will, it is hoped, provide a better understanding of how the library is to be used, as well as show the interrelationships among the various routines. Note that a good way to understand how to use these routines is to look at the source code for GRASS modules which use them. Most routines in this library require that the header file "gis.h" be included in any code using these routines. Therefore, programmers should always include this file when writing code using routines from this library:
#include "gis.h"
Note. All routines and global variables in this library, documented or undocumented, start with the prefix G_. To avoid name conflicts, programmers should not create variables or routines in their own modules which use this prefix.
int G_gisinit(char *program_name) initialize gis library
This routine reads the user's GRASS environment file into memory and makes sure that the user has selected a valid database and mapset. It also initializes hidden variables used by other routines. If the user's database information is invalid, an error message is printed and the module exits. The program_name is stored for later recall by G_program_name. It is recommended that argv[0] be used for the program_name:
int main (int argc, char **argv) { G_gisinit(argv[0]); }
int G_fatal_error(char *message, ...) print error message and exit
int G_debug(level, char *message, ...) print debug message
int G_warning(char *message, ...) print warning message and continue
These routines report errors to the user. The normal mode is to write the message to the screen (on the standard error output) and wait a few seconds. G_warning() will return and G_fatal_error() will exit.
If the standard error output is not a tty device, then the message is mailed to the user instead.
If the file GIS_ERROR_LOG exists (with write permission), in either the user's home directory or in the $GISBASE directory, the messages will also be logged to this file.
While most applications will find the normal error reporting quite adequate, there will be times when different handling is needed. For example, graphics modules may want the messages displayed graphically instead of on the standard error output. If the programmer wants to handle the error messages differently, the following routines can be used to modify the error handling:
int G_set_error_routine(int (*handler)()) change error handling
This routine provides a different error handler for G_fatal_error() and G_warning(). The handler routine must be defined as follows:
int handler (char *message, int fatal)
where message is the message to be handled and fatal indicates the type of error: 1 (fatal error) or 0 (warning).
Note. The handler only provides a way to send the message somewhere other than to the error output. If the error is fatal, the module will exit after the handler returns.
int G_unset_error_routine() reset normal error handling
This routine resets the error handling for G_fatal_error() and G_warning() back to the default action.
int G_sleep_on_error(int flag) sleep on error?
If flag is 0, then no pause will occur after printing an error or warning message. Otherwise the pause will occur.
int G_suppress_warnings(int flag) suppress warnings?
If flag is 0, then G_warning() will no longer print warning messages. If flag is 1, then G_warning() will print warning messages.
Note. This routine has no effect on G_fatal_error().
The following four routines can be used freely by the programmer:
char * G_location() current location name
Returns the name of the current database location. This routine should be used by modules that need to display the current location to the user. See Locations for an explanation of locations.
char * G_mapset() current mapset name
Returns the name of the current mapset in the current location. This routine is often used when accessing files in the current mapset. See Mapsets for an explanation of mapsets.
char * G_myname() location title
Returns a one line title for the database location. This title is read from the file MYNAME in the PERMANENT mapset. See also Permanent_Mapset for a discussion of the PERMANENT mapset.
char * G_gisbase() top level module directory
Returns the full path name of the top level directory for GRASS programs. This directory will have subdirectories which will contain modules and files required for the running of the system. Some of these directories are:
bin commands run by the user etc modules and data files used by GRASS commands html help files
The use of G_gisbase() to find these subdirectories enables GRASS modules to be written independently of where the GRASS system is actually installed on the machine. For example, to run the module sroff in the GRASS etc directory:
char command[200]; sprintf (command, "%s/etc/sroff", G_gisbase() ); system (command);
The following two routines return full path UNIX directory names. They should be used only in special cases. They are used by other routines in the library to build full UNIX file names for database files. The programmer should not use the next two routines to bypass the normal database access routines.
char * G_gisdbase() top level database directory
Returns the full UNIX path name of the directory which holds the database locations. See GISDBASE for a full explanation of this directory.
char * G_location_path() current location directory
Returns the full UNIX path name of the current database location. For example, if the user is working in location spearfish in the /home/user/grassdata database directory, this routine will return a string which looks like
/home/user/grassdata/spearfish.
These next routines provide the low-level management of the information in the user's GRASS environment file. They should not be used in place of the higher level interface routines described above.
int G_getenv(char *name) query GRASS environment variable
int G__getenv(char *name) query GRASS environment variable
These routines look up the variable name in the GRASS environment and return its value (which is a character string). If name is not set, G_getenv() issues an error message and calls exit(). G__setenv() just returns the NULL pointer.
int G_setenv (char *name, char *value) set GRASS environment variable
int G__setenv(char *name, char *value) set GRASS environment variable
These routines set the the GRASS environment variable name to value. If value is NULL, the name is unset.
Both routines set the value in module memory, but only G_setenv() writes the new value to the user's GRASS environment file.
In the descriptions below, the term database element is used. Elements are subdirectories within a mapset and are associated with a specific GRASS data type. For example, raster files live in the "cell" and "fcell" element. See Elements for more details.
The short (one or two word) label describing the element is used as part of a title when listing the files in element.
The user is required to enter a valid 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 file lives or is to be created is returned. Both the name and the mapset are used in other routines to refer to the file.
An example will be given here. The G_ask_old() routine used in the example is described a bit later. The user is asked to enter a file from the "paint/labels" element:
char name[GNAME_MAX]; char *mapset; mapset = G_ask_old("", name, "paint/labels", "labels"); if (mapset = = NULL) exit(EXIT_SUCCESS); /* user canceled the request */
The user will see the following:
Enter the name of an existing labels file Enter 'list' for a list of existing labels files Hit RETURN to cancel request
The last line of the prompt can be modified using G_set_ask_return_msg().
char * G_ask_old(char *prompt, char *name, char *element, char *label) prompt for existing database file
The user is asked to enter the name of an existing database file.
Note. This routine looks for the file in the current mapset as well as other mapsets. The mapsets that are searched are determined from the user's mapset search path. See Mapset_Search_Path for some more details about the search path.
char * G_ask_new(char *prompt, char *name, char *element, char label) prompt for new database file The user is asked to enter the name of a new file which does not exist in the current mapset.
Note. The file chosen by the user may exist in other mapsets. This routine does not look in other mapsets, since the assumption is that name will be used to create a new file. New files are always created in the current mapset.
char * G_ask_in_mapset(char *prompt, char *name, char *element, char label) prompt for existing database file
The user is asked to enter the name of an file which exists in the current mapset.
Note. The file chosen by the user may or may not exist in other mapsets. This routine does not look in other mapsets, since the assumption is that name will be used to modify a file. GRASS only permits users to modify files in the current mapset.
char * G_ask_any(char *prompt, char *name, char *element, char label, int warn) prompt for any valid file name
The user is asked to enter any legal file name. If warn is 1 and the file chosen exists in the current mapset, then the user is asked if it is ok to overwrite the file. If warn is 0, then any leg al name is accepted and no warning is issued to the user if the file exists.
int G_set_ask_return_msg(char *msg) set Hit RETURN msg
The "Hit RETURN to cancel request" part of the prompt in the prompting routines described above, is modified to "Hit RETURN <B>msg.</B>"
char * G_get_ask_return_msg() get Hit RETURN msg
The current msg (as set by G_set_ask_return_msg()) is returned.
char * G_fully_qualified_name(char *name, char *mapset) fully qualified file name
Returns a fully qualified name for the file name in mapset. Currently this string is in the form name, but the programmer should pretend not to know this and always call this routine to get the fully qualified name.
The following example shows how an interactive version of d.rast interfaces with the command-line version of d.rast:
#include "gis.h" int main(char *argc, char **argv) { char name[GNAME_MAX], *mapset, *fqn; char command[1024]; G_gisinit(argv[0]); mapset = G_ask_cell_old("", name, ""); if (mapset == NULL) exit(EXIT_SUCCESS); fqn = G_fully_qualified_name(name, mapset); sprintf(command, "d.rast map='%s'", fqn); system(command); }
The following routines search the database for files:
char * G_find_file(char *element, char *name, char *mapset) find a database file
Look for the file name under the specified element 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, which means . look for the file only in this one mapset (for example, in the current mapset).
If found, the mapset where the file lives is returned. If not found, the NULL pointer is returned.
If the user specifies a fully qualified file name, (i.e, a name that also contains the mapset; see Fully Qualified File Names) then G_find_file() modifies name by eliminating the mapset from the name
For example, to find a "paint/labels" file anywhere in the database:
char name[GNAME_MAX]; char *mapset; if ((mapset = G_find_file("paint/labels",name,"")) == NULL) /* not found */
To check that the file exists in the current mapset:
char name[GNAME_MAX]; if (G_find_file("paint/labels",name,G_mapset()) == NULL) /* not found */
int G_legal_filename(char *name) check for legal database file names
Returns 1 if name is ok, -1 otherwise.
int G_open_old(char *element, char *name, char *mapset) open a database file for reading
The database file name under the element in the specified mapset is opened for reading (but not for writing).
The UNIX open() routine is used to open the file. If the file does not exist, -1 is returned. Otherwise the file descriptor from the open() is returned.
FILE * G_fopen_old(char *element, char *name, char *mapset) open a database file for reading
The database file name under the element in the specified mapset is opened for reading (but not for writing).
The UNIX fopen() routine, with "r" read mode, is used to open the file. If the file does not exist, the NULL pointer is returned. Otherwise the file descriptor from the fopen() is returned.
int G_open_update(char *element, char *name) open a database file for update
The database file name under the element in the current mapset is opened for reading and writing.
The UNIX open() routine is used to open the file. If the file does not exist, -1 is returned. Otherwise the file is positioned at the end of the file and the file descriptor from the open() is returned.
int G_fopen_append(char *element, char *name) open a database file for update
The database file name under the element in the current mapset is opened for appending (but not for reading).
The UNIX fopen() routine, with "a" append mode, is used to open the file. If the file does not exist, the NULL pointer is returned. Otherwise the file is positioned at the end of the file and the file descriptor from the fopen() is returned.
The file name should be obtained interactively using G_ask_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. Warning. It is not an error for name to already exist. However, the file will be removed and recreated empty. The interactive routine G_ask_new() guarantees that name will not exist, but if name is obtained from the command line, name may exist. In this case G_find_file() could be used to see if name exists.
int G_open_new(char *element, char *name) open a new database file
The database file name under the element in the current mapset is created and opened for writing (but not reading).
The UNIX open() routine is used to open the file. If the file does not exist, -1 is returned. Otherwise the file is positioned at the end of the file and the file descriptor from the open() is returned.
FILE * G_fopen_new(char *element, char *name) open a new database file
The database file name under the element in the current mapset is created and opened for writing (but not reading).
The UNIX fopen() routine, with "w" write mode, is used to open the file. If the file does not exist, the NULL pointer is returned. Otherwise the file is positioned at the end of the file and the file descriptor from the fopen() is returned.
int G_rename(char *element, char *old, char *new) rename a database file
The file or directory old under the database element directory in the current mapset is renamed to new.
Returns 1 if successful, 0 if old does not exist, and -1 if there was an error.
Bug. This routine does not check to see if the new name is a valid database file name.
int G_remove(char *element, char *name) remove a database file
The file or directory name under the database element directory in the current mapset is removed.
Returns 1 if successful, 0 if name does not exist, and -1 if there was an error.
Note. If name is a directory, everything within the directory is removed as well.
Note. These functions only apply to the specific element and not to other "related" elements. For example, if element is "cell", then the specified raster file will be removed (or renamed), but the other support files, such as "cellhd" or "cats", will not. To remove these other files as well, specific calls must be made for each related element.
Note. Use the G_free() routine to release memory allocated by these routines.
int G_free(void *buf) free the memory allocated
Free the memory allocated by the GRASS malloc routines.
void * G_malloc (int size) memory allocation
Allocates a block of memory at least size bytes which is aligned properly for all data types. A pointer to the aligned block is returned.
void * G_realloc(void *ptr, int size) memory allocation
Changes the size of a previously allocated block of memory at ptr and returns a pointer to the new block of memory. The size may be larger or smaller than the original size. If the original block cannot be extended "in place", then a new block is allocated and the original block copied to the new block.
Note. If ptr is NULL, then this routine simply allocates a block of size bytes. This routine works around broken realloc() routines, which do not handle a NULL ptr.
void * G_calloc(int n, int size) memory allocation
Allocates a properly aligned block of memory n*size bytes in length, initializes the allocated memory to zero, and returns a pointer to the allocated block of memory.
Note. Allocating memory for reading and writing raster files is discussed in Allocating_Raster_I_O_Buffers.
double * G_alloc_vector(int n) memory allocation
Allocate a vector (array) of n doubles initialized to zero.
float * G_alloc_fvector(int n) memory allocation
Allocate a vector (array) of n floats initialized to zero.
double ** G_alloc_matrix(int rows, int cols) memory allocation
Allocate a matrix of rows by cols doubles initialized to zero.
float ** G_alloc_fmatrix(int rows, int cols) memory allocation
Allocate a matrix of rows by cols floats initialized to zero.
int G_free_vector(double *v) memory deallocation
Deallocate a vector (array) of doubles or floats.
int G_free_matrix(double **m) memory deallocation
Deallocate a matrix of doubles.
int G_free_fmatrix(float **m) memory deallocation
Deallocate a matrix of floats.
There are logically two different regions. The first is the database region that the user has set in the current mapset. The other is the region that is active in the module. This active module region is what controls reading and writing of raster file data. The vector map export does not take care for the active region settings.
The routines described below use a GRASS data structure Cell_head to hold region information. This structure is defined in the "gis.h" header file. It is discussed in detail under GIS_Library_Data_Structures .
[Note: Previous versions of GRASS called this the "window". Due to overuse of this term (database window, graphics window, etc.), the term was changed to "region". However, to maintain compatibility with existing programs, library routine names were not changed - hence the term "window" is used in the routine name (where "region" should probably be used instead.)]
int G_get_window(struct Cell_head *region) read the database region
Reads the database region as stored in the WIND file in the user's current mapset into region.
An error message is printed and exit() is called if there is a problem reading the region.
Note. GRASS applications that read or write raster files should not use this routine since its use implies that the active module region will not be used. Programs that read or write raster file data (or vector data) can query the active module region using G_window_rows() and G_window_cols().
int G_put_window(struct Cell_head *region) write the database region Writes the database region file (WIND) in the user's current mapset from region. Returns 1 if the region is written ok. Returns -1 if not (no diagnostic message is printed).
Warning. Since this routine actually changes the database region, it should only be called by modules which the user knows will change the region. It is probably fair to say that under GRASS 3.0 only the g.region, and d.zoom modules should call this routine.
There is another database region. This region is the default region for the location. The default region provides the user with a "starting" region, i.e., a region to begin with and return to as a reference point. The GRASS modules g.region allow the user to set their database region from the default region. (See Permanent_Mapset for a discussion of the default region.) The following routine reads this region:
int G_get_default_window(struct Cell_head *region) read the default region
Reads the default region for the location into region.
An error message is printed and exit() is called if there is a problem reading the default region.
Initially the active module region and the user's database region are the same, but the programmer can make them different. The following routines manage the active module region.
int G_window_rows() number of rows in active region
int G_window_cols() number of columns in active region
These routines return the number of rows and columns (respectively) in the active module region. Before raster files can be read or written, it is necessary to known how many rows and columns are in the active region. For example:
int nrows, cols; int row, col; nrows = G_window_rows(); ncols = G_window_cols(); for (row = 0; row < nrows; row++){ read row ... for (col = 0; col < ncols; col++){ process col ... } }
int G_set_window(struct Cell_head *region) set the active region
This routine sets the active region from region. Setting the active region does not change the WIND file in the database. It simply changes the region for the duration of the module.
However, the new region setting is not retained across the UNIX exec() call. This implies that G_set_window() cannot be used to set the region for a module to be executed using the system() or popen() routines.
A warning message is printed and -1 returned if region is not valid. Otherwise 1 is returned.
Note. This routine overrides the region as set by the user. Its use should be very limited since it changes what the user normally expects to happen. If this routine is not called, then the active region will be the same as what is in the user's WIND file.
Warning. Calling this routine with already opened raster files has some side effects. If there are raster files which are open for reading, they will be read into the newly set region, not the region that was active when they were opened. However, CELL buffers allocated for reading the raster files are not automatically reallocated. The module must reallocate them explicitly. Also, this routine does not change the region for raster files which are open for writing. The region that was active when the open occurred still applies to these files.
int G_get_set_window(struct Cell_head *region) get the active region
Gets the values of the currently active region into region. If G_set_window() has been called, then the values set by that call are retrieved. Otherwise the user's database region is retrieved.
Note. For modules that read or write raster data, and really need the full region information, this routine is preferred over G_get_window(). However, since G_window_rows() and G_window_cols() return the number of rows and columns in the active region, the programmer should consider whether or not the full region information is really needed before using this routine.
char * G_align_window(struct Cell_head *region, struct Cell_head *ref) align two regions
Modifies the input region to align to the ref region. The resolutions in region are set to match those in ref and the region edges (north, south, east, west) are modified to align with the grid of the ref region.
The region may be enlarged if necessary to achieve the alignment. The north is rounded northward, the south southward, the east eastward and the west westward.
This routine returns NULL if ok, otherwise it returns an error message.
double G_col_to_easting(double col, struct Cell_head *region) column to easting
Converts a column relative to a region to an easting;
Note. col is a double: col+0.5 will return the easting for the center of the column; col+0.0 will return the easting for the western edge of the column; and col+1.0 will return the easting for the eastern edge of the column.
double G_row_to_northing(double row, struct Cell_head *region) row to northing
Converts a row relative to a region to a northing;
Note. row is a double: row+0.5 will return the northing for the center of the row; row+0.0 will return the northing for the northern edge of the row; and row+1.0 will return the northing for the southern edge of the row.
double G_easting_to_col(double east, struct Cell_head *region) easting to column
Converts an easting relative to a region to a column.
Note. The result is a double. Casting it to an integer will give the column number.
double G_northing_to_row(double north, struct Cell_head *region) northing to row
Converts a northing relative to a region to a row.
Note. the result is a double. Casting it to an integer will give the row number.
int G_projection() query cartographic projection
This routine returns a code indicating the projection for the active region. The current values are:
0 unreferenced x,y (imagery data)
1 UTM
2 State Plane
3 Latitude-Longitude
99 Other (more than 121 projections are supported)
char * G_database_projection_name(int proj) query cartographic projection
Returns a pointer to a string which is a printable name for projection code proj (as returned by G_projection()). Returns NULL if proj is not a valid projection.
char * G_database_unit_name(int plural) database units
Returns a string describing the database grid units. It returns a plural form (eg. feet) if plural is true. Otherwise it returns a singular form (eg. foot).
double G_database_units_to_meters_factor() conversion to meters
Returns a factor which converts the grid unit to meters (by multiplication). If the database is not metric (eg. imagery) then 0.0 is returned.
int G_zone() query cartographic zone
This routine returns the zone for the active region. The meaning for the zone depends on the projection. For example zone 18 for projection type 1 would be UTM zone 18.
Also, since the world is round, maps may not have edges in the east-west direction, especially for global databases. Maps may have the same longitude at both the east and west edges of the display. This feature, called global wraparound, must be accounted for by GRASS modules (particularly vector based functions, like plotting.) What follows is a description of the GISLIB library routines that are available to support latitude-longitude databases.
Coordinates are represented in ASCII using the format dd:mm:ssN or dd:mm:ssS for latitudes, ddd:mm:ssE or ddd.mm.ssW for longitudes, and dd.mm.ss for grid resolution. For example, 80:30:24N represents a northern latitude of 80 degrees, 30 minutes, and 24 seconds. 120:15W represents a longitude 120 degrees and 15 minutes west of the prime meridian. 30:15 represents a resolution of 30 degrees and 15 minutes. These next routines convert between ASCII representations and the machine representation for a coordinate. They work both with latitude-longitude projections and planimetric projections.
Note. In each subroutine, the programmer must specify the projection number. If the projection number is PROJECTION_LL (defined in "gis.h"), then latitude-longitude ASCII format is invoked. Otherwise, a standard floating-point to ASCII conversion is made.
int G_format_easting(double east, char *buf, int projection) easting to ASCII
Converts the double representation of the east coordinate to its ASCII representation (into buf).
int G_format_northing(double north, char *buf, int projection) northing to ASCII
Converts the double representation of the north coordinate to its ASCII representation (into buf).
int G_format_resolution(double resolution, char *buf, int projection) resolution to ASCII
Converts the double representation of the resolution to its ASCII representation (into buf).
int G_scan_easting(char *buf, double *easting, int projection) ASCII easting to double
Converts the ASCII "easting" coordinate string in buf to its double representation (into easting).
int G_scan_northing(char *buf, double *northing, int projection) ASCII northing to double
Converts the ASCII "northing" coordinate string in buf to its double representation (into northing).
int G_scan_resolution(char *buf, double *resolution, int projection) ASCII resolution to double
Converts the ASCII "resolution" string in buf to its double representation (into resolution).
The following are examples of how these routines are used.
double north; char buf[50]; G_scan_northing(buf, north, G_projection()); /* ASCII to double */ G_format_northing(north, buf, G_projection()); /* double to ASCII */ G_format_northing(north, buf, -1); /* double to ASCII */ /* This last example forces floating-point ASCII format */
int G_begin_cell_area_calculations() begin cell area calculations
This routine must be called once before any call to G_area_of_cell_at_row(). It can be used in either planimetric projections or the latitude-longitude projection. It returns 2 if the projection is latitude-longitude, 1 if the projection is planimetric, and 0 of the projection doesn't hav e a metric (e.g. imagery.) If the return value is 1 or 0, all the grid cells in the map have the same area. Otherwise the area of a grid cell varies with the row.
double G_area_of_cell_at_row(int row) cell area in specified row
This routine returns the area in square meters of a cell in the specified row. This value is constant for planimetric grids and varies with the row if the projection is latitude-longitude.
int G_begin_zone_area_on_ellipsoid(double a, double e2, double s) begin area calculations for ellipsoid
Initializes raster area calculations for an ellipsoid, where a is the semi-major axis of the ellipse (in meters), e2 is the ellipsoid eccentricity squared, and s is a scale factor to allow for calculations of part of the zone (s=1.0 is full zone, s=0.5 is half the zone, and s=360/ew_res is for a single grid cell).
Note. e2 must be positive. A negative value makes no sense, and zero implies a sphere.
double G_area_for_zone_on_ellipsoid(double north, double south) area between latitudes
Returns the area between latitudes north and south scaled by the factor s passed to G_begin_zone_area_on_ellipsoid().
int G_begin_zone_area_on_sphere(double r, double s) initialize calculations for sphere
Initializes raster area calculations for a sphere. The radius of the sphere is r and s is a scale factor to allow for calculations of a part of the zone (see G_begin_zone_area_on_ellipsoid()).
double G_area_for_zone_on_sphere(double north, double south) area between latitudes
Returns the area between latitudes north and south scaled by the factor s passed to G_begin_zone_area_on_sphere()
However, there is an issue for latitude-longitude that does not occur with planimetric grids. Vector/polygon data is described as a series of x,y coordinates. The lines connecting the points are not stored but are inferred. This is a simple, straight-forward process for planimetric grids, but it is not simple for latitude-longitude. What is the shape of the line that connects two points on the surface of a globe?
One choice (among many) is the shortest path from x1,y1 to x2,y2, known as the geodesic. Another is a straight line on the grid. The area routines described below assume the latter. Routines to work with the former have not yet been developed.
int G_begin_polygon_area_calculations() begin polygon area calculations
This initializes the polygon area calculation routines. It is used both for planimetric and latitude-longitude projections.
It returns 2 if the projection is latitude-longitude, 1 if the projection is planimetric, and 0 if the projection doesn't have a metric (e.g. imagery.)
double G_area_of_polygon(double *x, double *y, int n) area in square meters of polygon
Returns the area in square meters of the polygon described by the n pairs of x,y coordinate vertices. It is used both for planimetric and latitude-longitude projections.
Note. If the database is planimetric with the non-meter grid, this routine performs the required unit conversion to produce square meters. double G_planimetric_polygon_area() (x, y, n) area in coordinate units double *x, *y ; int n ;
Returns the area in coordinate units of the polygon described by the n pairs of x,y coordinate vertices for planimetric grids. If the units for x,y are meters, then the area is in square meters. If the units are feet, then the area is in square feet, and so on.
int G_begin_ellipsoid_polygon_area (double a, double e2) begin area calculations
This initializes the polygon area calculations for the ellipsoid with semi-major axis a (in meters) and ellipsoid eccentricity squared e2.
double G_ellipsoid_polygon_area(double *lon, double *lat, int n) area of lat-long polygon
Returns the area in square meters of the polygon described by the n pairs of lat,long vertices for latitude-longitude grids.
Note. This routine assumes grid lines on the connecting the vertices (as opposed to geodesics).
int G_begin_distance_calculations() begin distance calculations
Initializes the distance calculations. It is used both for the planimetric and latitude-longitude projections.
It returns 2 if the projection is latitude-longitude, 1 if the projection is planimetric, and 0 if the projection doesn't hav e a metric (e.g. imagery).
double G_distance(double x1, y1, x2, y2) distance in meters
This routine computes the distance, in meters, from x1,y1 to x2,y2. If the projection is latitude-longitude, this distance is measured along the geodesic. Two routines perform geodesic distance calculations.
int G_begin_geodesic_distance(double a, double e2) begin geodesic distance
Initializes the distance calculations for the ellipsoid with semi-major axis a (in meters) and ellipsoid eccentricity squared e2. It is used only for the latitude-longitude projection.
double G_geodesic_distance(double lon1, double lat1, double lon2, double lat2) geodesic distance
Calculates the geodesic distance from lon1,lat1 to lon2,lat2 in meters.
The calculation of the geodesic distance is fairly costly. These next three routines provide a mechanism for calculating distance with two fixed latitudes and varying longitude separation.
int G_set_geodesic_distance_lat1(double lat1) set geodesic distance lat1
Set the first latitude.
int G_set_geodesic_distance_lat2(double lat2) set geodesic distance lat2
Set the second latitude.
double G_geodesic_distance_lon_to_lon(double lon1, double lon2) geodesic distance
Calculates the geodesic distance from lon1,lat1 to lon2,lat2 in meters, where lat1 was the latitude passed to G_set_geodesic_distance_latl() and lat2 was the latitude passed to G_set_geodesic_distance_lat2().
double G_adjust_easting(double east, struct Cell_head *region) returns east larger than west
If the region projection is PROJECTION_LL, then this routine returns an equivalent east that is larger, but no more than 360 degrees larger, than the coordinate for the western edge of the region. Otherwise no adjustment is made and the original east is returned.
double G_adjust_east_longitude(double east, double west) adjust east longitude
This routine returns an equivalent east that is larger, but no more than 360 larger than the west coordinate.
This routine should be used only with latitude-longitude coordinates.
int G_shortest_way(double *east1, double *east2) shortest way between eastings
If the database projection is PROJECTION_LL, then east1,east2 are changed so that they are no more than 180 degrees apart. Their true locations are not changed. If the database projection is not PROJECTION_LL, then east1,east2 are not changed.
This routine returns a pointer to a string containing the name for the nth ellipsoid in the GRASS ellipsoid table; NULL when n is too large. It can be used as follows:
int n; char *name; for (n=0; name=G_ellipsoid_name(n); n++) fprintf(stdout, "%s\n", name);
int G_get_ellipsoid_by_name(char *name, double *a, double *e2) get ellipsoid by name
This routine returns the semi-major axis a (in meters) and eccentricity squared e2 for the named ellipsoid. Returns 1 if name is a known ellipsoid, 0 otherwise.
int G_get_ellipsoid_parameters(double *a, double *e2) get ellipsoid parameters
This routine returns the semi-major axis a (in meters) and the eccentricity squared e2 for the ellipsoid associated with the database. If there is no ellipsoid explicitly associated with the database, it returns the values for the WGS 84 ellipsoid.
double G_meridional_radius_of_curvature(double lon, double a, double e2) meridional radius of curvature
Returns the meridional radius of curvature at a given longitude:
double G_transverse_radius_of_curvature(double lon, double a, double e2) transverse radius of curvature
Returns the transverse radius of curvature at a given longitude:
double G_radius_of_conformal_tangent_sphere(double lon, double a, double e2) radius of conformal tangent sphere
Returns the radius of the conformal sphere tangent to ellipsoid at a given longitude:
int G_pole_in_polygon(double *x, double *y, int n) pole in polygon
For latitude-longitude coordinates, this routine determines if the polygon defined by the n coordinate vertices x,y contains one of the poles.
Returns -1 if it contains the south pole; 1 if it contains the north pole; 0 if it contains neither pole.
Note. Use this routine only if the projection is PROJECTION_LL.
int G_bresenham_line(int x1, int y1, int x2, int y2, int (*point)()) Bresenham line algorithm
Draws a line from x1,y1 to x2,y2 using Bresenham's algorithm. A routine to plot points must be provided, as is defined as:
point(x, y) plot a point at x,y
This routine does not require a previous call to G_setup_plot() to function correctly, and is independent of all following routines.
int G_setup_plot(double t, double b, double l, double r, nt (*Move)(), int (*Cont)()) initialize plotting routines
Initializes the plotting capability. This routine must be called once before calling the G_plot_*() routines described below.
The parameters t, b, l, r are the top, bottom, left, and right of the output x,y coordinate space. They are not integers, but doubles to allow for subpixel registration of the input and output coordinate spaces. The input coordinate space is assumed to be the current GRASS region, and the routines supports both planimetric and latitude-longitude coordinate systems.
Move and Cont are subroutines that will draw lines in x,y space. They will be called as follows:
Move(x, y) move to x,y (no draw)
Cont(x, y) draw from previous position
to x,y. Cont() is responsible for clipping
int G_plot_line(double east1, double north1, double east2, double north2) plot line between latlon coordinates
A line from east1,north1 to east2,north2 is plotted in output x,y coordinates (e.g. pixels for graphics.) This routine handles global wrap-around for latitude-longitude databases.
See G_setup_plot() for the required coordinate initialization procedure.
int G_plot_polygon(double *east, double *north, int n) plot filled polygon with n vertices
The polygon, described by the n vertices east,north, is plotted in the output x,y space as a filled polygon.
See G_setup_plot() for the required coordinate initialization procedure.
int G_plot_area(double **xs, double **ys, int *npts, int rings) plot multiple polygons
Like G_plot_polygon(), except it takes a set of polygons, each with npts[i] vertices, where the number of polygons is specified with the rings argument. It is especially useful for plotting vector areas with interior islands.
int G_plot_where_en(int x, int y, double *east, double *north) x,y to east,north
The pixel coordinates x,y are converted to map coordinates east,north.
See G_setup_plot() for the required coordinate initialization procedure.
int G_plot_where_xy(double *east, double *north, int *x, int *y) east,north to x,y
The map coordinates east,north are converted to pixel coordinates x,y.
See G_setup_plot() for the required coordinate initialization procedure.
int G_plot_fx(double (*f)(), double east1, double east2) plot f(east1) to f(east2)
The function f(east) is plotted from east1 to east2. The function f(east) must return the map northing coordinate associated with east.
See G_setup_plot() for the required coordinate initialization procedure.
char * G_tempfile() returns a temporary file name
This routine returns a pointer to a string containing a unique file name that can be used as a temporary file within the module. Successive calls to G_tempfile() will generate new names.
Only the file name is generated. The file itself is not created. To create the file, the module must use standard UNIX functions which create and open files, e.g., creat() or fopen().
The programmer should take reasonable care to remove (unlink) the file before the module exits. However, GRASS database management will eventually remove all temporary files created by G_tempfile() that have been left behind by the modules which created them.
Note. The temporary files are created in the GRASS database rather than under /tmp. This is done for two reasons. The first is to increase the likelihood that enough disk is available for large temporary files since /tmp may be a very small file system. The second is so that abandoned temporary files can be automatically removed (but see the warning below).
Warning. The temporary files are named, in part, using the process id of the module. GRASS database management will remove these files only if the module which created them is no longer running. However, this feature has a subtle trap. Programs which create child processes (using the UNIX fork(), see also G_fork() routine) should let the child call G_tempfile(). If the parent does it and then exits, the child may find that GRASS has removed the temporary file since the process which created it is no longer running.
The parser routines behave in one of three ways:
(1) If no command line arguments are entered by the user, the parser searches for a completely interactive version of the command. If the interactive version is found, control is passed over to this version. If not, the parser will prompt the user for all programmer-defined options and flags. This prompting conforms to the same standard for every GRASS command that uses the parser routines.
(2) If command line arguments are entered but they are a subset of the options and flags that the programmer has defined as required arguments, three things happen. The parser will pass an error message to the user indicating which required options and/or flags were missing from the command line, the parser will then display a complete usage message for that command, and finally the parser cancels execution of the command.
(3) If all necessary options and flags are entered on the command line by the user, the parser executes the command with the given options and flags.
This is a basic list of members of the Option and Flag structures. A comprehensive description of all elements of these two structures and their possible values can be found in Full_Structure_Members_Description.
struct Option *opt; /* to declare a command line option */
Structure Member Description of Member
opt->key Option name that user will use opt->description Option description that is shown to the user opt->type Variable type of the user's answer to the option opt->required Is this option required on the command line? (Boolean)
struct Flag *flag; /* to declare a command line flag */
Structure Member Description of Member
flag->key Single letter used for flag name flag->description Flag description that is shown to the user
struct Option * G_define_option() returns Option structure
Allocates memory for the Option structure and returns a pointer to this memory (of type struct Option *).
struct Flag * G_define_flag() return Flag structure
Allocates memory for the Flag structure and returns a pointer to this memory (of type struct Flag *).
int G_parser(int argc, char *argv[]) parse command line
The command line parameters argv and the number of parameters argc from the main() routine are passed directly to G_parser(). G_parser() accepts the command line input entered by the user, and parses this input according to the input options and/or flags that were defined by the programmer.
G_parser() returns 0 if successful. If not successful, a usage statement is displayed that describes the expected and/or required options and flags and a non-zero value is returned.
int G_usage() command line help/usage message
Calls to G_usage() allow the programmer to print the usage message at any time. This will explain the allowed and required command line input to the user. This description is given according to the programmer's definitions for options and flags. This function becomes useful when the user enters options and/or flags on the command line that are syntactically valid to the parser, but functionally invalid for the command (e.g. an invalid file name.)
For example, the parser logic doesn't directly support grouping options. If two options be specified together or not at all, the parser must be told that these options are not required and the programmer must check that if one is specified the other must be as well. If this additional check fails, then G_parser() will succeed, but the programmer can then call G_usage() to print the standard usage message and print additional information about how the two options work together.
int G_disable_interactive() turns off interactive capability
When a user calls a command with no arguments on the command line, the parser will enter its own standardized interactive session in which all flags and options are presented to the user for input. A call to G_disable_interactive() disables the parser's interactive prompting.
Note: Displaying multiple answers default values (new in GRASS 5, see d.zoom for example).
char *def[] = {"One", "Two", "Last", NULL}; opt->multiple = YES; opt->answers = def; if (G_parser(argc, argv)) exit(EXIT_FAILURE);
The programmer may not forget last NULL value.
(1) Allocate memory for Flags and Options:
Flags and Options are pointers to structures allocated through the parser routines G_define_option() and G_define_flag() as defined in Parser_Routines.
#include "gis.h" ; /* The standard GRASS include file */ struct Option *opt ; /* Establish an Option pointer for each option */ struct Flag *flag ; /* Establish a Flag pointer for each option */ opt = G_define_option() ; /* Request a pointer to memory for each option */ flag = G_define_flag() ; /* Request a pointer to memory for each flag */
(2) Define members of Flag and Option structures:
The programmer should define the characteristics of each option and flag desired as outlined by the following example:
opt->key = "option"; /* The name of this option is "option". */ opt->description = _("Option test"); /* The option description is "Option test" */ opt->type = TYPE_STRING; /* The data type of the answer to the option */ opt->required = YES; /* This option *is* required from the user */ flag->key = "t"; /* Single letter name for flag */ flag->description = _("Flag test"); /* The flag description is "Flag test" */
Note.There are more options defined later in Complete_Structure_Members_Table.
(3) Call the parser:
int main(int argc, char *argv[]); /* command line args passed into main() */ if (G_parser(argc, argv)) /* Returns 0 if successful, non-zero otherwise */ exit(EXIT_FAILURE);
(4) Extracting information from the parser structures:
fprintf(stdout, "For the option "%s" you chose: <%s>\n", opt->description, opt->answer ); fprintf(stdout, "The flag "-%s" is %s set.\n", flag->key, flag->answer ? "" : "not" );
(5) Running the example program
Once such a module has been compiled (for example to the default executable file a.out , execution will result in the following user interface scenarios. Lines that begin with # imply user entered commands on the command line.
# a.out help
This is a standard user call for basic help information on the module. The command line options (in this case, "help") are sent to the parser via G_parser(). The parser recognizes the "help" command line option and returns a list of options and/or flags that are applicable for the specific command. Note how the programmer provided option and flag information is captured in the output.
a.out [-t] option=name Flags: -t Flag test Parameters: option Option test
Now the following command is executed:
# a.out -t
This command line does not contain the required option. Note that the output provides this information along with the standard usage message (as already shown above):
Required parameter <option> not set (Option test). Usage: a.out[-t] option=name Flags: -t Flag test Parameters: option Option test
The following commands are correct and equivalent. The parser provides no error messages and the module executes normally:
# a.out option=Hello -t # a.out -t option=Hello For the option "Option test" you chose: Hello The flag "-t" is set.
If this specific command has no fully interactive version (a user interface that does not use the parser), the parser will prompt for all programmer-defined options and/or flags.
User input is in italics, default answers are displayed in square brackets [ ].
# a.out OPTION: Option test key: option required: YES enter option> <I>Hello</I> You have chosen: option=Hello Is this correct? (y/n) [y] <I>y</I> FLAG: Set the following flag? Flag test? (y/n) [n] <I>n</I> You chose: <Hello> The flag is not set
MODULE_TOPDIR = ../.. PGM = r.mysample LIBES = $(GISLIB) DEPENDENCIES = $(GISDEP) include $(MODULE_TOPDIR)/include/Make/Module.make default: cmd
The sample.c code follows. You might experiment with this code to familiarize yourself with the parser.
Note. This example includes some of the advanced structure members described in Complete_Structure_Members_Table.
#include <stdlib.h> #include <string.h> #include "gis.h" #include "glocale.h" int main(int argc , char *argv[] ) { struct Option *opt ; struct Option *coor ; struct Flag *flag ; double X , Y ; int n ; opt = G_define_option() ; opt->key = "debug" ; opt->type = TYPE_STRING ; opt->required = NO ; opt->answer = "0" ; opt->description = _("Debug level") ; coor = G_define_option() ; coor->key = "coordinate" ; coor->key_desc = "x,y" ; coor->type = TYPE_STRING ; coor->required = YES ; coor->multiple = YES ; coor->description = _("One or more coordinates") ; /* Note that coor->answer is not given a default value. */ flag = G_define_flag() ; flag->key = 'v' ; flag->description = _("Verbose execution") ; /* Note that flag->answer is not given a default value. */ if (G_parser( argc , argv )) exit (EXIT_FAILURE); G_message("For the option <%s> you chose: <%s>\n", opt->description, opt->answer ); G_message("The flag <%s> is: %s set \n", flag->key, flag->answer ? "" : "not"); G_message("You specified the following coordinates:\n"); for ( n=0 ; coor->answers[n] != NULL ; n+=2 ) { G_scan_easting ( coor->answers[n ] , &X , G_projection() ); G_scan_northing ( coor->answers[n+1] , &Y , G_projection() ); G_message( "%.31f,%.21f\n", X , Y ); } }
TODO: Explain ''auto-conf''....
TODO: Include contents of SUBMITTING and INSTALL files from source code
To compile enter following:
./configure make make install
Then the code will be compiled into "/usr/local/grass-6.x.y" directory. The start script "grass6x" will be placed into "/usr/local/bin/".\
Optionally other target directories can be specified while "configuring":
./configure --prefix=/opt/grass-6.x.y --with-bindir=/usr/bin make make install
This will store the GRASS binaries into the directory "/opt/grass-6.x.y" and the script mentioned above into "/usr/bin".
The script "make" is required to compile single modules. The compilation process and requirements are discussed in more detail now.
GISLIB This names the GIS Library, which is the principal GRASS library. See GIS_Library for details about this library, and Loading the GIS Library for a sample Makefile which loads this library.
VASKLIB This names the Vask Library, which does full screen user input.
VASK This specifies the Vask Library plus the UNIX [n]curses and termcap libraries needed to use the Vask Library routines. See Vask_Library for details about this library, and Loading_the_Vask_Library for a sample Makefile which loads this library.
SEGMENTLIB This names the Segment Library, which manages large matrix data. See Segment_Library for details about this library, and Loading_the_Vask_Library for a sample Makefile which loads this library.
RASTERLIB This names the Raster Graphics Library, which communicates with GRASS graphics drivers. See Raster_Graphics_Library for details about this library, and Loading_the_Raster_Graphics_Library for a sample Makefile which loads this library.
DISPLAYLIB This names the Display Graphics Library, which provides a higher level graphics interface to RASTERLIB. See Display_Graphics_Library for details about this library, and Loading_the_Display_Graphics_Library for a sample Makefile which loads this library.\
UNIX Libraries: The following variables name some useful UNIX system libraries:
MATHLIB This names the math library. It should be used instead of the -lm loader option.
CURSES This names both the curses and termcap libraries. It should be used instead of the -lcurses/-lncurses and -ltermcap loader options. Do not use $CURSES
if you use $VASK
.
TERMLIB This names the termcap library. It should be used instead of the -ltermcap or -ltermlib loader options. Do not use $TERMLIB
if you use $VASK
or $CURSES
.\
Compiler and loader variables. The following variables are related to compiling and loading C programs:
EXTRA This variable can be used to add additional options to $CFLAGS
. It has no predefined values. It is usually used to specify additional -I include directories, or -D preprocessor defines.
target: dependencies actions more actions
If the target does not exist, or if any of the dependencies have a newer date than the target (i.e., have changed), the actions will be executed to build the target. The actions must be indented using a TAB. make is picky about this. It does not like spaces in place of the TAB.
Object files and library archives are compiled into subdirectories that represent the architecture that they were compiled on. These subdirectories are created in the $SRC directory as OBJ.arch and LIB.arch, where arch represents the architecture of the compiling machine. Thus, for example, $SRC/OBJ.sun4 would contain the object files for Sun/4 and SPARC architectures, and $SRC/LIB.686-pc-linux-gnu would contain library archives for Linux architectures. Likewise, $SRC/OBJ.686-pc-linux-gnu would contain the object files for Linux architectures, and $SRC/LIB.686-pc-linux-gnu would contain library archives for Linux architectures.
Note that 'arch' is defined for a specific architecture during setup and compilation of GRASS, it is not limited to sun4 or any specific string.
An in-depth summary of the more complex structure members is presented in Description_of_Complex_Structure_Members.
structure member | C type | required | default | description and example |
key | char | YES | none | Key char used on command line flag->key = 'f' ; |
Description | char * | YES | none | String describing flag meaning flag->description = _("run in fast mode") ; |
answer | char | NO | NULL | Default and parser-returned flag states. |
struct Option
structure member | C type | required | default | description and example |
key | char * | YES | none | Key word used on command line. opt->key = "map" ; |
type | int | YES | none | Option type: TYPE_STRING TYPE_INTEGER TYPE_DOUBLE opt->type = TYPE_STRING ; |
Description | char * | YES | none | String describing option along with gettext macro for internationalization opt->description = _("Map name") ; |
answer | char * | NO | NULL | Default and parser-returned answer to an option. opt->answer = "defaultmap" ; |
key_desc | char * | NO | NULL | Single word describing the key. Commas in this string denote to the parser that several comma-separated arguments are expected from the user as one answer. For example, if a pair of coordinates is desired, this element might be defined as follows. opt->key_desc = "x,y" ; |
structure member | C type | required | default | description and example |
multiple | int | NO | NO | Indicates whether the user can provide multiple answers or not. YES and NO are defined in "gis.h" and should be used (NO is the default.) Multiple is used in conjunction with the answers structure member below. opt->multiple = NO ; |
answers | NO | NULL | Multiple parser-returned answers to an option. N/A | |
required | int | NO | NO | Indicates whether user MUST provide the option on the command line. YES and NO are defined in "gis.h" and should be used (NO is the default.) opt->required = YES ; |
options | char * | NO | NULL | Approved values or range of values. opt->options = "red,blue,white" ; For integers and doubles, the following format is available: opt->options = "0-1000" ; |
gisprompt | char * | NO | NULL | Interactive prompt guidance. There are three comma separated parts to this argument which guide the use of the standard GRASS file name prompting routines. opt->gisprompt = "old,cell,raster" ; |
checker | char *() | NO | NULL | Routine to check the answer to an option m opt->checker = my_routine() ; |
(1) To set the default answer to an option:
If a default state is desired for a programmer-defined option, the programmer may define the Option structure member "answer" before calling G_parser() in his module. After the G_parser() call, the answer member will hold this preset default value if the user did not enter an option that has the default answer member value.
(2) To obtain the command-line answer to an option or flag: After a call to G_parser(), the answer member will contain one of two values:
(a) If the user provided an option, and answered this option on the command line, the default value of the answer member (as described above) is replaced by the user's input.
(b) If the user provided an option, but did not answer this option on the command line, the default is not used. The user may use the default answer to an option by withholding mention of the option on the command line. But if the user enters an option without an answer, the default answer member value will be replaced and set to a NULL value by G_parser().
As an example, please review the use of answer members in the structures implemented in Full_Module_Example.
If the multiple structure member is set to YES, the programmer has told G_parser() to capture multiple answers. Multiple answers are separated by commas on the command line after an option.
Note. G_parser() does not recognize any character other than a comma to delimit multiple answers.
After the programmer has set up an option to receive multiple answers, these the answers are stored in the answers member of the Option structure. The answers member is an array that contains each individual user-entered answer. The elements of this array are the type specified by the programmer using the type member. The answers array contains however many comma-delimited answers the user entered, followed (terminated) by a NULL array element.
For example, here is a sample definition of an Option using multiple and answers structure members:
opt->key ="option" ; opt->description = _("option example") ; opt->type = TYPE_INTEGER ; opt->required = NO ; opt->multiple = YES ;
The above definition would ask the user for multiple integer answers to the option. If in response to a routine that contained the above code, the user entered "option=1,3,8,15" on the command line, the answers array would contain the following values:
answers[0] == 1 answers[1] == 3 answers[2] == 8 answers[3] == 15 answers[4] == NULL
opt->key ="coordinate" ; opt->description = _("Specified Coordinate") ; opt->type = TYPE_INTEGER ; opt->required = NO ; opt->key_desc = "x,y" opt->multiple = NO ;
The answer to this option would not be stored in the answer member, but in the answers member. If the user entered "coordinate=112,225" on the command line in response to a routine that contains the above option definition, the answers array would have the following values after the call to G_parser():
answers[0] == 112 answers[1] == 225 answers[2] == NULL
Note that "coordinate=112" would not be valid, as it does not contain both components of an answer as defined by the key_desc structure member.
If the multiple structure member were set to YES instead of NO in the example above, the answers are stored sequentially in the answers member. For example, if the user wanted to enter the coordinates (112,225), (142,155), and (43,201), his response on the command line would be "coordinate=112,225,142,155,43,201". Note that G_parser() recognizes only a comma for both the key_desc member, and for multiple answers.
The answers array would have the following values after a call to G_parser():
answers[0] == 112 answers[1] == 225 answers[2] == 142 answers[3] == 155 answers[4] == 43 answers[5] == 201 answers[6] == NULL
Note. In this case as well, neither "coordinate=112" nor "coordinate=112,225,142" would be valid command line arguments, as they do not contain even pairs of coordinates. Each answer's format (as described by the key_desc member) must be fulfilled completely.
The overall function of the key_desc and multiple structure members is very similar. The key_desc member is used to specify the number of required components of a single option answer (e.g. a multi-valued coordinate.) The multiple member tells G_parser() to ask the user for multiple instances of the compound answer as defined by the format in the key_desc structure member.
Another function of the key_desc structure member is to explain to the user the type of information expected as an answer. The coordinate example is explained above.
The usage message that is displayed by G_parser() in case of an error, or by
G_usage() on programmer demand, is shown below. The Option "option" for the command a.out does not have its key_desc structure member defined.
Usage: a.out option=name
The use of "name" is a G_parser() standard. If the programmer defines the key_desc structure member before a call to G_parser(), the value of the key_desc member replaces "name". Thus, if the key_desc member is set to "x,y" as was used in an example above, the following usage message would be displayed:
Usage: a.out option=x,y
The key_desc structure member can be used by the programmer to clarify the usage message as well as specify single or multiple required components of a single option answer.
First argument:
"old" results in a call to the GRASS library subroutine G_ask_old(), "new" to G_ask_new(), "any" to G_ask_any(), and "mapset" to G_ask_in_mapset().
Second argument:
This is identical to the "element" argument in the above subroutine calls. It specifies a directory inside the mapset that may contain the user's response.
Third argument:
Identical to the "prompt" argument in the above subroutine calls. This is a string presented to the user that describes the type of data element being requested.
Here are two examples:
gisprompt arguments Resulting call
"new,cell,raster" G_ask_new("", buffer, "cell", "raster")
"old,dig,vector" G_ask_old("", buffer, "dig", "vector")
GRASS 4.0 introduced a new method for driving GRASS interactive and non-interactive modules as described in Compiling_and_Installing_GRASS_Programs. Here is a short overview.
For most modules a user runs a front-end module out of the GRASS bin directory which in turn looks for the existence of interactive and non-interactive versions of the module. If an interactive version exists and the user provided no command line arguments, then that version is executed.
In such a situation, the parser's default interaction will never be seen by the user. A programmer using the parser is able to avoid the front-end's default search for a fully interactive version of the command by placing a call to G_disable_interactive() before calling G_parser() (see Parser Routines for details.)
"Can the user mix options and flags?"
Yes. Options and flags can be given in any order.
"In what order does the parser present options and flags?"
Flags and options are presented by the usage message in the order that the programmer defines them using calls to G_define_option() and G_define_flag().
"How does a programmer query for coordinates?"
For any user input that requires a set of arguments (like a pair of map coordinates,) the programmer specifies the number of arguments in the key_desc member of the Option structure. For example, if opt->key_desc was set to "x,y", the parser will require that the user enter a pair of arguments separated only by a comma. See the source code for the GRASS commands r.drain or r.cost for examples.
"Is a user required to use full option names?"
No! Users are required to type in only as many characters of an option name as is necessary to make the option choice unambiguous. If, for example, there are two options, "input=" and "output=", the following would be valid command line arguments:
# command i=map1 o=map2
# command in=map1 out=map2
"Are options standardized at all?"
Yes. There are a few conventions. Options which identify a single input map are usually "map=", not "raster=" or "vector=". In the case of an input and output map the convention is: "input=xx output=yy". By passing the 'help' option to existing GRASS commands, it is likely that you will find other conventions. The desire is to make it as easy as possible for the user to remember (or guess correctly) what the command line syntax is for a given command.
These next 3 routines copy characters from one string to another.
char * G_strcpy(char *dst, char *src)copy strings
Copies the src string to dst up to and including the NULL which terminates the src string. Returns dst.
char * G_strncpy(char *dst, char *src, int n) copy strings
Copies at most n characters from the src string to dst. If src contains less than n characters, then only those characters are copied. A NULL byte is added at the end of dst. This implies that dst should be at least n+1 bytes long. Returns dst. Note. This routine varies from the UNIX strncpy() in that G_strncpy() ensures that dst is NULL terminated, while strncpy() does not.
char * G_strcat(char *dst, char *src) concatenate strings
Appends the src string to the end of the dst string, which is then NULL terminated. Returns dst.
These next 3 routines remove unwanted white space from a single string.
char * G_squeeze(char *s) remove unnecessary white space
Leading and trailing white space is removed from the string s and internal white space which is more than one character is reduced to a single space character. White space here means spaces, tabs, linefeeds, newlines, and formfeeds. Returns s.
void G_strip(char *s) remove leading/training white space
Leading and trailing white space is removed from the string s. White space here means only spaces and tabs. There is no return value.
char * G_chop(char *s) Chop leading and trailing white spaces: space, \f, \n, \r, \t, \v - returns pointer to string
The next routines replaces character(s) from string.
char * G_strchg(char *bug, char character, char new) replace character(s)
Replace all occurencies of character in string bug with new. Returns changed string
This next routine copies a string to allocated memory.
char * G_store(char *s) copy string to allocated memory
This routine allocates enough memory to hold the string s, copies s to the allocated memory, and returns a pointer to the allocated memory.
The next 2 routines convert between upper and lower case.
char * G_tolcase(char *s) convert string to lower case
Upper case letters in the string s are converted to their lower case equivalent. Returns s.
char * G_toucase(char *s) convert string to upper case
Lower case letters in the string s are converted to their upper case equivalent. Returns s.
And finally a routine which gives a printable version of control characters.
char * G_unctrl(unsigned char c) printable version of control character
This routine returns a pointer to a string which contains an English-like representation for the character c. This is useful for nonprinting characters, such as control characters. Control characters are represented by ctrl-C, e.g., control A is represented by ctrl-A. 0177 is represented by DEL/RUB. Normal characters remain unchanged.
This routine is useful in combination with G_intr_char() for printing the user's interrupt character:
char G_intr_char(); char * G_unctrl(); fprintf(stdout, "Your interrupt character is %s\n", G_unctrl(G_intr_char()));
Note. G_unctrl() uses a hidden static buffer which is overwritten from call to call.
FOLLOWING new FUNCTIONS need to be merged into the flow of this text:
int G_trim_decimal(char *buf) trim
This routine remove trailing zeros from decimal number for example: 23.45000 would come back as 23.45
char * G_index(str, delim) delimiter
Position of delimiter
char * G_rindex (str, delim) ??????
int G_strcasecmp(char *a, char *b) string compare ignoring case (upper or lower) returns: -1 if a<b
0 if a==b
1 if a>b
char * G_strstr(char *mainString, char *subString)Return a pointer to the first occurrence of subString in mainString, or NULL if no occurrences are found
char * G_strdup(char *string) Return a pointer to a string that is a duplicate of the string given to G_strdup. The duplicate is created using malloc. If unable to allocate the required space, NULL is returned.
However, there is a subtle problem with this logic. The fork() routine does not protect child processes from keyboard interrupts even if the parent is no longer running. Keyboard interrupts will also kill background processes that do not protect themselves.
Note: Programmers who use /bin/sh know that programs run in the background (using & on the command line) are not automatically protected from keyboard interrupts. To protect a command that is run in the background, /bin/sh users must do nohup command &. Programmers who use the /bin/csh (or other variants) do not know, or forget that the C-shell automatically protects background processes from keyboard interrupts.
Thus a module which puts itself in the background may never finish if the user interrupts another module which is running at the keyboard.
The solution is to fork() but also put the child process in a process group which is different from the keyboard process group. G_fork() does this.
pid_t G_fork() create a protected child process
This routine creates a child process by calling the UNIX fork() routine. It also changes the process group for the child so that interrupts from the keyboard do not reach the child. It does not cause the parent to exit().
G_fork() returns what fork() returns: -1 if fork() failed; otherwise 0 to the child, and the process id of the new child to the parent.
Note. Interrupts are still active for the child. Interrupts sent using the kill command, for example, will interrupt the child. It is simply that keyboard-generated interrupts are not sent to the child.
However, in some cases, this may not be the desired effect. In a menu environment where the parent activates menu choices by running commands using the system() call, it would be nice if the user could interrupt the command, but not terminate the menu module itself. The G_system() call allows this.
int G_system(command) run a shell level command
The shell level command is executed. Interrupt signals for the parent module are ignored during the call. Interrupt signals for the command are enabled. The interrupt signals for the parent are restored to their previous settings upon return.
G_system() returns the same value as system(), which is essentially the exit status of the command. See UNIX manual system(1) for details.
int G_is_little_endian() test little ENDIAN
Test if machine is little or big endian.
Returns:
1 little endian
0 big endian
char * G_sock_get_fname(char *name) makes full socket path
Takes a simple name for a communication channel and builds the full path for a sockets file with that name. The path as of this writing (2000-02-18) is located in the temporary directory for the user's current mapset (although this will likely change). A NULL pointer is returned if the function fails for some reason. The caller is responsible for freeing the memory of the returned string when it is no longer needed.
int G_sock_exists(char *name) does the socket exist
Takes the full path to a unix socket; determines if the file exists; and if the file exists whether it is a socket file or not. Returns a non-zero value if the file exists and is a socket file. Otherwise it returns zero.
int G_sock_bind(char *name) binds the socket
Takes the full path to a unix socket and attempts to bind a file descriptor to the path name. If successful it will return the file descriptor. Otherwise, it returns -1. The socket file must not already exist. If it does, this function will fail and set the global errno to EADDRINUSE. Other error numbers may be set if the call to bind() fails. Server programs wishing to bind a socket should test if the socket file they wish to use already exists. And, if so, they may try to connect to the socket to see if it is in use. If it is not in use, such programs may then call unlink() or remove() to delete the file before calling G_sock_bind(). It is important that server processes do not just delete existing socket files without testing the connection. Doing so may make another server process unreachable (i.e. you will have hijacked the other server's communication channel). Server processes must call G_sock_bind() prior to calling G_sock_listen() and G_sock_accept().
int G_sock_listen(int fd, unsigned int queue) listen on a socket
Takes the file descriptor returned by a successful call to G_sock_bind() and the length of the the listen queue. A successful call will return 0, while a failed call will return -1. The global errno will contain the error number corresponding to the reason for the failure. The queue length should never be zero. Some systems may interpret this to mean that no connections should be queued. Other systems may add a fudge factor to the queue length that the caller specifies. Servers that don't want additional connections queued should close() the listening file descriptor after a successful call to G_sock_accept(). This function is a simple wrapper around the system listen() function.
int G_sock_accept(int fd) accept a connection on the listening socket
Takes the file descriptor returned by a successful call to G_sock_bind(), for which a successful call to G_sock_listen() has also been made, and waits for an incoming connection. When a connection arrives, the file descriptor for the connection is returned. This function normally blocks indefinitely. However, an interrupt like SIGINT may cause this function to return without a valid connection. In this case, the return value will be -1 and the global error number will be set to EINTR. Servers should handle this possibility by calling G_sock_accept() again. A typical server might have a call to fork() after a successful return from G_sock_accept(). A server might also use select() to see if an a connection is ready prior to calling G_sock_accept(). This function is a simple wrapper around the system's accept() function, with the second and third arguments being NULL.
int G_sock_connect(char *name) make a connection to a server process
Takes the full path to a socket file and attempts to make a connection to a server listening for connections. If successful, the file descriptor for the socket connection is returned. Otherwise, -1 is returned and the global errno may be set. This function and G_sock_get_fname() are the only functions a client program really needs to worry about. If the caller wants to be sure that the global error number was set from an unsuccessful call to this function, she should zero errno prior to the call. Failures due to a non-existent socket file or a path name that exceeds system limits, will not change the global error number.
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include "gis.h" int main (int argc, char *argv[]) { int listenfd, rwfd; char *path; pid_t pid; /* Path is built using server's name */ if (NULL == (path = G_sock_get_fname (argv[0]))) exit (EXIT_FAILURE); /* Make sure another instance isn't running */ if (G_sock_exists (path)) { if ((listenfd = G_sock_connect (path)) != -1) { close (listenfd); exit (EXIT_FAILURE); } remove (path); } /* Bind the socket */ if ((listenfd = G_sock_bind (path)) < 0) exit (EXIT_FAILURE); /* Begin listening on the socket */ if (G_sock_listen (listenfd, 1) != 0) exit (EXIT_FAILURE); /* Loop forever waiting for connections */ for (;;) { if ((rwfd = G_sock_accept (listenfd)) < 0) { if (errno == EINTR) continue; } else exit (EXIT_FAILURE); /* Fork connection */ if ((pid = fork()) == 0) { char c; /* child closes listenfd */ close (listenfd); while (read (rwfd, &c, 1) > 0) write (rwfd, &c, 1); close (rwfd); return 0; } else if (pid > 0) { /* parent closes rwfd * a well behaved server would limit * the number of forks. */ close (rwfd); } else exit (EXIT_FAILURE); } G_free (path); return 0; }
char * G_date() current date and time
Returns a pointer to a string which is the current date and time. The format is the same as that produced by the UNIX date command.
char * G_gets(char *buf) get a line of input (detect ctrl-z)
This routine does a gets() from stdin into buf. It exits if end-of-file is detected. If stdin is a tty (i.e., not a pipe or redirected) then ctrl-z is detected. Returns 1 if the read was successful, or 0 if ctrl-z was entered.
Note. This is very useful for allowing a module to reprompt when a module is restarted after being stopped with a ctrl-z. If this routine returns 0, then the calling module should reprint a prompt and call G_gets() again. For example:
char buf[1024]; do{ fprintf(stdout, "Enter some input: ") ; } while ( ! G_gets(buf) ) ;
char * G_home() user's home directory
Returns a pointer to a string which is the full path name of the user's home directory.
char G_intr_char() return interrupt char
This routine returns the user's keyboard interrupt character. This is the character that generates the SIGINT signal from the keyboard.
See also G_unctr() for converting this character to a printable format.
int G_percent(int n, int total, int incr) print percent complete messages
This routine prints a percentage complete message to stderr. The percentage complete is (n/ total)*100, and these are printed only for each incr percentage. This is perhaps best explained by example:
# include <stdio.h> int row; int nrows; nrows = 1352; /* 1352 is not a special value - example only */ fprintf (stderr, "Percent complete: "); for (row = 0; row < nrows; row++) G_percent (row, nrows, 10);
This will print completion messages at 10% increments; i.e., 10%, 20%, 30%, etc., up to 100%. Each message does not appear on a new line, but rather erases the previous message. After 100%, a new line is printed.
char * G_program_name() return module name
Routine returns the name of the module as set by the call to G_gisinit().
char * G_whoami() user's name
Returns a pointer to a string which is the user's login name.
int G_yes(char *question, int default) ask a yes/no question
This routine prints a question to the user, and expects the user to respond either yes or no. (Invalid responses are rejected and the process is repeated until the user answers yes or no.)
The default indicates what the RETURN key alone should mean. A default of 1 indicates that RETURN means yes, 0 indicates that RETURN means no, and -1 indicates that RETURN alone is not a valid response.
The question will be appended with "(y/n) ", and, if default is not -1, with "[y] " or "[n] ", depending on the default.
G_yes() returns 1 if the user said yes, and 0 if the user said no.
struct Cell_head { int format; /* number of bytes per cell */ int compressed; /* compressed(1) or not compressed(0) */ int rows, cols; /* number of rows and columns */ int proj; /* projection */ int zone; /* zone */ double ew_res; /* east-west resolution */ double ns_res; /* north-south resolution */ double north; /* northern edge */ double south; /* southern edge */ double east; /* eastern edge */ double west; /* western edge */ };
The format and compressed fields apply only to raster headers. The format field describes the number of bytes per raster data value and the compressed field indicates if the raster file is compressed or not. The other fields apply both to raster headers and regions. The geographic boundaries are described by north, south, east and west. The grid resolution is described by ew_res and ns_res. The cartographic projection is described by proj and the related zone for the projection by zone. The rows and cols indicate the number of rows and columns in the raster file, or in the region. See Raster_Header_Format for more information about raster headers, and Region for more information about regions.
The routines described in Raster Header File use this structure.
The structure is declared: struct Categories .
This structure should be accessed using the routines described in Raster_Category_File.
The structure is declared: struct Colors .
The routines described in Raster_Color_Table must be used to store and retrieve color information using this structure.
# define MAXEDLINES 50 # define RECORD_LEN 80 struct History { char mapid[RECORD_LEN]; char title[RECORD_LEN]; char mapset[RECORD_LEN]; char creator[RECORD_LEN]; char maptype[RECORD_LEN]; char datsrc_1[RECORD_LEN]; char datsrc_2[RECORD_LEN]; char keywrd[RECORD_LEN]; int edlinecnt; char edhist[MAXEDLINES][RECORD_LEN]; };
The mapid and mapset are the raster file name and mapset, title is the raster file title, creator is the user who created the file, maptype is the map type (which should always be "raster"), datasrc_1 and datasrc_2 describe the original data source, keywrd is a one-line data description and edhist contains edlinecnt lines of user comments.
The routines described in Raster_History_File use this structure. However, there is very little support for manipulating the contents of this structure. The programmer must manipulate the contents directly.
Note. Some of the information in this structure is not meaningful. For example, if the raster file is renamed, or copied into another mapset, the mapid and mapset will no longer be correct. Also the title does not reflect the true raster file title. The true title is maintained in the category file.
Warning. This structure has remained unchanged since the inception of GRASS. There is a good possibility that it will be changed or eliminated in future releases.
The structure is declared: struct Range .
The routines described in Raster_Range_File should be used to access this structure.
MODULE_TOPDIR = ../.. PGM = r.info LIBES = $(GISLIB) DEPENDENCIES = $(GISDEP) include $(MODULE_TOPDIR)/include/Make/Module.make default: cmd
See Compiling and Installing GRASS Modules for a complete discussion of Makefiles.
#include "gis.h"
This structure is defined in gis.h, but there should be no reason to access its elements directly:
struct TimeStamp { DateTime dt[2]; /* two datetimes */ int count; };
Using the G_*_timestamp() routines reads/writes a timestamp file in the cell_misc/rastername or dig_misc/vectorname mapset element.
A TimeStamp can be one DateTime, or two DateTimes representing a range. When preparing to write a TimeStamp, the programmer should use one of:
G_set_timestamp() to set a single DateTime
G_set_timestamp_range() to set two DateTimes.
int G_read_raster_timestamp(char *name, char *mapset, struct TimeStamp ts) Read raster timestamp
Returns 1 on success. 0 or negative on error.
int G_read_vector_timestamp(char *name, char *mapset, struct TimeStamp ts) Read vector timestamp
Returns 1 on success. 0 or negative on error.
int G_get_timestamps(struct TimeStamp *ts, DateTime *dt1, DateTime dt2, int *count) copy TimeStamp into Datetimes
Use to copy the TimeStamp information into Datetimes, so the members of struct TimeStamp shouldn't be accessed directly.
count=0 means no datetimes were copied
count=1 means 1 datetime was copied into dt1
count=2 means 2 datetimes were copied
int G_init_timestamp(struct TimeStamp *ts) Sets ts->count = 0, to indicate no valid DateTimes are in TimeStamp.
int G_set_timestamp(struct TimeStamp *ts, DateTime *dt) Copies a single DateTime to a TimeStamp in preparation for writing. (overwrites any existing information in TimeStamp)
int G_set_timestamp_range(struct TimeStamp *ts, DateTime *dt1, DateTime *dt2) Copies two DateTimes (a range) to a TimeStamp in preparation for writing. (overwrites any existing information in TimeStamp)
int G_write_raster_timestamp(char *name, struct TimeStamp *ts) Returns:
1 on success.
-1 error - can't create timestamp file
-2 error - invalid datetime in ts
int G_write_vector_timestamp(char *name, struct TimeStamp *ts) Returns:
1 on success.
-1 error - can't create timestamp file
-2 error - invalid datetime in ts
int G_format_timestamp(struct TimeStamp *ts, char *buf) Returns:
1 on success
-1 error
int G_scan_timestamp(struct TimeStamp *ts, char *buf) Returns:
1 on success
-1 error
int G_remove_raster_timestamp(char *name) Only timestamp files in current mapset can be removed
Returns:
0 if no file
1 if successful
-1 on fail
int G_remove_vector_timestamp(char *name) Only timestamp files in current mapset can be removed
Returns:
0 if no file
1 if successful
-1 on fail
int G_read_grid3_timestamp(char *name,char *mapset, struct TimeStamp *ts) read grid3 timestamp
Returns 1 on success. 0 or negative on error.
int G_remove_grid3_timestamp(char *name) remove grid3 timestamp
Only timestamp files in current mapset can be removed
Returns:
0 if no file
1 if successful
-1 on fail
int G_write_grid3_timestamp(char *name, struct TimeStamp *ts) write grid3 timestamp
Returns:
1 on success.
-1 error - can't create timestamp file
-2 error - invalid datetime in ts
See DateTime_Library for a complete discussion of GRASS datetime routines.
bitmap : bitmap library for X Window Bitmaps btree : binary tree library bwidget : tcl/tk extra library cdhc : library for testing normality and exponentiality D : display library datetime : DateTime library db : database management interface database drivers + SQL parser display : library for CELL driver dspf : G3D display files library edit : edit library external : external libraries from other projects (shapelib) fonts : Hershey fonts form : forms library front.end : interface for interactive modules g3d : G3D raster volume library gis : main GRASS library gmath : generic mathematical functions (matrix, fft etc.) (later to be extended, BLAS/LAPACK library) gtcltk : Tcl/Tk stuff image : extra imagery library (image3) imagery : imagery library init : GRASS initialization code + scripts linkm : linked list memory manager ogsf : ported gsurf library (required for NVIZ) proj : PROJ4.4.x projection library raster : GRASS raster display library (raster map functions are in gis/) rowio : row in/out library rst : library for interpolation with regularized splines with tension segment : segment library sites : old sites library (deprecated), now interfaced to vect library symbol : drawing symbols for point vector data vask : Curses management library vect : GRASS vector and Direct Graph library