GDALDataset *GRASSDataset::Open( GDALOpenInfo * poOpenInfo ) { char *pszGisdb = NULL, *pszLoc = NULL; char *pszMapset = NULL, *pszElem = NULL, *pszName = NULL; char **papszCells = NULL; char **papszMapsets = NULL; /* -------------------------------------------------------------------- */ /* Does this even look like a grass file path? */ /* -------------------------------------------------------------------- */ if( strstr(poOpenInfo->pszFilename,"/cellhd/") == NULL && strstr(poOpenInfo->pszFilename,"/group/") == NULL ) return NULL; /* 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. G_set_gisrc_mode ( G_GISRC_MODE_MEMORY ); // Init GRASS libraries (required) G_no_gisinit(); // Doesn't check write permissions for mapset compare to G_gisinit // Set error function G_set_error_routine ( (GrassErrorHandler) Grass2CPLErrorHook ); // GISBASE is path to the directory where GRASS is installed, if ( !getenv( "GISBASE" ) ) { static char* gisbaseEnv = NULL; const char *gisbase = GRASS_GISBASE; CPLError( CE_Warning, CPLE_AppDefined, "GRASS warning: GISBASE " "enviroment variable was not set, using:\n%s", gisbase ); char buf[2000]; snprintf ( buf, sizeof(buf), "GISBASE=%s", gisbase ); buf[sizeof(buf)-1] = '\0'; CPLFree(gisbaseEnv); gisbaseEnv = CPLStrdup ( buf ); putenv( gisbaseEnv ); } if ( !SplitPath( poOpenInfo->pszFilename, &pszGisdb, &pszLoc, &pszMapset, &pszElem, &pszName) ) { return NULL; } /* -------------------------------------------------------------------- */ /* Check element name */ /* -------------------------------------------------------------------- */ 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_reset_mapsets(); G_add_mapset_to_search_path ( pszMapset ); /* -------------------------------------------------------------------- */ /* 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; } papszMapsets = CSLAddString( papszMapsets, pszMapset ); papszCells = CSLAddString( papszCells, pszName ); } /* -------------------------------------------------------------------- */ /* Check if this is a valid GRASS imagery group. */ /* -------------------------------------------------------------------- */ else { struct Ref ref; I_init_group_ref( &ref ); if ( I_get_group_ref( pszName, &ref ) == 0 ) { 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++ ) { papszCells = CSLAddString( papszCells, ref.file[iRef].name ); papszMapsets = CSLAddString( papszMapsets, ref.file[iRef].mapset ); G_add_mapset_to_search_path ( ref.file[iRef].mapset ); } I_free_group_ref( &ref ); } G_free( pszMapset ); G_free( pszName ); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ GRASSDataset *poDS; poDS = new GRASSDataset(); /* notdef: should only allow read access to an existing cell, right? */ poDS->eAccess = poOpenInfo->eAccess; poDS->pszGisdbase = pszGisdb; poDS->pszLocation = pszLoc; poDS->pszElement = pszElem; /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ #if GRASS_VERSION_MAJOR >= 7 Rast_get_cellhd( papszCells[0], papszMapsets[0], &(poDS->sCellInfo) ); #else if( G_get_cellhd( papszCells[0], papszMapsets[0], &(poDS->sCellInfo) ) != 0 ) { CPLError( CE_Warning, CPLE_AppDefined, "GRASS: Cannot open raster header"); delete poDS; return NULL; } #endif poDS->nRasterXSize = poDS->sCellInfo.cols; poDS->nRasterYSize = poDS->sCellInfo.rows; poDS->adfGeoTransform[0] = poDS->sCellInfo.west; poDS->adfGeoTransform[1] = poDS->sCellInfo.ew_res; poDS->adfGeoTransform[2] = 0.0; 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. */ /* -------------------------------------------------------------------- */ struct Key_Value *projinfo, *projunits; projinfo = G_get_projinfo(); projunits = G_get_projunits(); poDS->pszProjection = GPJ_grass_to_wkt ( projinfo, projunits, 0, 0); if (projinfo) G_free_key_value(projinfo); if (projunits) G_free_key_value(projunits); /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ for( int iBand = 0; papszCells[iBand] != NULL; iBand++ ) { GRASSRasterBand *rb = new GRASSRasterBand( poDS, iBand+1, papszMapsets[iBand], papszCells[iBand] ); if ( !rb->valid ) { CPLError( CE_Warning, CPLE_AppDefined, "GRASS: Cannot open raster band %d", iBand); 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, "The GRASS driver does not support update access to existing" " datasets.\n" ); return NULL; } return poDS; }
GDALDataset *GRASSDataset::Open( GDALOpenInfo * poOpenInfo ) { static int bDoneGISInit = FALSE; char *pszMapset = NULL, *pszCell = NULL; char **papszCells = NULL; char **papszMapsets = NULL; if( !bDoneGISInit ) { G_set_error_routine( (GrassErrorHandler) Grass2CPLErrorHook ); G_gisinit_2( "GDAL", NULL, NULL, NULL ); } /* -------------------------------------------------------------------- */ /* Check if this is a valid grass cell. */ /* -------------------------------------------------------------------- */ if( G_check_cell( poOpenInfo->pszFilename, &pszMapset, &pszCell ) ) { papszCells = CSLAddString( papszCells, pszCell ); papszMapsets = CSLAddString( papszMapsets, pszMapset ); G_free( pszMapset ); G_free( pszCell ); } /* -------------------------------------------------------------------- */ /* Check if this is a valid GRASS imagery group. */ /* -------------------------------------------------------------------- */ else if( I_check_group( poOpenInfo->pszFilename, &pszMapset, &pszCell ) ) { struct Ref ref; I_init_group_ref( &ref ); I_get_group_ref( pszCell, &ref ); for( int iRef = 0; iRef < ref.nfiles; iRef++ ) { papszCells = CSLAddString( papszCells, ref.file[iRef].name ); papszMapsets = CSLAddString( papszMapsets, ref.file[iRef].mapset ); } I_free_group_ref( &ref ); G_free( pszMapset ); G_free( pszCell ); } else return NULL; /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ GRASSDataset *poDS; poDS = new GRASSDataset(); /* notdef: should only allow read access to an existing cell, right? */ poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ struct Cell_head sCellInfo; if( G_get_cellhd( papszCells[0], papszMapsets[0], &sCellInfo ) != 0 ) { /* notdef: report failure. */ return NULL; } poDS->nRasterXSize = sCellInfo.cols; poDS->nRasterYSize = sCellInfo.rows; G_set_window( &sCellInfo ); poDS->adfGeoTransform[0] = sCellInfo.west; poDS->adfGeoTransform[1] = sCellInfo.ew_res; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = sCellInfo.north; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = -1 * sCellInfo.ns_res; /* -------------------------------------------------------------------- */ /* Try to get a projection definition. */ /* -------------------------------------------------------------------- */ char *pszProj4; pszProj4 = G_get_cell_as_proj4( papszCells[0], papszMapsets[0] ); if( pszProj4 != NULL ) { OGRSpatialReference oSRS; if( oSRS.importFromProj4( pszProj4 ) == OGRERR_NONE ) { oSRS.exportToWkt( &(poDS->pszProjection) ); } G_free( pszProj4 ); } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ for( int iBand = 0; papszCells[iBand] != NULL; iBand++ ) { poDS->SetBand( iBand+1, new GRASSRasterBand( poDS, iBand+1, papszMapsets[iBand], papszCells[iBand] ) ); } /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { delete poDS; CPLError( CE_Failure, CPLE_NotSupported, "The GRASS driver does not support update access to existing" " datasets.\n" ); return NULL; } return poDS; }