[GRASS5] First libgrass Release

Frank Warmerdam warmerda at home.com
Tue Sep 12 18:41:42 EDT 2000


Folks, 

As part of the OSSIM/GRASS Bridge project I am preparing a standalone version
of the grass raster access code as a shared library.  I have prepared a first
cut of this, and would be happy to have others try it out if interest.  I have
included the contents of the README.  The source is available on my GRASS
page at:

  http://gdal.velocet.ca/projects/grass/

Best regards,

---------------------------------------+--------------------------------------
I set the clouds in motion - turn up   | Frank Warmerdam, warmerda at home.com
light and sound - activate the windows | http://members.home.com/warmerda
and watch the world go round - Rush    | Geospatial Programmer for Rent
-------------- next part --------------

	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.


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.  


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



More information about the grass-dev mailing list