Standalone GRASS Database Access Library - libgrass =================================================== Overview -------- The libgrass package consists of the majority of the GRASS libgis, and libdatetime library build as a standalone shared library suitable for use by non-GRASS applications wishing to read and write GRASS databases. Some additional functions have been added to simplify library initialization and data access by non-GRASS applications. While libgrass is currently only suitable for accessing GRASS raster cells, and associated support files, it is hoped that future revisions will include support for vector files, and other data elements stored within the GRASS database. New Versions ------------ The temporary libgrass web page is at: http://gdal.velocet.ca/projects/grass/index.html The source for libgrass can be found in the "libgrass" tree on the grass CVS server. http://www.geog.uni-hannover.de/grass/grasscvs.html Building -------- The INSTALL file addresses generic build, and installation issues. The libgrass package uses configure, and libtool to simplify building in different environments. Libgrass has no noteworthy dependencies, but is unlikely to work in a non-Unix environment. By default the install target should put libgrass.so and libgrass.a in /usr/local/lib, and several include files in /usr/local/include. Building On Windows ------------------- It is possible to build using the latest Cygwin environment (ie. 1.1.x): http://sources.redhat.com/cygwin/ It is also necessary to install "sun rpc" support to provide access to XDR functions. A pre-built version (to be untarred over /usr) can be found at: http://gdal.velocet.ca/projects/grass/sunrpc-4_0_cygwin1_bin_tar.gz Programmer Documentation ------------------------ All the standard libgis GRASS functions are documented in the GRASS 5 Programmers Manual, available from: http://www.geog.uni-hannover.de/grass/grassdevel.html The following functions have been implemented custom to libgrass, though some of them may move into the GRASS core in time. The libgrass extensions can be accessed by #include'ing "libgrass.h" normally stored in /usr/local/include. In general a standalone application needing to read, or write the GRASS database should: 1) Call g_gisinit_2(program_name, NULL, NULL, NULL) to intialize the library. If a $HOME/.grassrc5 file exists, it will be read and used to default the database, mapset and location. 2) Use G_check_cell() to test if a particular path is a valid GRASS raster cell. Note that if it is, G_check_cell() will make that cells mapset the current mapset. 3) It may be necessary to set the active window before accessing a cell with G_open_cell_old_2(), in particular if the cell has a different projection than the raster. The cells window can be fetched with G_get_cellhd(), after G_check_cell() has succeeded and set with G_set_window(). Use the mapset, and cellname returned by G_check_cell(). 3) Use G_open_cell_old_2() to open a raster cell. It understands direct paths as well as current mapset names like G_check_cell(). 4) Use normal GRASS calls like G_set_window(), G_get_raster_row(), and G_get_cellhd() to access the database. Don't forget to close the cell with G_close_cell(). The new entry points are listed here: /*************************************************************************** * char **G_gisinit_2(pgm, gisdbase, location, mapset ); * * char *pgm name of the program for error reporting. * char *gisdbase path to database, or NULL to use GISDBASE environment * variable, or contents of ~/.grassrc file. * char *location location within database, or NULL to use environment * variable LOCATION_NAME or ~/.grassrc file. * char *mapset mapset within location, or NULL to use environment * variable MAPSET or ~/.grassrc. * * Library initialization similar to G_gisinit(), but giving the * calling application some control over what database, location and * mapset is used. * * If the initialization fails (because no valid mapset was given, * nor determinable) the function will return a non-zero error, otherwise * zero is returned. * * Note that this will potentially modify the programs environment * with G_setenv() to record the database, location and mapset selected. * * ------------------------------------------------------------------------ * FIXME: I am currently using G_setenv() to override environment variables * which results in the .grassrc file being rewritten. This isn't * really desirable. I would prefer the effects to be "in memory" * only. *************************************************************************/ /********************************************************************** * char **G_fetch_list_element (element, mapset) * * char *element database element (eg, "cell", "cellhd", etc) * char *mapset mapset to be listed. * NULL to list all mapsets in mapset search list * "." will list current mapset * * Fetches a list of all the files in the indicated element in the * indicated mapsets. The returned list is a NULL terminated array * of strings that should be deallocated with G_free(). *********************************************************************/ /********************************************************************** * char **G_fetch_list_locations( gisdbase ) * * char *gisdbase Database to selection locations from, or * NULL to use the default database. * * Returns a NULL terminated list of location names, which can be * freed with G_free_list() when no longer needed. *********************************************************************/ /********************************************************************** * char **G_fetch_list_mapsets( location_path ) * * char *location_path full path to location to list mapsets for, * or NULL to use the default. * * Returns a NULL terminated list of mapset names, which can be * freed with G_free_list() when no longer needed. *********************************************************************/ /********************************************************************** * void G_free_list( list ) * * char **list NULL terminated list of strings to be freed with * G_free(), as returned by the various G_fetch_list*() * functions. *********************************************************************/ /*************************************************************************** * int G_check_cell( full_name, ret_mapset, ret_cellname ); * * char *full_name Name of cell to open. This may be just the cell name, * in which case it will be interpreted relative to the * current mapset, or it may be a relative or absolute * path to a cellhd file. * * char **ret_mapset * Location in which to return the mapset name, or NULL * if not requested. Mapset name should be freed with * G_free() when no longer needed. * * char **ret_cellname * Location in which to return the cell name, or NULL * if not requested. Cell name should be freed with * G_free() when no longer needed. * * Returns 0 if the passed name does not appear to be a valid cell name, or * 1 otherwise. If this functions returns 1, then the cell_name should * be suitable for G_open_cell_old_2() (but might not work with * G_open_cell_old(). This function may call G_gisinit_2() if the cell * if fully qualified and in a different location or database than the current * one. * * Applications should have called G_gisinit(), or G_gisinit_2() before * calling this function; however, this doesn't require that the * initialization successfully identified a current grass mapset. *************************************************************************/ /*************************************************************************** * int G_open_cell_old_2( cell_name ); * * char *cell_name Name of cell to open. This may be just the cell name, * in which case it will be interpreted relative to the * current mapset, or it may be a relative or absolute * path to a cellhd file. * * Returns -1 if the open fails, or the file descriptor for the cell otherwise. * Applications should have called G_gisinit(), or G_gisinit_2() before * calling this function; however, this doesn't require that the * initialization successfully identified a current grass mapset. After * a successful return, the current database, location and mapset will have * been set suitably for the given cell. *************************************************************************/ Hints and Tips for Programmers ------------------------------ o libgrass can be used to open GRASS cells (rasters) with just the name of the cell (as opposed to a whole path to the cell header file) if there is a $HOME/.grassrc5 file with a valid database, location and mapset set. o Any GRASS cell can be access by giving a full path to the cell header file. This might look something like: /u/data/grassdb/global/PERMANENT/cellhd/soil.f Note that the path must include the grass database, location, mapset and cellhd components. If a relative path is used without all these components the access will not work properly. o As of the first revision, directly accessing a raster cell with a path will result in the $HOME/.grassrc5 being updating with that cell's mapset, location and database being current. o There is currently no support for preventing concurrent access or update to the grass database (unlike GRASS itself which avoids multiple users operating on the same mapset). o G_open_cell_old_2(), and G_check_cell() may call G_gisinit_2() internally potentially resulting in confusion of access to existing open grass cells. o Many GRASS functions treat a failure as a fatal error, and will call exit() via G_fatal_error() without returning. This can be a problem if the master program would prefer to recover from the error. :-) The G_gisinit_2(), G_check_cell(), and G_open_cell_2() functions have been "cleansed" to avoid this problem. Care should be taken to avoid calling other functions in situations where they may fail. It may be possible to avoid this by installing a custom error handler with G_set_error_routine(), and careful use of setjmp(), and longjmp() to return to application level code without giving the GRASS library an opportunity to call exit(). o Sample code demonstrating use of libgrass can be found in the samples directory, as well as in the GRASS drivers of GDAL and OSSIM. http://www.remotesensing.org/cgi-bin/cvsweb.cgi/osrs/ossim/src/util/image_proc/formats/grass/GrassTileSource.cc?rev=1.1 http://www.remotesensing.org/cgi-bin/cvsweb.cgi/osrs/gdal/frmts/grass/grassdataset.cpp?rev=1.1