[gdal-grass] 02/04: Imported Upstream version 2.1.0~beta1

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Sat Apr 2 16:32:07 UTC 2016


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch experimental-2.1
in repository gdal-grass.

commit 60a8a97153f939ae1bced4f54c71af0d99714d84
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Sat Apr 2 18:25:45 2016 +0200

    Imported Upstream version 2.1.0~beta1
---
 Makefile.in            |  10 +-
 VERSION                |   2 +-
 configure.in           |   8 +-
 grass57dataset.cpp     | 254 +++++++++++++++++++--------------------
 ogrgrass.h             |  28 +++--
 ogrgrassdatasource.cpp |  57 +++++----
 ogrgrassdriver.cpp     |  38 +++---
 ogrgrasslayer.cpp      | 313 ++++++++++++++++++++++++-------------------------
 8 files changed, 350 insertions(+), 360 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index 007df6d..9bac96a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -4,9 +4,9 @@ LD	=	@CXX@
 
 CPPFLAGS = -DUSE_CPL -DGRASS_GISBASE=\"@GRASS_GISBASE@\" \
 	  @GDAL_INC@ @GRASS_INCLUDE@ @PQ_INCLUDE@ @CPPFLAGS@
-CXXFLAGS = @CXX_WFLAGS@ @CXX_PIC@ 
-CFLAGS   = @CFLAGS@ 
-LDFLAGS  = @LDFLAGS@ 
+CXXFLAGS = @CXX_WFLAGS@ @CXX_PIC@
+CFLAGS   = @CFLAGS@
+LDFLAGS  = @LDFLAGS@
 
 RANLIB		=	@RANLIB@
 SO_EXT		=	@SO_EXT@
@@ -40,7 +40,7 @@ install:	default
 	cp -r @GRASS_GISBASE@/driver/db/* ${GRASSTABLES_DIR}/driver/db/
 
 clean:
-	rm -f $(OLIBNAME) $(GLIBNAME) *.o 
+	rm -f $(OLIBNAME) $(GLIBNAME) *.o
 
 distclean: clean
 	rm -fr Makefile config.status config.log autom*.cache
@@ -49,7 +49,7 @@ distclean: clean
 $(GLIBNAME):	grass57dataset.o
 	$(LD_SHARED) $(LDFLAGS) grass57dataset.o $(LIBS) -o $(GLIBNAME)
 
-$(OLIBNAME):	ogrgrassdriver.o ogrgrassdatasource.o ogrgrasslayer.o 
+$(OLIBNAME):	ogrgrassdriver.o ogrgrassdatasource.o ogrgrasslayer.o
 	$(LD_SHARED) $(LDFLAGS) ogrgrassdriver.o ogrgrassdatasource.o ogrgrasslayer.o $(LIBS) -o $(OLIBNAME)
 
 %.o:	%.cpp
diff --git a/VERSION b/VERSION
index e9307ca..7ec1d6d 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.0.2
+2.1.0
diff --git a/configure.in b/configure.in
index 0ac90cb..a0cfa9c 100644
--- a/configure.in
+++ b/configure.in
@@ -1,5 +1,5 @@
 dnl ***************************************************************************
-dnl $Id: configure.in 28598 2015-03-03 07:34:28Z martinl $
+dnl $Id: configure.in 33717 2016-03-14 06:29:14Z goatbar $
 dnl
 dnl Project:  GDAL GRASS Plugin
 dnl Purpose:  Configure source file.
@@ -127,9 +127,9 @@ if test "$with_grass" != "yes" ; then
   if test "$GRASS_SETTING" = "no" ; then
     AC_CHECK_LIB(grass_gis,G_asprintf,GRASS_SETTING=grass57+,GRASS_SETTING=no,-L$with_grass/lib -lgrass_datetime)
   fi
-   
-  if test "$GRASS_SETTING" != "no" ; then   
-    if test "$GRASS_SETTING" = "grass70+" ; then   
+
+  if test "$GRASS_SETTING" != "no" ; then
+    if test "$GRASS_SETTING" = "grass70+" ; then
       G_RASTLIBS="-lgrass_raster -lgrass_imagery"
       G_VECTLIBS="-lgrass_vector -lgrass_dig2 -lgrass_dgl -lgrass_rtree -lgrass_linkm -lgrass_dbmiclient -lgrass_dbmibase"
       LIBS="-L$with_grass/lib $G_VECTLIBS $G_RASTLIBS -lgrass_gproj -lgrass_gmath -lgrass_gis -lgrass_datetime $LIBS"
diff --git a/grass57dataset.cpp b/grass57dataset.cpp
index 0b97887..fac8a1f 100644
--- a/grass57dataset.cpp
+++ b/grass57dataset.cpp
@@ -1,10 +1,10 @@
 /******************************************************************************
- * $Id: grass57dataset.cpp 28534 2015-02-21 14:34:39Z rouault $
+ * $Id: grass57dataset.cpp 33717 2016-03-14 06:29:14Z goatbar $
  *
  * Project:  GRASS Driver
  * Purpose:  Implement GRASS raster read/write support
  *           This version is for GRASS 5.7+ and uses GRASS libraries
- *           directly instead of using libgrass. 
+ *           directly instead of using libgrass.
  * Author:   Frank Warmerdam <warmerdam at pobox.com>
  *           Radim Blazek <blazek at itc.it>
  *
@@ -41,7 +41,12 @@ extern "C" {
 #ifdef __cplusplus
 #undef class
 #endif
-    
+
+#include "cpl_string.h"
+#include "gdal_frmts.h"
+#include "gdal_priv.h"
+#include "ogr_spatialref.h"
+
 #include <grass/version.h>
 #include <grass/gprojects.h>
 #include <grass/gis.h>
@@ -57,17 +62,9 @@ char *GPJ_grass_to_wkt(struct Key_Value *,
 #endif
 }
 
-#include "gdal_priv.h"
-#include "cpl_string.h"
-#include "ogr_spatialref.h"
-
 #define GRASS_MAX_COLORS 100000  // what is the right value
 
-CPL_CVSID("$Id: grass57dataset.cpp 28534 2015-02-21 14:34:39Z rouault $");
-
-CPL_C_START
-void	GDALRegister_GRASS(void);
-CPL_C_END
+CPL_CVSID("$Id: grass57dataset.cpp 33717 2016-03-14 06:29:14Z goatbar $");
 
 #if GRASS_VERSION_MAJOR  >= 7
 #define G_get_cellhd             Rast_get_cellhd
@@ -123,12 +120,12 @@ class GRASSDataset : public GDALDataset
 {
     friend class GRASSRasterBand;
 
-    char	*pszGisdbase;  
+    char	*pszGisdbase;
     char	*pszLocation;  /* LOCATION_NAME */
     char	*pszElement;   /* cellhd or group */
 
-    struct Cell_head sCellInfo; /* raster region */ 
-    
+    struct Cell_head sCellInfo; /* raster region */
+
     char	*pszProjection;
 
     double	adfGeoTransform[6];
@@ -165,7 +162,7 @@ class GRASSRasterBand : public GDALRasterBand
     struct Colors sGrassColors;
     GDALColorTable *poCT;
 
-    struct Cell_head sOpenWindow; /* the region when the raster was opened */ 
+    struct Cell_head sOpenWindow; /* the region when the raster was opened */
 
     int		bHaveMinMax;
     double	dfCellMin;
@@ -177,7 +174,7 @@ class GRASSRasterBand : public GDALRasterBand
 
   public:
 
-                   GRASSRasterBand( GRASSDataset *, int, 
+                   GRASSRasterBand( GRASSDataset *, int,
                                     const char *, const char * );
     virtual        ~GRASSRasterBand();
 
@@ -194,7 +191,7 @@ class GRASSRasterBand : public GDALRasterBand
 
   private:
     CPLErr ResetReading( struct Cell_head * );
-    
+
 };
 
 
@@ -226,7 +223,7 @@ GRASSRasterBand::GRASSRasterBand( GRASSDataset *poDS, int nBand,
 /* -------------------------------------------------------------------- */
     struct FPRange sRange;
 
-    if( G_read_fp_range( (char *) pszCellName, (char *) pszMapset, 
+    if( G_read_fp_range( (char *) pszCellName, (char *) pszMapset,
                          &sRange ) == -1 )
     {
         bHaveMinMax = FALSE;
@@ -240,12 +237,12 @@ GRASSRasterBand::GRASSRasterBand( GRASSDataset *poDS, int nBand,
 /* -------------------------------------------------------------------- */
 /*      Setup band type, and preferred nodata value.                    */
 /* -------------------------------------------------------------------- */
-    // Negative values are also (?) stored as 4 bytes (format = 3) 
+    // Negative values are also (?) stored as 4 bytes (format = 3)
     //       => raster with format < 3 has only positive values
 
-    // GRASS modules usually do not waste space and only the format necessary to keep 
+    // GRASS modules usually do not waste space and only the format necessary to keep
     // full raster values range is used -> no checks if shorter type could be used
-    
+
     if( nGRSType == CELL_TYPE ) {
 	if ( sCellInfo.format == 0 ) {  // 1 byte / cell -> possible range 0,255
 	    if ( bHaveMinMax && dfCellMin > 0 ) {
@@ -268,20 +265,20 @@ GRASSRasterBand::GRASSRasterBand( GRASSDataset *poDS, int nBand,
 		dfNoData = 65535;
 	    } else { // maximum is not known or full range is used
 		CELL cval;
-		this->eDataType = GDT_Int32; 
+		this->eDataType = GDT_Int32;
 		G_set_c_null_value ( &cval, 1);
 		dfNoData = (double) cval;
 		nativeNulls = true;
 	    }
 	    nativeNulls = false;
-	} else {  // 3-4 bytes 
+	} else {  // 3-4 bytes
 	    CELL cval;
 	    this->eDataType = GDT_Int32;
 	    G_set_c_null_value ( &cval, 1);
 	    dfNoData = (double) cval;
 	    nativeNulls = true;
 	}
-    } 
+    }
     else if( nGRSType == FCELL_TYPE ) {
 	FCELL fval;
         this->eDataType = GDT_Float32;
@@ -314,7 +311,7 @@ GRASSRasterBand::GRASSRasterBand( GRASSDataset *poDS, int nBand,
     poCT = NULL;
     if( G_read_colors( (char *) pszCellName, (char *) pszMapset, &sGrassColors ) == 1 )
     {
-	int maxcolor; 
+	int maxcolor;
 	CELL min, max;
 
 	G_get_color_range ( &min, &max, &sGrassColors);
@@ -325,7 +322,7 @@ GRASSRasterBand::GRASSRasterBand( GRASSDataset *poDS, int nBand,
             } else {
 	       maxcolor = (int) ceil ( dfCellMax );
 	    }
-	    if ( maxcolor > GRASS_MAX_COLORS ) { 
+	    if ( maxcolor > GRASS_MAX_COLORS ) {
 		maxcolor = GRASS_MAX_COLORS;
                 CPLDebug( "GRASS", "Too many values, color table cut to %d entries.", maxcolor );
 	    }
@@ -337,7 +334,7 @@ GRASSRasterBand::GRASSRasterBand( GRASSDataset *poDS, int nBand,
                CPLDebug( "GRASS", "Too many values, color table set to %d entries.", maxcolor );
 	    }
         }
-	    
+
         poCT = new GDALColorTable();
         for( int iColor = 0; iColor <= maxcolor; iColor++ )
         {
@@ -367,30 +364,29 @@ GRASSRasterBand::GRASSRasterBand( GRASSDataset *poDS, int nBand,
                 poCT->SetColorEntry( iColor, &sColor );
             }
         }
-	    
-	/* Create metadata enries for color table rules */
-	char key[200], value[200];
-	int rcount = G_colors_count ( &sGrassColors );
 
-	sprintf ( value, "%d", rcount );
-	this->SetMetadataItem( "COLOR_TABLE_RULES_COUNT", value );
+        /* Create metadata entries for color table rules */
+        char key[200], value[200];
+        int rcount = G_colors_count ( &sGrassColors );
 
-	/* Add the rules in reverse order */
-	for ( int i = rcount-1; i >= 0; i-- ) {
-	    DCELL val1, val2;
-	    unsigned char r1, g1, b1, r2, g2, b2;
+        snprintf ( value, sizeof(value), "%d", rcount );
+        this->SetMetadataItem( "COLOR_TABLE_RULES_COUNT", value );
 
-	     G_get_f_color_rule ( &val1, &r1, &g1, &b1, &val2, &r2, &g2, &b2, &sGrassColors, i );
-		
+        /* Add the rules in reverse order */
+        for ( int i = rcount-1; i >= 0; i-- ) {
+            DCELL val1, val2;
+            unsigned char r1, g1, b1, r2, g2, b2;
 
-	     sprintf ( key, "COLOR_TABLE_RULE_RGB_%d", rcount-i-1 );
-	     sprintf ( value, "%e %e %d %d %d %d %d %d", val1, val2, r1, g1, b1, r2, g2, b2 );
-	     this->SetMetadataItem( key, value );
-	}
+            G_get_f_color_rule ( &val1, &r1, &g1, &b1, &val2, &r2, &g2, &b2, &sGrassColors, i );
+
+            snprintf ( key, sizeof(key), "COLOR_TABLE_RULE_RGB_%d", rcount-i-1 );
+            snprintf ( value, sizeof(value), "%e %e %d %d %d %d %d %d", val1, val2, r1, g1, b1, r2, g2, b2 );
+            this->SetMetadataItem( key, value );
+        }
     } else {
-	this->SetMetadataItem( "COLOR_TABLE_RULES_COUNT", "0" );
+        this->SetMetadataItem( "COLOR_TABLE_RULES_COUNT", "0" );
     }
-    
+
     this->valid = true;
 }
 
@@ -407,7 +403,7 @@ GRASSRasterBand::~GRASSRasterBand()
 
     if( hCell >= 0 )
         G_close_cell( hCell );
-    
+
     if ( pszCellName )
         G_free ( pszCellName );
 
@@ -443,10 +439,10 @@ CPLErr GRASSRasterBand::ResetReading ( struct Cell_head *sNewWindow )
 	/* Open raster */
 	G__setenv( "GISDBASE", ((GRASSDataset *)poDS)->pszGisdbase );
 	G__setenv( "LOCATION_NAME", ((GRASSDataset *)poDS)->pszLocation );
-	G__setenv( "MAPSET", pszMapset); 
+	G__setenv( "MAPSET", pszMapset);
 	G_reset_mapsets();
 	G_add_mapset_to_search_path ( pszMapset );
-	
+
 	if ( (hCell = G_open_cell_old( pszCellName, pszMapset)) < 0 ) {
 	    CPLError( CE_Warning, CPLE_AppDefined, "GRASS: Cannot open raster '%s'", pszCellName );
             this->valid = false;
@@ -454,7 +450,7 @@ CPLErr GRASSRasterBand::ResetReading ( struct Cell_head *sNewWindow )
 	}
 
 	G_copy((void *) &sOpenWindow, (void *) sNewWindow, sizeof(struct Cell_head));
-	
+
     }
     else
     {
@@ -483,21 +479,22 @@ CPLErr GRASSRasterBand::ResetReading ( struct Cell_head *sNewWindow )
 /*                                                                      */
 /************************************************************************/
 
-CPLErr GRASSRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage )
+CPLErr GRASSRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
+                                    void *pImage )
 
 {
     if ( ! this->valid ) return CE_Failure;
 
-    // Reset window because IRasterIO could be previosly called
+    // Reset window because IRasterIO could be previously called.
     if ( ResetReading ( &(((GRASSDataset *)poDS)->sCellInfo) ) != CE_None ) {
        return CE_Failure;
-    }       
-    
+    }
+
     if ( eDataType == GDT_Byte || eDataType == GDT_UInt16 ) {
         CELL  *cbuf;
 
 	cbuf = G_allocate_c_raster_buf();
-	G_get_c_raster_row ( hCell, cbuf, nBlockYOff );	
+	G_get_c_raster_row ( hCell, cbuf, nBlockYOff );
 
 	/* Reset NULLs */
 	for ( int col = 0; col < nBlockXSize; col++ ) {
@@ -505,9 +502,9 @@ CPLErr GRASSRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImag
 		cbuf[col] = (CELL) dfNoData;
 	}
 
-	GDALCopyWords ( (void *) cbuf, GDT_Int32, sizeof(CELL), 
+	GDALCopyWords ( (void *) cbuf, GDT_Int32, sizeof(CELL),
 	                pImage, eDataType, GDALGetDataTypeSize(eDataType)/8,
-			nBlockXSize );    
+			nBlockXSize );
 
 	G_free ( cbuf );
 
@@ -518,7 +515,7 @@ CPLErr GRASSRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImag
     } else if ( eDataType == GDT_Float64 ) {
 	G_get_d_raster_row ( hCell, (DCELL *) pImage, nBlockYOff );
     }
-	
+
     return CE_None;
 }
 
@@ -537,25 +534,25 @@ CPLErr GRASSRasterBand::IRasterIO ( GDALRWFlag eRWFlag,
 {
     /* GRASS library does that, we have only calculate and reset the region in map units
      * and if the region has changed, reopen the raster */
-    
+
     /* Calculate the region */
     struct Cell_head sWindow;
     struct Cell_head *psDsWindow;
-    
+
     if ( ! this->valid ) return CE_Failure;
 
     psDsWindow = &(((GRASSDataset *)poDS)->sCellInfo);
-    
-    sWindow.north = psDsWindow->north - nYOff * psDsWindow->ns_res; 
-    sWindow.south = sWindow.north - nYSize * psDsWindow->ns_res; 
-    sWindow.west = psDsWindow->west + nXOff * psDsWindow->ew_res; 
-    sWindow.east = sWindow.west + nXSize * psDsWindow->ew_res; 
+
+    sWindow.north = psDsWindow->north - nYOff * psDsWindow->ns_res;
+    sWindow.south = sWindow.north - nYSize * psDsWindow->ns_res;
+    sWindow.west = psDsWindow->west + nXOff * psDsWindow->ew_res;
+    sWindow.east = sWindow.west + nXSize * psDsWindow->ew_res;
     sWindow.proj = psDsWindow->proj;
     sWindow.zone = psDsWindow->zone;
 
     sWindow.cols = nBufXSize;
     sWindow.rows = nBufYSize;
-     
+
     /* Reset resolution */
     G_adjust_Cell_head ( &sWindow, 1, 1);
 
@@ -563,7 +560,7 @@ CPLErr GRASSRasterBand::IRasterIO ( GDALRWFlag eRWFlag,
     {
         return CE_Failure;
     }
-    
+
     /* Read Data */
     CELL  *cbuf = NULL;
     FCELL *fbuf = NULL;
@@ -578,7 +575,7 @@ CPLErr GRASSRasterBand::IRasterIO ( GDALRWFlag eRWFlag,
 	nLineSpace = nBufXSize * nPixelSpace;
 
     if ( nGRSType == CELL_TYPE && ( !nativeNulls || eBufType != GDT_Int32 || sizeof(CELL) != 4 ||
-		                    nPixelSpace != sizeof(CELL) )  ) 
+		                    nPixelSpace != sizeof(CELL) )  )
     {
 	cbuf = G_allocate_c_raster_buf();
     } else if( nGRSType == FCELL_TYPE && ( eBufType != GDT_Float32 || nPixelSpace != sizeof(FCELL) ) ) {
@@ -591,42 +588,42 @@ CPLErr GRASSRasterBand::IRasterIO ( GDALRWFlag eRWFlag,
 
     for ( int row = 0; row < nBufYSize; row++ ) {
         char *pnt = (char *)pData + row * nLineSpace;
-	
+
 	if ( nGRSType == CELL_TYPE ) {
 	    if ( direct ) {
 		G_get_c_raster_row ( hCell, (CELL *) pnt, row );
 	    } else {
 		G_get_c_raster_row ( hCell, cbuf, row );
-		
+
 		/* Reset NULLs */
 		for ( int col = 0; col < nBufXSize; col++ ) {
-		    if ( G_is_c_null_value(&(cbuf[col])) ) 
+		    if ( G_is_c_null_value(&(cbuf[col])) )
 			cbuf[col] = (CELL) dfNoData;
 		}
 
-		GDALCopyWords ( (void *) cbuf, GDT_Int32, sizeof(CELL), 
+		GDALCopyWords ( (void *) cbuf, GDT_Int32, sizeof(CELL),
 			        (void *)  pnt,  eBufType, nPixelSpace,
-				nBufXSize ); 
+				nBufXSize );
 	    }
 	} else if( nGRSType == FCELL_TYPE ) {
 	    if ( direct ) {
 		G_get_f_raster_row ( hCell, (FCELL *) pnt, row );
 	    } else {
 		G_get_f_raster_row ( hCell, fbuf, row );
-		
-		GDALCopyWords ( (void *) fbuf, GDT_Float32, sizeof(FCELL), 
+
+		GDALCopyWords ( (void *) fbuf, GDT_Float32, sizeof(FCELL),
 			        (void *)  pnt,  eBufType, nPixelSpace,
-				nBufXSize ); 
+				nBufXSize );
 	    }
 	} else if( nGRSType == DCELL_TYPE ) {
 	    if ( direct ) {
 		G_get_d_raster_row ( hCell, (DCELL *) pnt, row );
 	    } else {
 		G_get_d_raster_row ( hCell, dbuf, row );
-		
-		GDALCopyWords ( (void *) dbuf, GDT_Float64, sizeof(DCELL), 
+
+		GDALCopyWords ( (void *) dbuf, GDT_Float64, sizeof(DCELL),
 			        (void *)  pnt,  eBufType, nPixelSpace,
-				nBufXSize ); 
+				nBufXSize );
 	    }
 	}
     }
@@ -634,7 +631,7 @@ CPLErr GRASSRasterBand::IRasterIO ( GDALRWFlag eRWFlag,
     if ( cbuf ) G_free ( cbuf );
     if ( fbuf ) G_free ( fbuf );
     if ( dbuf ) G_free ( dbuf );
-    
+
     return CE_None;
 }
 
@@ -699,7 +696,7 @@ double GRASSRasterBand::GetMaximum( int *pbSuccess )
         return 4294967295.0;
     else if( eDataType == GDT_UInt16 )
         return 65535;
-    else 
+    else
         return 255;
 }
 
@@ -745,13 +742,13 @@ GRASSDataset::GRASSDataset()
 
 GRASSDataset::~GRASSDataset()
 {
-    
+
     if ( pszGisdbase )
 	G_free ( pszGisdbase );
-    
+
     if ( pszLocation )
         G_free ( pszLocation );
-    
+
     if ( pszElement )
 	G_free ( pszElement );
 
@@ -762,7 +759,7 @@ GRASSDataset::~GRASSDataset()
 /*                          GetProjectionRef()                          */
 /************************************************************************/
 
-const char *GRASSDataset::GetProjectionRef() 
+const char *GRASSDataset::GetProjectionRef()
 {
     if( pszProjection == NULL )
         return "";
@@ -774,10 +771,10 @@ const char *GRASSDataset::GetProjectionRef()
 /*                          GetGeoTransform()                           */
 /************************************************************************/
 
-CPLErr GRASSDataset::GetGeoTransform( double * padfGeoTransform ) 
+CPLErr GRASSDataset::GetGeoTransform( double * padfGeoTransform )
 {
     memcpy( padfGeoTransform, adfGeoTransform, sizeof(double) * 6 );
-    
+
     return CE_None;
 }
 
@@ -790,22 +787,22 @@ CPLErr GRASSDataset::GetGeoTransform( double * padfGeoTransform )
 /* Returns: true - OK                                                   */
 /*          false - failed                                              */
 /************************************************************************/
-bool GRASSDataset::SplitPath( char *path, char **gisdbase, char **location, 
+bool GRASSDataset::SplitPath( char *path, char **gisdbase, char **location,
 	                      char **mapset, char **element, char **name )
 {
     char *p, *ptr[5], *tmp;
     int  i = 0;
-    
+
     *gisdbase = *location = *mapset = *element = *name = NULL;
-    
-    if ( !path || strlen(path) == 0 ) 
+
+    if ( !path || strlen(path) == 0 )
 	return false;
 
     tmp = G_store ( path );
 
     while ( (p = strrchr(tmp,'/')) != NULL  && i < 4 ) {
 	*p = '\0';
-	
+
 	if ( strlen(p+1) == 0 ) /* repeated '/' */
 	    continue;
 
@@ -853,7 +850,7 @@ GDALDataset *GRASSDataset::Open( GDALOpenInfo * poOpenInfo )
         && strstr(poOpenInfo->pszFilename,"/group/") == NULL )
         return NULL;
 
-    /* Always init, if no rasters are opened G_no_gisinit resets the projection and 
+    /* Always init, if no rasters are opened G_no_gisinit resets the projection and
      * rasters in different projection may be then opened */
 
     // Don't use GISRC file and read/write GRASS variables (from location G_VAR_GISRC) to memory only.
@@ -864,7 +861,7 @@ GDALDataset *GRASSDataset::Open( GDALOpenInfo * poOpenInfo )
 
     // Set error function
     G_set_error_routine ( (GrassErrorHandler) Grass2CPLErrorHook );
-    
+
 
     // GISBASE is path to the directory where GRASS is installed,
     if ( !getenv( "GISBASE" ) ) {
@@ -889,22 +886,22 @@ GDALDataset *GRASSDataset::Open( GDALOpenInfo * poOpenInfo )
 /* -------------------------------------------------------------------- */
 /*      Check element name                                              */
 /* -------------------------------------------------------------------- */
-    if ( strcmp(pszElem,"cellhd") != 0 && strcmp(pszElem,"group") != 0 ) { 
-	G_free(pszGisdb); 
-        G_free(pszLoc); 
-        G_free(pszMapset); 
-        G_free(pszElem); 
+    if ( strcmp(pszElem,"cellhd") != 0 && strcmp(pszElem,"group") != 0 ) {
+	G_free(pszGisdb);
+        G_free(pszLoc);
+        G_free(pszMapset);
+        G_free(pszElem);
         G_free(pszName);
 	return NULL;
     }
-    
+
 /* -------------------------------------------------------------------- */
 /*      Set GRASS variables                                             */
 /* -------------------------------------------------------------------- */
 
     G__setenv( "GISDBASE", pszGisdb );
     G__setenv( "LOCATION_NAME", pszLoc );
-    G__setenv( "MAPSET", pszMapset); // group is searched only in current mapset 
+    G__setenv( "MAPSET", pszMapset); // group is searched only in current mapset
     G_reset_mapsets();
     G_add_mapset_to_search_path ( pszMapset );
 
@@ -912,7 +909,7 @@ GDALDataset *GRASSDataset::Open( GDALOpenInfo * poOpenInfo )
 /*      Check if this is a valid grass cell.                            */
 /* -------------------------------------------------------------------- */
     if ( strcmp(pszElem,"cellhd") == 0 ) {
-	
+
         if ( G_find_file2("cell", pszName, pszMapset) == NULL ) {
 	    G_free(pszGisdb); G_free(pszLoc); G_free(pszMapset); G_free(pszElem); G_free(pszName);
 	    return NULL;
@@ -932,8 +929,8 @@ GDALDataset *GRASSDataset::Open( GDALOpenInfo * poOpenInfo )
 	    G_free(pszGisdb); G_free(pszLoc); G_free(pszMapset); G_free(pszElem); G_free(pszName);
 	    return NULL;
 	}
-        
-        for( int iRef = 0; iRef < ref.nfiles; iRef++ ) 
+
+        for( int iRef = 0; iRef < ref.nfiles; iRef++ )
 	{
             papszCells = CSLAddString( papszCells, ref.file[iRef].name );
             papszMapsets = CSLAddString( papszMapsets, ref.file[iRef].mapset );
@@ -942,7 +939,7 @@ GDALDataset *GRASSDataset::Open( GDALOpenInfo * poOpenInfo )
 
         I_free_group_ref( &ref );
     }
-    
+
     G_free( pszMapset );
     G_free( pszName );
 
@@ -959,7 +956,7 @@ GDALDataset *GRASSDataset::Open( GDALOpenInfo * poOpenInfo )
     poDS->pszGisdbase = pszGisdb;
     poDS->pszLocation = pszLoc;
     poDS->pszElement = pszElem;
-    
+
 /* -------------------------------------------------------------------- */
 /*      Capture some information from the file that is of interest.     */
 /* -------------------------------------------------------------------- */
@@ -983,7 +980,7 @@ GDALDataset *GRASSDataset::Open( GDALOpenInfo * poOpenInfo )
     poDS->adfGeoTransform[3] = poDS->sCellInfo.north;
     poDS->adfGeoTransform[4] = 0.0;
     poDS->adfGeoTransform[5] = -1 * poDS->sCellInfo.ns_res;
-    
+
 /* -------------------------------------------------------------------- */
 /*      Try to get a projection definition.                             */
 /* -------------------------------------------------------------------- */
@@ -1000,7 +997,7 @@ GDALDataset *GRASSDataset::Open( GDALOpenInfo * poOpenInfo )
 /* -------------------------------------------------------------------- */
     for( int iBand = 0; papszCells[iBand] != NULL; iBand++ )
     {
-	GRASSRasterBand *rb = new GRASSRasterBand( poDS, iBand+1, papszMapsets[iBand], 
+	GRASSRasterBand *rb = new GRASSRasterBand( poDS, iBand+1, papszMapsets[iBand],
                                                                   papszCells[iBand] );
 
 	if ( !rb->valid ) {
@@ -1008,26 +1005,26 @@ GDALDataset *GRASSDataset::Open( GDALOpenInfo * poOpenInfo )
 	    delete rb;
 	    delete poDS;
 	    return NULL;
-	}
+        }
 
         poDS->SetBand( iBand+1, rb );
     }
 
     CSLDestroy(papszCells);
     CSLDestroy(papszMapsets);
-    
+
 /* -------------------------------------------------------------------- */
 /*      Confirm the requested access is supported.                      */
 /* -------------------------------------------------------------------- */
     if( poOpenInfo->eAccess == GA_Update )
     {
         delete poDS;
-        CPLError( CE_Failure, CPLE_NotSupported, 
+        CPLError( CE_Failure, CPLE_NotSupported,
                   "The GRASS driver does not support update access to existing"
                   " datasets.\n" );
         return NULL;
     }
-    
+
     return poDS;
 }
 
@@ -1037,25 +1034,20 @@ GDALDataset *GRASSDataset::Open( GDALOpenInfo * poOpenInfo )
 
 void GDALRegister_GRASS()
 {
-    GDALDriver	*poDriver;
-    
-    if (! GDAL_CHECK_VERSION("GDAL/GRASS57 driver"))
+    if( !GDAL_CHECK_VERSION( "GDAL/GRASS57 driver" ) )
         return;
 
-    if( GDALGetDriverByName( "GRASS" ) == NULL )
-    {
-        poDriver = new GDALDriver();
-        
-        poDriver->SetDescription( "GRASS" );
-        poDriver->SetMetadataItem( GDAL_DCAP_RASTER, "YES" );
-        poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
-                                   "GRASS Rasters (5.7+)" );
-        poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
-                                   "frmt_grass.html" );
-        
-        poDriver->pfnOpen = GRASSDataset::Open;
-
-        GetGDALDriverManager()->RegisterDriver( poDriver );
-    }
-}
+    if( GDALGetDriverByName( "GRASS" ) != NULL )
+        return;
+
+    GDALDriver *poDriver = new GDALDriver();
 
+    poDriver->SetDescription( "GRASS" );
+    poDriver->SetMetadataItem( GDAL_DCAP_RASTER, "YES" );
+    poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, "GRASS Rasters (5.7+)" );
+    poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, "frmt_grass.html" );
+
+    poDriver->pfnOpen = GRASSDataset::Open;
+
+    GetGDALDriverManager()->RegisterDriver( poDriver );
+}
diff --git a/ogrgrass.h b/ogrgrass.h
index 5abed15..3cda766 100644
--- a/ogrgrass.h
+++ b/ogrgrass.h
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: ogrgrass.h 28375 2015-01-30 12:06:11Z rouault $
+ * $Id: ogrgrass.h 33713 2016-03-12 17:41:57Z goatbar $
  *
  * Project:  OpenGIS Simple Features Reference Implementation
  * Purpose:  Private definitions for OGR/GRASS driver.
@@ -27,8 +27,8 @@
  * DEALINGS IN THE SOFTWARE.
  ****************************************************************************/
 
-#ifndef _OGRGRASS_H_INCLUDED
-#define _OGRGRASS_H_INCLUDED
+#ifndef OGRGRASS_H_INCLUDED
+#define OGRGRASS_H_INCLUDED
 
 #include "ogrsf_frmts.h"
 
@@ -57,6 +57,8 @@ class OGRGRASSLayer : public OGRLayer
     OGRFeatureDefn *    GetLayerDefn() { return poFeatureDefn; }
     GIntBig             GetFeatureCount( int );
     OGRErr              GetExtent(OGREnvelope *psExtent, int bForce);
+    virtual OGRErr      GetExtent(int iGeomField, OGREnvelope *psExtent, int bForce)
+                { return OGRLayer::GetExtent(iGeomField, psExtent, bForce); }
     virtual OGRSpatialReference *GetSpatialRef();
     int                 TestCapability( const char * );
 
@@ -69,12 +71,14 @@ class OGRGRASSLayer : public OGRLayer
     // Filters
     virtual OGRErr 	SetAttributeFilter( const char *query );
     virtual void 	SetSpatialFilter( OGRGeometry * poGeomIn );
+    virtual void        SetSpatialFilter( int iGeomField, OGRGeometry *poGeom )
+                { OGRLayer::SetSpatialFilter(iGeomField, poGeom); }
 
     // Write access, not supported:
     virtual OGRErr      CreateField( OGRFieldDefn *poField, int bApproxOK = TRUE );
     OGRErr              ISetFeature( OGRFeature *poFeature );
     OGRErr              ICreateFeature( OGRFeature *poFeature );
-    
+
   private:
     char		*pszName;
     OGRSpatialReference *poSRS;
@@ -83,7 +87,7 @@ class OGRGRASSLayer : public OGRLayer
 
     int			iNextId;
     int			nTotalCount;
-    int			iLayer;		// Layer number 
+    int			iLayer;		// Layer number
     int			iLayerIndex;	// Layer index (in GRASS category index)
     int			iCatField;	// Field where category (key) is stored
     int			nFields;
@@ -99,11 +103,11 @@ class OGRGRASSLayer : public OGRLayer
     dbString		*poDbString;
     dbDriver		*poDriver;
     dbCursor		*poCursor;
-    
+
     bool		bCursorOpened;	// Sequential database cursor opened
     int 		iCurrentCat;	// Current category in select cursor
 
-    struct line_pnts	*poPoints; 
+    struct line_pnts	*poPoints;
     struct line_cats	*poCats;
 
     bool		StartDbDriver ();
@@ -142,7 +146,7 @@ class OGRGRASSDataSource : public OGRDataSource
     int                 TestCapability( const char * );
 
     // Not implemented (returns NULL):
-    virtual OGRLayer    *ICreateLayer( const char *, 
+    virtual OGRLayer    *ICreateLayer( const char *,
                                       OGRSpatialReference * = NULL,
                                       OGRwkbGeometryType = wkbUnknown,
                                       char ** = NULL );
@@ -158,7 +162,7 @@ class OGRGRASSDataSource : public OGRDataSource
 
     struct Map_info 	map;
     int                 nLayers;
-    
+
     int                 bOpened;
 
     static bool SplitPath ( char *, char **, char **, char **, char ** );
@@ -171,16 +175,16 @@ class OGRGRASSDriver : public OGRSFDriver
 {
   public:
 			~OGRGRASSDriver();
-                
+
     const char 		*GetName();
     OGRDataSource 	*Open( const char *, int );
 
     int                 TestCapability( const char * );
 
     // Not implemented (return error/NULL):
-    virtual OGRDataSource *CreateDataSource( const char *pszName, 
+    virtual OGRDataSource *CreateDataSource( const char *pszName,
 	    				     char ** = NULL );
     OGRErr              DeleteDataSource( const char *pszDataSource );
 };
 
-#endif /* ndef _OGRGRASS_H_INCLUDED */
+#endif /* ndef OGRGRASS_H_INCLUDED */
diff --git a/ogrgrassdatasource.cpp b/ogrgrassdatasource.cpp
index 8677c47..e454f0a 100644
--- a/ogrgrassdatasource.cpp
+++ b/ogrgrassdatasource.cpp
@@ -1,9 +1,9 @@
 /******************************************************************************
- * $Id: ogrgrassdatasource.cpp 28534 2015-02-21 14:34:39Z rouault $
+ * $Id: ogrgrassdatasource.cpp 33713 2016-03-12 17:41:57Z goatbar $
  *
  * Project:  OpenGIS Simple Features Reference Implementation
  * Purpose:  Implements OGRGRASSDataSource class.
- * Author:   Radim Blazek, radim.blazek at gmail.com 
+ * Author:   Radim Blazek, radim.blazek at gmail.com
  *
  ******************************************************************************
  * Copyright (c) 2005, Radim Blazek <radim.blazek at gmail.com>
@@ -32,7 +32,7 @@
 #include "cpl_conv.h"
 #include "cpl_string.h"
 
-CPL_CVSID("$Id: ogrgrassdatasource.cpp 28534 2015-02-21 14:34:39Z rouault $");
+CPL_CVSID("$Id: ogrgrassdatasource.cpp 33713 2016-03-12 17:41:57Z goatbar $");
 
 #if GRASS_VERSION_MAJOR  >= 7
 #define G__setenv                G_setenv_nogisrc
@@ -73,14 +73,14 @@ OGRGRASSDataSource::~OGRGRASSDataSource()
 {
     for( int i = 0; i < nLayers; i++ )
         delete papoLayers[i];
-    
+
     if ( pszName ) CPLFree( pszName );
     if ( papoLayers ) CPLFree( papoLayers );
     if ( pszGisdbase ) G_free( pszGisdbase );
     if ( pszLocation ) G_free( pszLocation );
     if ( pszMapset ) G_free( pszMapset );
     if ( pszMap ) G_free( pszMap );
-    
+
     if (bOpened)
         Vect_close(&map);
 }
@@ -89,7 +89,7 @@ OGRGRASSDataSource::~OGRGRASSDataSource()
 /*                                Open()                                */
 /************************************************************************/
 
-#if (GRASS_VERSION_MAJOR  >= 6 && GRASS_VERSION_MINOR  >= 3) || GRASS_VERSION_MAJOR  >= 7 
+#if (GRASS_VERSION_MAJOR  >= 6 && GRASS_VERSION_MINOR  >= 3) || GRASS_VERSION_MAJOR  >= 7
 typedef int (*GrassErrorHandler)(const char *, int);
 #else
 typedef int (*GrassErrorHandler)(char *, int);
@@ -99,9 +99,9 @@ int OGRGRASSDataSource::Open( const char * pszNewName, int bUpdate,
                               int bTestOpen, int bSingleNewFileIn )
 {
     VSIStatBuf  stat;
-    
+
     CPLAssert( nLayers == 0 );
-    
+
     pszName = CPLStrdup( pszNewName ); // Released by destructor
 
 /* -------------------------------------------------------------------- */
@@ -116,7 +116,7 @@ int OGRGRASSDataSource::Open( const char * pszNewName, int bUpdate,
 	}
 	return FALSE;
     }
-    
+
 /* -------------------------------------------------------------------- */
 /*      Is the given a regular file?                                    */
 /* -------------------------------------------------------------------- */
@@ -134,18 +134,18 @@ int OGRGRASSDataSource::Open( const char * pszNewName, int bUpdate,
 /* -------------------------------------------------------------------- */
 /*      Parse datasource name                                           */
 /* -------------------------------------------------------------------- */
-    if ( !SplitPath(pszName, &pszGisdbase, &pszLocation, 
-		    &pszMapset, &pszMap) ) 
+    if ( !SplitPath(pszName, &pszGisdbase, &pszLocation,
+		    &pszMapset, &pszMap) )
     {
         if( !bTestOpen )
 	{
             CPLError( CE_Failure, CPLE_AppDefined,
-                      "%s is not GRASS datasource name, access failed.\n", 
+                      "%s is not GRASS datasource name, access failed.\n",
 		      pszName );
 	}
 	return FALSE;
     }
-			
+
     CPLDebug ( "GRASS", "Gisdbase: %s", pszGisdbase );
     CPLDebug ( "GRASS", "Location: %s", pszLocation );
     CPLDebug ( "GRASS", "Mapset: %s", pszMapset );
@@ -170,13 +170,13 @@ int OGRGRASSDataSource::Open( const char * pszNewName, int bUpdate,
         putenv( gisbaseEnv );
     }
 
-    // Don't use GISRC file and read/write GRASS variables 
+    // Don't use GISRC file and read/write GRASS variables
     // (from location G_VAR_GISRC) to memory only.
     G_set_gisrc_mode ( G_GISRC_MODE_MEMORY );
 
-    // Init GRASS libraries (required). G_no_gisinit() doesn't check 
+    // Init GRASS libraries (required). G_no_gisinit() doesn't check
     // write permissions for mapset compare to G_gisinit()
-    G_no_gisinit();  
+    G_no_gisinit();
 
     // Set error function
     G_set_error_routine ( (GrassErrorHandler) Grass2OGRErrorHook );
@@ -186,7 +186,7 @@ int OGRGRASSDataSource::Open( const char * pszNewName, int bUpdate,
 /* -------------------------------------------------------------------- */
      G__setenv( "GISDBASE", pszGisdbase );
      G__setenv( "LOCATION_NAME", pszLocation );
-     G__setenv( "MAPSET", pszMapset); 
+     G__setenv( "MAPSET", pszMapset);
      G_reset_mapsets();
      G_add_mapset_to_search_path ( pszMapset );
 
@@ -206,7 +206,7 @@ int OGRGRASSDataSource::Open( const char * pszNewName, int bUpdate,
     }
 
     CPLDebug ( "GRASS", "Num lines = %d", Vect_get_num_lines(&map) );
-    
+
 /* -------------------------------------------------------------------- */
 /*      Build a list of layers.                                         */
 /* -------------------------------------------------------------------- */
@@ -218,15 +218,15 @@ int OGRGRASSDataSource::Open( const char * pszNewName, int bUpdate,
 	OGRGRASSLayer       *poLayer;
 
         poLayer = new OGRGRASSLayer( i, &map );
-	
+
         // Add layer to data source layer list
 	papoLayers = (OGRGRASSLayer **)
 	    CPLRealloc( papoLayers,  sizeof(OGRGRASSLayer *) * (nLayers+1) );
 	papoLayers[nLayers++] = poLayer;
     }
-    
+
     bOpened = TRUE;
-    
+
     return TRUE;
 }
 
@@ -274,24 +274,24 @@ OGRLayer *OGRGRASSDataSource::GetLayer( int iLayer )
 /* Returns: true - OK                                                   */
 /*          false - failed                                              */
 /************************************************************************/
-bool OGRGRASSDataSource::SplitPath( char *path, char **gisdbase, 
+bool OGRGRASSDataSource::SplitPath( char *path, char **gisdbase,
 	                     char **location, char **mapset, char **map )
 {
     char *p, *ptr[5], *tmp;
     int  i = 0;
-    
+
     CPLDebug ( "GRASS", "OGRGRASSDataSource::SplitPath" );
-    
+
     *gisdbase = *location = *mapset = *map = NULL;
-    
-    if ( !path || strlen(path) == 0 ) 
+
+    if ( !path || strlen(path) == 0 )
 	return false;
 
     tmp = G_store ( path );
 
     while ( (p = strrchr(tmp,'/')) != NULL  && i < 5 ) {
 	*p = '\0';
-	
+
 	if ( strlen(p+1) == 0 ) /* repeated '/' */
 	    continue;
 
@@ -306,7 +306,7 @@ bool OGRGRASSDataSource::SplitPath( char *path, char **gisdbase,
 
     if ( strcmp(ptr[0],"head") != 0 || strcmp(ptr[2],"vector") != 0 ) {
        return false;
-    }       
+    }
 
     *gisdbase = G_store ( tmp );
     *location = G_store ( ptr[4] );
@@ -316,4 +316,3 @@ bool OGRGRASSDataSource::SplitPath( char *path, char **gisdbase,
     free ( tmp );
     return true;
 }
-
diff --git a/ogrgrassdriver.cpp b/ogrgrassdriver.cpp
index 999da00..f1a9521 100644
--- a/ogrgrassdriver.cpp
+++ b/ogrgrassdriver.cpp
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: ogrgrassdriver.cpp 28290 2015-01-05 13:16:48Z martinl $
+ * $Id: ogrgrassdriver.cpp 32110 2015-12-10 17:19:40Z goatbar $
  *
  * Project:  OpenGIS Simple Features Reference Implementation
  * Purpose:  Implements OGRGRASSDriver class.
@@ -31,7 +31,7 @@
 #include "cpl_conv.h"
 #include "cpl_string.h"
 
-CPL_CVSID("$Id: ogrgrassdriver.cpp 28290 2015-01-05 13:16:48Z martinl $");
+CPL_CVSID("$Id: ogrgrassdriver.cpp 32110 2015-12-10 17:19:40Z goatbar $");
 
 /************************************************************************/
 /*                          ~OGRGRASSDriver()                           */
@@ -75,9 +75,9 @@ OGRDataSource *OGRGRASSDriver::Open( const char * pszFilename,
 OGRDataSource *OGRGRASSDriver::CreateDataSource( const char * pszName,
                                                  char **papszOptions )
 {
-    CPLError( CE_Failure, CPLE_AppDefined, 
-	      "CreateDataSource is not supported by GRASS driver.\n" );
-            
+    CPLError( CE_Failure, CPLE_AppDefined,
+              "CreateDataSource is not supported by GRASS driver.\n" );
+
     return NULL;
 }
 
@@ -87,7 +87,7 @@ OGRDataSource *OGRGRASSDriver::CreateDataSource( const char * pszName,
 OGRErr OGRGRASSDriver::DeleteDataSource( const char *pszDataSource )
 {
     CPLError( CE_Failure, CPLE_AppDefined,
-	      "DeleteDataSource is not supported by GRASS driver" );
+              "DeleteDataSource is not supported by GRASS driver" );
 
     return OGRERR_FAILURE;
 }
@@ -105,23 +105,19 @@ int OGRGRASSDriver::TestCapability( const char * pszCap )
 /************************************************************************/
 void RegisterOGRGRASS()
 {
-    OGRGRASSDriver	*poDriver;
-
     if (! GDAL_CHECK_VERSION("OGR/GRASS driver"))
         return;
 
-    if( GDALGetDriverByName( "OGR_GRASS" ) == NULL )
-    {
-        poDriver = new OGRGRASSDriver();
-        
-        poDriver->SetDescription( "GRASS" );
-        poDriver->SetMetadataItem( GDAL_DCAP_VECTOR, "YES" );
-        poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
-                                   "GRASS Vectors (5.7+)" );
-        poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
-                                   "drv_grass.html" );
-
-        OGRSFDriverRegistrar::GetRegistrar()->RegisterDriver( poDriver );
-    }
+    if( GDALGetDriverByName( "OGR_GRASS" ) != NULL )
+        return;
+
+    OGRGRASSDriver *poDriver = new OGRGRASSDriver();
+
+    poDriver->SetDescription( "GRASS" );
+    poDriver->SetMetadataItem( GDAL_DCAP_VECTOR, "YES" );
+    poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, "GRASS Vectors (5.7+)" );
+    poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, "drv_grass.html" );
+
+    OGRSFDriverRegistrar::GetRegistrar()->RegisterDriver( poDriver );
 }
 
diff --git a/ogrgrasslayer.cpp b/ogrgrasslayer.cpp
index 41855b3..a2be8ea 100644
--- a/ogrgrasslayer.cpp
+++ b/ogrgrasslayer.cpp
@@ -1,9 +1,9 @@
 /******************************************************************************
- * $Id: ogrgrasslayer.cpp 28831 2015-04-01 16:46:05Z rouault $
+ * $Id: ogrgrasslayer.cpp 33713 2016-03-12 17:41:57Z goatbar $
  *
  * Project:  OpenGIS Simple Features Reference Implementation
  * Purpose:  Implements OGRGRASSLayer class.
- * Author:   Radim Blazek, radim.blazek at gmail.com 
+ * Author:   Radim Blazek, radim.blazek at gmail.com
  *
  ******************************************************************************
  * Copyright (c) 2005, Radim Blazek <radim.blazek at gmail.com>
@@ -32,7 +32,7 @@
 #include "ogrgrass.h"
 #include "cpl_conv.h"
 
-CPL_CVSID("$Id: ogrgrasslayer.cpp 28831 2015-04-01 16:46:05Z rouault $");
+CPL_CVSID("$Id: ogrgrasslayer.cpp 33713 2016-03-12 17:41:57Z goatbar $");
 
 /************************************************************************/
 /*                           OGRGRASSLayer()                            */
@@ -40,9 +40,9 @@ CPL_CVSID("$Id: ogrgrasslayer.cpp 28831 2015-04-01 16:46:05Z rouault $");
 OGRGRASSLayer::OGRGRASSLayer( int layerIndex,  struct Map_info * map )
 {
     CPLDebug ( "GRASS", "OGRGRASSLayer::OGRGRASSLayer layerIndex = %d", layerIndex );
-    
+
     iLayerIndex = layerIndex;
-    poMap = map; 
+    poMap = map;
     poSRS = NULL;
     iNextId = 0;
     poPoints = Vect_new_line_struct();
@@ -53,18 +53,18 @@ OGRGRASSLayer::OGRGRASSLayer( int layerIndex,  struct Map_info * map )
 
     iLayer = Vect_cidx_get_field_number ( poMap, iLayerIndex);
     CPLDebug ( "GRASS", "iLayer = %d", iLayer );
-    
+
     poLink = Vect_get_field ( poMap, iLayer ); // May be NULL if not defined
 
     // Layer name
     if ( poLink && poLink->name )
     {
-	pszName = CPLStrdup( poLink->name );	
+	pszName = CPLStrdup( poLink->name );
     }
     else
-    {	
-	char buf[20]; 
-	sprintf ( buf, "%d", iLayer ); 
+    {
+	char buf[20];
+	sprintf ( buf, "%d", iLayer );
 	pszName = CPLStrdup( buf );
     }
 
@@ -73,15 +73,15 @@ OGRGRASSLayer::OGRGRASSLayer( int layerIndex,  struct Map_info * map )
     nTotalCount = Vect_cidx_get_type_count(poMap,iLayer, GV_POINT|GV_LINES|GV_AREA);
     CPLDebug ( "GRASS", "nTotalCount = %d", nTotalCount );
     paFeatureIndex = (int *) CPLMalloc ( nTotalCount * sizeof(int) );
-    
+
     int n = Vect_cidx_get_type_count(poMap,iLayer, GV_POINTS|GV_LINES|GV_AREA);
     int cnt = 0;
-    for ( int i = 0; i < n; i++ ) 
+    for ( int i = 0; i < n; i++ )
     {
 	int cat,type, id;
-	
+
 	Vect_cidx_get_cat_by_index ( poMap, iLayerIndex, i, &cat, &type, &id );
-    
+
 	if ( !( type & (GV_POINT|GV_LINES|GV_AREA) ) ) continue;
 	paFeatureIndex[cnt++] = i;
     }
@@ -100,12 +100,12 @@ OGRGRASSLayer::OGRGRASSLayer( int layerIndex,  struct Map_info * map )
 	types |= type;
         CPLDebug ( "GRASS", "type = %d types = %d", type, types );
     }
-    
+
     OGRwkbGeometryType eGeomType = wkbUnknown;
-    if ( types == GV_LINE || types == GV_BOUNDARY || types == GV_LINES ) 
+    if ( types == GV_LINE || types == GV_BOUNDARY || types == GV_LINES )
     {
         eGeomType = wkbLineString;
-    } 
+    }
     else if ( types == GV_POINT )
     {
         eGeomType = wkbPoint;
@@ -129,9 +129,9 @@ OGRGRASSLayer::OGRGRASSLayer( int layerIndex,  struct Map_info * map )
     poDriver = NULL;
     bHaveAttributes = false;
     db_init_string ( poDbString );
-    if ( poLink ) 
+    if ( poLink )
     {
-	if ( StartDbDriver() ) 
+	if ( StartDbDriver() )
 	{
 	    db_set_string ( poDbString, poLink->table );
 	    dbTable *table;
@@ -139,30 +139,30 @@ OGRGRASSLayer::OGRGRASSLayer( int layerIndex,  struct Map_info * map )
 	    {
 		nFields = db_get_table_number_of_columns ( table );
 		iCatField = -1;
-		for ( int i = 0; i < nFields; i++) 
+		for ( int i = 0; i < nFields; i++)
 		{
 		    dbColumn *column = db_get_table_column ( table, i );
 		    int ctype = db_sqltype_to_Ctype ( db_get_column_sqltype(column) );
-    
+
 		    OGRFieldType ogrFtype = OFTInteger;
  	     	    switch ( ctype ) {
 			 case DB_C_TYPE_INT:
 			    ogrFtype = OFTInteger;
-			    break; 
+			    break;
 			 case DB_C_TYPE_DOUBLE:
 			    ogrFtype = OFTReal;
-			    break; 
+			    break;
 			 case DB_C_TYPE_STRING:
 			    ogrFtype = OFTString;
-			    break; 
+			    break;
 			 case DB_C_TYPE_DATETIME:
 			    ogrFtype = OFTDateTime;
-			    break; 
+			    break;
 		    }
 
-		    CPLDebug ( "GRASS", "column = %s type = %d", 
+		    CPLDebug ( "GRASS", "column = %s type = %d",
 			       db_get_column_name(column), ctype );
-		    
+
 		    OGRFieldDefn oField ( db_get_column_name(column), ogrFtype );
 		    poFeatureDefn->AddFieldDefn( &oField );
 
@@ -171,7 +171,7 @@ OGRGRASSLayer::OGRGRASSLayer( int layerIndex,  struct Map_info * map )
 			iCatField = i;
 		    }
 		}
-		if ( iCatField >= 0  ) 
+		if ( iCatField >= 0  )
 		{
     		    bHaveAttributes = true;
 		}
@@ -180,20 +180,20 @@ OGRGRASSLayer::OGRGRASSLayer( int layerIndex,  struct Map_info * map )
 		    CPLError( CE_Failure, CPLE_AppDefined, "Cannot find key field" );
 		    db_close_database_shutdown_driver ( poDriver );
 		    poDriver = NULL;
-		}
-	    }
+                }
+            }
 	    else
-	    {
-		CPLError( CE_Failure, CPLE_AppDefined, "Cannot describe table %s", 
+            {
+		CPLError( CE_Failure, CPLE_AppDefined, "Cannot describe table %s",
 			  poLink->table );
 
-	    }
+            }
 	    db_close_database_shutdown_driver ( poDriver );
 	    poDriver = NULL;
-	}
-    } 
-	
-    if ( !bHaveAttributes && iLayer > 0 ) // Because features in layer 0 have no cats  
+        }
+    }
+
+    if ( !bHaveAttributes && iLayer > 0 ) // Because features in layer 0 have no cats
     {
 	OGRFieldDefn oField("cat", OFTInteger);
 	poFeatureDefn->AddFieldDefn( &oField );
@@ -203,19 +203,19 @@ OGRGRASSLayer::OGRGRASSLayer( int layerIndex,  struct Map_info * map )
     {
         struct Key_Value *projinfo, *projunits;
 
-	// Note: we dont have to reset GISDBASE and LOCATION_NAME because 
-	// OGRGRASSLayer constructor is called from OGRGRASSDataSource::Open
-	// where those variables are set
+        // Note: we do not have to reset GISDBASE and LOCATION_NAME because
+        // OGRGRASSLayer constructor is called from OGRGRASSDataSource::Open
+        // where those variables are set
 
         projinfo = G_get_projinfo();
 	projunits = G_get_projunits();
 
 	char *srsWkt = GPJ_grass_to_wkt ( projinfo, projunits, 0, 0);
-	if ( srsWkt ) 
-	{
+        if ( srsWkt )
+        {
 	    poSRS = new OGRSpatialReference ( srsWkt );
 	    G_free ( srsWkt );
-	}
+        }
 
         G_free_key_value(projinfo);
         G_free_key_value(projunits);
@@ -227,16 +227,16 @@ OGRGRASSLayer::OGRGRASSLayer( int layerIndex,  struct Map_info * map )
 /************************************************************************/
 OGRGRASSLayer::~OGRGRASSLayer()
 {
-    if ( bCursorOpened ) 
+    if ( bCursorOpened )
     {
 	db_close_cursor ( poCursor);
     }
 
-    if ( poDriver ) 
+    if ( poDriver )
     {
 	StopDbDriver();
     }
-    
+
     if ( pszName ) CPLFree ( pszName );
     if ( poFeatureDefn )
         poFeatureDefn->Release();
@@ -244,11 +244,11 @@ OGRGRASSLayer::~OGRGRASSLayer()
         poSRS->Release();
 
     if ( pszQuery ) CPLFree ( pszQuery );
-    
+
     if ( paFeatureIndex ) CPLFree ( paFeatureIndex );
-    
+
     if ( poLink ) G_free ( poLink );
-    
+
     Vect_destroy_line_struct ( poPoints );
     Vect_destroy_cats_struct ( poCats );
 
@@ -265,23 +265,23 @@ OGRGRASSLayer::~OGRGRASSLayer()
 /************************************************************************/
 bool OGRGRASSLayer::StartDbDriver()
 {
-    CPLDebug ( "GRASS", "StartDbDriver()" ); 
+    CPLDebug ( "GRASS", "StartDbDriver()" );
 
     bCursorOpened = false;
-	    
-    if ( !poLink ) 
+
+    if ( !poLink )
     {
 	return false;
     }
     poDriver = db_start_driver_open_database ( poLink->driver, poLink->database );
-    
-    if ( poDriver == NULL) 
+
+    if ( poDriver == NULL)
     {
 	CPLError( CE_Failure, CPLE_AppDefined, "Cannot open database %s by driver %s, "
 		  "check if GISBASE environment variable is set, the driver is available "
 		  " and the database is accessible.", poLink->driver, poLink->database );
 	return false;
-    } 
+    }
     return true;
 }
 
@@ -290,32 +290,32 @@ bool OGRGRASSLayer::StartDbDriver()
 /************************************************************************/
 bool OGRGRASSLayer::StopDbDriver()
 {
-    if ( !poDriver ) 
+    if ( !poDriver )
     {
 	CPLError( CE_Failure, CPLE_AppDefined, "Driver is not started" );
 	return true; // I think that true is OK here
     }
 
-    // TODO!!!: Because of bug in GRASS library it is impossible 
-    // to stop drivers in FIFO order. Until this is fixed 
+    // TODO!!!: Because of bug in GRASS library it is impossible
+    // to stop drivers in FIFO order. Until this is fixed
     // we have to use kill
-    CPLDebug ( "GRASS", "driver PID = %d", poDriver->pid ); 
+    CPLDebug ( "GRASS", "driver PID = %d", poDriver->pid );
 
 #if defined(_WIN32) || defined(__WIN32__)
     db_close_database_shutdown_driver ( poDriver );
 #else
-    if ( kill (poDriver->pid, SIGINT) != 0 ) 
+    if ( kill (poDriver->pid, SIGINT) != 0 )
     {
-	if ( kill (poDriver->pid, SIGKILL) != 0 ) 
-	{
-	    CPLError( CE_Failure, CPLE_AppDefined, "Cannot stop database "
-		      "driver pid = %d", poDriver->pid );
-	}
+        if ( kill (poDriver->pid, SIGKILL) != 0 )
+        {
+            CPLError( CE_Failure, CPLE_AppDefined, "Cannot stop database "
+                      "driver pid = %d", poDriver->pid );
+        }
     }
 #endif
-	    
+
     bCursorOpened = false;
-    
+
     return true;
 }
 
@@ -325,25 +325,25 @@ bool OGRGRASSLayer::StopDbDriver()
 void OGRGRASSLayer::ResetReading()
 {
     iNextId = 0;
-    
+
     if ( bCursorOpened ) {
-	ResetSequentialCursor();
+        ResetSequentialCursor();
     }
 }
 
 /************************************************************************/
 /*                           SetNextByIndex()                           */
 /*                                                                      */
-/*      If we already have an FID list, we can easily resposition       */
+/*      If we already have an FID list, we can easily reposition        */
 /*      ourselves in it.                                                */
 /************************************************************************/
 OGRErr OGRGRASSLayer::SetNextByIndex( GIntBig nIndex )
 {
-    if( m_poFilterGeom != NULL || m_poAttrQuery != NULL ) 
+    if( m_poFilterGeom != NULL || m_poAttrQuery != NULL )
     {
 	iNextId = 0;
 	int count = 0;
-	
+
 	while ( true ) {
 	    if( iNextId >= nTotalCount ) break;
 	    if ( count == nIndex ) break;
@@ -352,7 +352,7 @@ OGRErr OGRGRASSLayer::SetNextByIndex( GIntBig nIndex )
 	    if( pszQuery != NULL && !paQueryMatch[iNextId] ) {
 		iNextId++;
 		continue;
-	    }
+            }
 
 	    // Spatial
 	    if( m_poFilterGeom && !paSpatialMatch[iNextId] ) {
@@ -360,7 +360,7 @@ OGRErr OGRGRASSLayer::SetNextByIndex( GIntBig nIndex )
 		continue;
 	    }
 	    count++;
-	}
+        }
     }
 
     iNextId = nIndex;
@@ -396,16 +396,16 @@ OGRErr OGRGRASSLayer::SetAttributeFilter( const char *query )
 
     if ( bHaveAttributes ) {
 
-	if ( !poDriver ) 
+	if ( !poDriver )
 	{
 	    StartDbDriver();
 	}
 
-	if ( poDriver ) 
+	if ( poDriver )
 	{
 	    if ( bCursorOpened )
 	    {
-		db_close_cursor ( poCursor ); 
+		db_close_cursor ( poCursor );
 		bCursorOpened = false;
 	    }
 	    OpenSequentialCursor();
@@ -434,9 +434,9 @@ OGRErr OGRGRASSLayer::SetAttributeFilter( const char *query )
     else
     {
 	// Use OGR to evaluate category match
-	for ( int i = 0; i < nTotalCount; i++ ) 
+	for ( int i = 0; i < nTotalCount; i++ )
 	{
-	    OGRFeature *feature = GetFeature(i); 
+	    OGRFeature *feature = GetFeature(i);
 	    CPLDebug ( "GRASS", "i = %d eval = %d", i, m_poAttrQuery->Evaluate ( feature ) );
 	    if ( m_poAttrQuery->Evaluate ( feature ) )
 	    {
@@ -444,7 +444,7 @@ OGRErr OGRGRASSLayer::SetAttributeFilter( const char *query )
 	    }
 	}
     }
-    
+
     return OGRERR_NONE;
 }
 
@@ -457,7 +457,7 @@ bool OGRGRASSLayer::SetQueryMatch()
 
     // NOTE: we don't have to call ResetSequentialCursor() first because
     // this method is called immediately after OpenSequentialCursor()
-    
+
     if ( !bCursorOpened ) {
 	CPLError( CE_Failure, CPLE_AppDefined, "Cursor is not opened.");
 	return false;
@@ -470,7 +470,7 @@ bool OGRGRASSLayer::SetQueryMatch()
     int ncats = Vect_cidx_get_num_cats_by_index ( poMap, iLayerIndex );
     dbTable *table = db_get_cursor_table ( poCursor );
     while ( true ) {
-	if( db_fetch ( poCursor, DB_NEXT, &more) != DB_OK ) 
+	if( db_fetch ( poCursor, DB_NEXT, &more) != DB_OK )
 	{
 	    CPLError( CE_Failure, CPLE_AppDefined, "Cannot fetch attributes.");
 	    return false;
@@ -483,12 +483,12 @@ bool OGRGRASSLayer::SetQueryMatch()
 
 	// NOTE: because of bug in GRASS library it is impossible to use
 	//       Vect_cidx_find_next
-	
-	// Go through category index until first record of current category 
+
+	// Go through category index until first record of current category
 	// is found or a category > current is found
 	int cidxcat, type, id;
 	while ( cidx < ncats ) {
-	    Vect_cidx_get_cat_by_index ( poMap, iLayerIndex, cidx, 
+	    Vect_cidx_get_cat_by_index ( poMap, iLayerIndex, cidx,
 		                         &cidxcat, &type, &id );
 
 	    if ( cidxcat < cat ) {
@@ -496,7 +496,7 @@ bool OGRGRASSLayer::SetQueryMatch()
 		continue;
 	    }
 	    if ( cidxcat > cat ) break; // Not found
-	    
+
 	    // We have the category we want, check type
 	    if ( !(type & (GV_POINT|GV_LINES|GV_AREA)) )
 	    {
@@ -506,11 +506,11 @@ bool OGRGRASSLayer::SetQueryMatch()
 
 	    // Both category and type match -> find feature and set it on
 	    while ( true ) {
-		if ( fidx > nTotalCount || paFeatureIndex[fidx] > cidx ) { 
+		if ( fidx > nTotalCount || paFeatureIndex[fidx] > cidx ) {
 		    // should not happen
 		    break;
 		}
-		    
+
 		if ( paFeatureIndex[fidx] == cidx ) {
 		    paQueryMatch[fidx] = 1;
 		    fidx++;
@@ -526,7 +526,7 @@ bool OGRGRASSLayer::SetQueryMatch()
 
     return true;
 }
-    
+
 /************************************************************************/
 /*                           OpenSequentialCursor                       */
 /************************************************************************/
@@ -534,7 +534,7 @@ bool OGRGRASSLayer::OpenSequentialCursor()
 {
     CPLDebug ( "GRASS", "OpenSequentialCursor: %s", pszQuery  );
 
-    if ( !poDriver ) 
+    if ( !poDriver )
     {
 	CPLError( CE_Failure, CPLE_AppDefined, "Driver not opened.");
 	return false;
@@ -559,15 +559,15 @@ bool OGRGRASSLayer::OpenSequentialCursor()
     db_append_string ( poDbString, buf);
 
     CPLDebug ( "GRASS", "Query: %s", db_get_string(poDbString) );
-    
-    if ( db_open_select_cursor ( poDriver, poDbString, 
-		poCursor, DB_SCROLL) == DB_OK ) 
+
+    if ( db_open_select_cursor ( poDriver, poDbString,
+		poCursor, DB_SCROLL) == DB_OK )
     {
 	iCurrentCat = -1;
 	bCursorOpened = true;
 	CPLDebug ( "GRASS", "num rows = %d", db_get_num_rows ( poCursor ) );
-    } 
-    else 
+    }
+    else
     {
 	CPLError( CE_Failure, CPLE_AppDefined, "Cannot open cursor.");
 	return false;
@@ -583,12 +583,12 @@ bool OGRGRASSLayer::ResetSequentialCursor()
     CPLDebug ( "GRASS", "ResetSequentialCursor" );
 
     int more;
-    if( db_fetch ( poCursor, DB_FIRST, &more) != DB_OK ) 
+    if( db_fetch ( poCursor, DB_FIRST, &more) != DB_OK )
     {
 	CPLError( CE_Failure, CPLE_AppDefined, "Cannot reset cursor.");
 	return false;
     }
-    if( db_fetch ( poCursor, DB_PREVIOUS, &more) != DB_OK ) 
+    if( db_fetch ( poCursor, DB_PREVIOUS, &more) != DB_OK )
     {
 	CPLError( CE_Failure, CPLE_AppDefined, "Cannot reset cursor.");
 	return false;
@@ -624,13 +624,13 @@ bool OGRGRASSLayer::SetSpatialMatch()
 {
     CPLDebug ( "GRASS", "SetSpatialMatch" );
 
-    if ( !paSpatialMatch ) 
+    if ( !paSpatialMatch )
     {
 	paSpatialMatch = (char *) CPLMalloc ( nTotalCount );
     }
     memset ( paSpatialMatch, 0x0, nTotalCount );
 
-    OGRGeometry *geom; 
+    OGRGeometry *geom;
     OGRLineString *lstring = new OGRLineString();
     lstring->setNumPoints ( 5 );
     geom = lstring;
@@ -639,7 +639,7 @@ bool OGRGRASSLayer::SetSpatialMatch()
 	int cidx = paFeatureIndex[i];
 
 	int cat, type, id;
-	
+
 	Vect_cidx_get_cat_by_index ( poMap, iLayerIndex, cidx, &cat, &type, &id );
 
 #if GRASS_VERSION_MAJOR  >= 7
@@ -648,7 +648,7 @@ bool OGRGRASSLayer::SetSpatialMatch()
 	BOUND_BOX box;
 #endif
 
-	switch ( type ) 
+	switch ( type )
 	{
 	    case GV_POINT:
 	    case GV_LINE:
@@ -660,7 +660,7 @@ bool OGRGRASSLayer::SetSpatialMatch()
 		Vect_get_area_box ( poMap, id, &box );
 		break;
 	}
-		
+
 	lstring->setPoint( 0, box.W, box.N, 0. );
 	lstring->setPoint( 1, box.W, box.S, 0. );
 	lstring->setPoint( 2, box.E, box.S, 0. );
@@ -675,7 +675,7 @@ bool OGRGRASSLayer::SetSpatialMatch()
     delete lstring;
     return true;
 }
-    
+
 /************************************************************************/
 /*                           GetNextFeature()                           */
 /************************************************************************/
@@ -689,14 +689,14 @@ OGRFeature *OGRGRASSLayer::GetNextFeature()
     // Get next iNextId
     while ( true ) {
 	if( iNextId >= nTotalCount ) // No more features
-	{ 
-	    // Close cursor / driver if opened 
-	    if ( bCursorOpened ) 
+	{
+	    // Close cursor / driver if opened
+	    if ( bCursorOpened )
 	    {
 	    	db_close_cursor ( poCursor);
 	    	bCursorOpened = false;
 	    }
-	    if ( poDriver ) 
+	    if ( poDriver )
 	    {
     	    	db_close_database_shutdown_driver ( poDriver );
 		poDriver = NULL;
@@ -716,7 +716,7 @@ OGRFeature *OGRGRASSLayer::GetNextFeature()
 	    iNextId++;
 	    continue;
 	}
-	
+
 	break; // Attributes & spatial filter match
     }
 
@@ -726,30 +726,30 @@ OGRFeature *OGRGRASSLayer::GetNextFeature()
     poFeature->SetGeometryDirectly( poOGR );
     poFeature->SetFID ( iNextId );
     iNextId++;
-    
+
     // Get attributes
     CPLDebug ( "GRASS", "bHaveAttributes = %d", bHaveAttributes );
-    if ( bHaveAttributes ) 
+    if ( bHaveAttributes )
     {
-	if ( !poDriver ) 
+	if ( !poDriver )
 	{
 	    StartDbDriver();
 	}
 	if ( poDriver ) {
-	    if ( !bCursorOpened ) 
+	    if ( !bCursorOpened )
 	    {
 		OpenSequentialCursor();
 	    }
-	    if ( bCursorOpened ) 
+	    if ( bCursorOpened )
 	    {
 		dbTable  *table = db_get_cursor_table ( poCursor );
-		if ( iCurrentCat < cat ) 
+		if ( iCurrentCat < cat )
 		{
 		    while ( true ) {
 			int more;
-			if( db_fetch ( poCursor, DB_NEXT, &more) != DB_OK ) 
+			if( db_fetch ( poCursor, DB_NEXT, &more) != DB_OK )
 			{
-			    CPLError( CE_Failure, CPLE_AppDefined, 
+			    CPLError( CE_Failure, CPLE_AppDefined,
 				      "Cannot fetch attributes.");
 			    break;
 			}
@@ -765,19 +765,19 @@ OGRFeature *OGRGRASSLayer::GetNextFeature()
 		if ( cat == iCurrentCat )
 		{
 		    SetAttributes ( poFeature, table );
-		} 
-		else 
+		}
+		else
 		{
 		    CPLError( CE_Failure, CPLE_AppDefined, "Attributes not found.");
 		}
 	    }
 	}
-    } 
+    }
     else if ( iLayer > 0 ) // Add category
     {
 	poFeature->SetField( 0, cat );
-    }	
-    
+    }
+
     m_nFeaturesRead++;
     return poFeature;
 }
@@ -799,47 +799,47 @@ OGRFeature *OGRGRASSLayer::GetFeature( GIntBig nFeatureId )
     poFeature->SetFID ( nFeatureId );
 
     // Get attributes
-    if ( bHaveAttributes && !poDriver ) 
+    if ( bHaveAttributes && !poDriver )
     {
 	StartDbDriver();
     }
-    if ( poDriver ) 
+    if ( poDriver )
     {
-	if ( bCursorOpened ) 
+	if ( bCursorOpened )
 	{
 	    db_close_cursor ( poCursor);
 	    bCursorOpened = false;
 	}
 	CPLDebug ( "GRASS", "Open cursor for key = %d", cat );
 	char buf[2000];
-	sprintf ( buf, "SELECT * FROM %s WHERE %s = %d", 
+	sprintf ( buf, "SELECT * FROM %s WHERE %s = %d",
 		       poLink->table, poLink->key, cat );
 	db_set_string ( poDbString, buf);
-	if ( db_open_select_cursor ( poDriver, poDbString, 
-		    poCursor, DB_SEQUENTIAL) == DB_OK ) 
+	if ( db_open_select_cursor ( poDriver, poDbString,
+		    poCursor, DB_SEQUENTIAL) == DB_OK )
 	{
 	    iCurrentCat = cat; // Not important
 	    bCursorOpened = true;
-	} 
-	else 
+	}
+	else
 	{
 	    CPLError( CE_Failure, CPLE_AppDefined, "Cannot open cursor.");
 	}
 
-	if ( bCursorOpened ) 
+	if ( bCursorOpened )
 	{
 	    int more;
-	    if( db_fetch ( poCursor, DB_NEXT, &more) != DB_OK ) 
+	    if( db_fetch ( poCursor, DB_NEXT, &more) != DB_OK )
 	    {
 		CPLError( CE_Failure, CPLE_AppDefined, "Cannot fetch attributes.");
-	    } 
-	    else 
+	    }
+	    else
 	    {
-		if ( !more ) 
+		if ( !more )
 		{
 		    CPLError( CE_Failure, CPLE_AppDefined, "Attributes not found.");
-		} 
-		else 
+		}
+		else
 		{
 	    	    dbTable *table = db_get_cursor_table ( poCursor );
 		    SetAttributes ( poFeature, table );
@@ -848,12 +848,12 @@ OGRFeature *OGRGRASSLayer::GetFeature( GIntBig nFeatureId )
 	    db_close_cursor ( poCursor);
 	    bCursorOpened = false;
 	}
-    } 
+    }
     else if ( iLayer > 0 ) // Add category
     {
 	poFeature->SetField( 0, cat );
-    }	
-    
+    }
+
     m_nFeaturesRead++;
     return poFeature;
 }
@@ -885,17 +885,17 @@ OGRGeometry *OGRGRASSLayer::GetFeatureGeometry ( long nFeatureId, int *cat )
                 poOGR = new OGRPoint( poPoints->x[0], poPoints->y[0] );
         }
         break;
-	    
+
 	case GV_LINE:
 	case GV_BOUNDARY:
         {
 	    Vect_read_line ( poMap, poPoints, poCats, id);
 	    OGRLineString *poOGRLine = new OGRLineString();
             if (bIs3D)
-                poOGRLine->setPoints( poPoints->n_points, 
+                poOGRLine->setPoints( poPoints->n_points,
                                       poPoints->x, poPoints->y, poPoints->z );
             else
-                poOGRLine->setPoints( poPoints->n_points, 
+                poOGRLine->setPoints( poPoints->n_points,
                                       poPoints->x, poPoints->y );
 
             poOGR = poOGRLine;
@@ -905,7 +905,7 @@ OGRGeometry *OGRGRASSLayer::GetFeatureGeometry ( long nFeatureId, int *cat )
 	case GV_AREA:
         {
 	    Vect_get_area_points ( poMap, id, poPoints );
-	    
+
 	    OGRPolygon 		*poOGRPoly;
 	    poOGRPoly = new OGRPolygon();
 
@@ -916,7 +916,7 @@ OGRGeometry *OGRGRASSLayer::GetFeatureGeometry ( long nFeatureId, int *cat )
                                 poPoints->x, poPoints->y, poPoints->z );
             else
                 poRing->setPoints( poPoints->n_points,
-                                poPoints->x, poPoints->y ); 
+                                poPoints->x, poPoints->y );
 
 	    poOGRPoly->addRingDirectly( poRing );
 
@@ -936,9 +936,9 @@ OGRGeometry *OGRGRASSLayer::GetFeatureGeometry ( long nFeatureId, int *cat )
 
 		poOGRPoly->addRingDirectly( poRing );
 	    }
-	    
+
 	    poOGR = poOGRPoly;
-        }   
+        }
         break;
 
 	default: // Should not happen
@@ -947,7 +947,7 @@ OGRGeometry *OGRGRASSLayer::GetFeatureGeometry ( long nFeatureId, int *cat )
 	    return NULL;
         }
     }
-	    
+
     return poOGR;
 }
 
@@ -958,7 +958,7 @@ bool OGRGRASSLayer::SetAttributes ( OGRFeature *poFeature, dbTable *table )
 {
     CPLDebug ( "GRASS", "OGRGRASSLayer::SetAttributes" );
 
-    for ( int i = 0; i < nFields; i++) 
+    for ( int i = 0; i < nFields; i++)
     {
 	dbColumn *column = db_get_table_column ( table, i );
 	dbValue *value = db_get_column_value ( column );
@@ -970,20 +970,20 @@ bool OGRGRASSLayer::SetAttributes ( OGRFeature *poFeature, dbTable *table )
 	    switch ( ctype ) {
 		case DB_C_TYPE_INT:
 		    poFeature->SetField( i, db_get_value_int ( value ));
-		    break; 
+		    break;
 		case DB_C_TYPE_DOUBLE:
 		    poFeature->SetField( i, db_get_value_double ( value ));
-		    break; 
+		    break;
 		case DB_C_TYPE_STRING:
 		    poFeature->SetField( i, db_get_value_string ( value ));
-		    break; 
+		    break;
 		case DB_C_TYPE_DATETIME:
 		    db_convert_column_value_to_string ( column, poDbString );
 		    poFeature->SetField( i, db_get_string ( poDbString ));
-		    break; 
+		    break;
 	    }
 	}
-	
+
 	db_convert_column_value_to_string ( column, poDbString );
 	//CPLDebug ( "GRASS", "val = %s", db_get_string ( poDbString ));
     }
@@ -1018,7 +1018,7 @@ GIntBig OGRGRASSLayer::GetFeatureCount( int bForce )
 {
     if( m_poFilterGeom != NULL || m_poAttrQuery != NULL )
         return OGRLayer::GetFeatureCount( bForce );
-        
+
     return nTotalCount;
 }
 
@@ -1069,7 +1069,7 @@ int OGRGRASSLayer::TestCapability( const char * pszCap )
     else if( EQUAL(pszCap,OLCFastSetNextByIndex) )
         return TRUE;
 
-    else 
+    else
         return FALSE;
 }
 
@@ -1080,7 +1080,7 @@ OGRErr OGRGRASSLayer::CreateField( OGRFieldDefn *poField, int bApproxOK )
 {
     CPLError( CE_Failure, CPLE_NotSupported,
                   "Can't create fields on a GRASS layer.\n");
-    
+
     return OGRERR_FAILURE;
 }
 
@@ -1091,4 +1091,3 @@ OGRSpatialReference *OGRGRASSLayer::GetSpatialRef()
 {
     return poSRS;
 }
-

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/gdal-grass.git



More information about the Pkg-grass-devel mailing list