Example #1
0
int GRASS_LIB_EXPORT QgsGrassGisLib::G__gisinit( const char * version, const char * programName )
{
    Q_UNUSED( version );
    // We use this function also to init our fake lib
    QgsDebugMsg( QString( "version = %1 programName = %2" ).arg( version ).arg( programName ) );

    // Init providers path
    int argc = 1;
    char **argv = new char*[1];
    argv[0] = qstrdup( programName );


    // unfortunately it seems impossible to get QGIS prefix
    // QCoreApplication::applicationDirPath() returns $GISBASE/lib on Linux
#if 0
    QDir dir( QCoreApplication::applicationDirPath() );
    dir.cdUp();
    QString prefixPath = dir.absolutePath();
#endif

    //QCoreApplication app( argc, argv ); // to init paths
    QgsApplication app( argc, argv, false ); // to init paths

    // TODO: WCS (network) fails with: "QTimer can only be used with threads started
    // with QThread" because QCoreApplication::exec() was not called, but
    // QCoreApplication::exec() goes to loop. We need to start QThread somehow.

    // QGIS_PREFIX_PATH should be loaded by QgsApplication
    //QString prefixPath = getenv( "QGIS_PREFIX_PATH" );
    //if ( prefixPath.isEmpty() )
    //{
    //  fatal( "Cannot get QGIS_PREFIX_PATH" );
    //}
    //QgsApplication::setPrefixPath( prefixPath, true );

    QgsDebugMsg( "Plugin path: " + QgsApplication::pluginPath() );
    QgsProviderRegistry::instance( QgsApplication::pluginPath() );

    QgsDebugMsg( "qgisSettingsDirPath = " + app.qgisSettingsDirPath() );

    G_set_error_routine( &errorRoutine );
    G_set_gisrc_mode( G_GISRC_MODE_MEMORY );
    G_setenv( "OVERWRITE", "1" );  // avoid checking if map exists

    G_suppress_masking();

#if GRASS_VERSION_MAJOR<6 || (GRASS_VERSION_MAJOR == 6 && GRASS_VERSION_MINOR <= 4)
    G__init_null_patterns();
#endif

    // Read projection if set
    //mCrs.createFromOgcWmsCrs( "EPSG:900913" );
    QString crsStr = getenv( "QGIS_GRASS_CRS" );

    QgsDebugMsg( "Setting CRS to " + crsStr );

    if ( !crsStr.isEmpty() )
    {
        if ( !mCrs.createFromProj4( crsStr ) )
        {
            fatal( "Cannot create CRS from QGIS_GRASS_CRS: " + crsStr );
        }
        //TODO: createFromProj4 used to save to the user database any new CRS
        // this behavior was changed in order to separate creation and saving.
        // Not sure if it necessary to save it here, should be checked by someone
        // familiar with the code (should also give a more descriptive name to the generated CRS)
        if ( mCrs.srsid() == 0 )
        {
            QString myName = QString( " * %1 (%2)" )
                             .arg( QObject::tr( "Generated CRS", "A CRS automatically generated from layer info get this prefix for description" ) )
                             .arg( mCrs.toProj4() );
            mCrs.saveAsUserCRS( myName );
        }
    }
    mDistanceArea.setSourceCrs( mCrs.srsid() );

    // Read region fron environment variable
    // QGIS_GRASS_REGION=west,south,east,north,cols,rows
#if 0
    QString regionStr = getenv( "QGIS_GRASS_REGION" );
    QStringList regionList = regionStr.split( "," );
    if ( regionList.size() != 6 )
    {
        fatal( "Cannot read region from QGIS_GRASS_REGION environment variable" );
    }

    double xMin, yMin, xMax, yMax;
    int cols, rows;
    bool xMinOk, yMinOk, xMaxOk, yMaxOk, colsOk, rowsOk;
    xMin = regionList.value( 0 ).toDouble( &xMinOk );
    yMin = regionList.value( 1 ).toDouble( &yMinOk );
    xMax = regionList.value( 2 ).toDouble( &xMaxOk );
    yMax = regionList.value( 3 ).toDouble( &yMaxOk );
    cols = regionList.value( 4 ).toInt( &colsOk );
    rows = regionList.value( 5 ).toInt( &rowsOk );

    if ( !xMinOk || !yMinOk || !xMaxOk || !yMaxOk || !colsOk || !rowsOk )
    {
        fatal( "Cannot parse QGIS_GRASS_REGION" );
    }

    struct Cell_head window;
    window.west = xMin;
    window.south = yMin;
    window.east = xMax;
    window.north = yMax;
    window.rows = rows;
    window.cols = cols;

    char* err = G_adjust_Cell_head( &window, 1, 1 );
    if ( err )
    {
        fatal( QString( err ) );
    }
    G_set_window( &window );
#endif

    QString regionStr = getenv( "GRASS_REGION" );
    if ( regionStr.isEmpty() )
    {
        fatal( "GRASS_REGION environment variable not set" );
    }

    QgsDebugMsg( "Getting region via true lib from GRASS_REGION: " +  regionStr );
    // GRASS true lib reads GRASS_REGION environment variable
    G_get_window( &mWindow );

    mExtent = QgsRectangle( mWindow.west, mWindow.south, mWindow.east, mWindow.north );
    mRows = mWindow.rows;
    mColumns = mWindow.cols;
    mXRes = mExtent.width() / mColumns;
    mYRes = mExtent.height() / mColumns;

    QgsDebugMsg( "End" );
    return 0;
}
Example #2
0
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;
}
Example #3
0
int OGRGRASSDataSource::Open( const char * pszNewName, int /*bUpdate*/,
                              int bTestOpen, int /*bSingleNewFileIn*/ )
{
    VSIStatBuf  stat;

    CPLAssert( nLayers == 0 );

    pszName = CPLStrdup( pszNewName ); // Released by destructor

/* -------------------------------------------------------------------- */
/*      Do the given path contains 'vector' and 'head'?                 */
/* -------------------------------------------------------------------- */
    if ( strstr(pszName,"vector") == NULL || strstr(pszName,"head") == NULL )
    {
        if( !bTestOpen )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                 "%s is not GRASS vector, access failed.\n", pszName );
        }
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Is the given a regular file?                                    */
/* -------------------------------------------------------------------- */
    if( CPLStat( pszName, &stat ) != 0 || !VSI_ISREG(stat.st_mode) )
    {
        if( !bTestOpen )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                 "%s is not GRASS vector, access failed.\n", pszName );
        }

        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Parse datasource name                                           */
/* -------------------------------------------------------------------- */
    if ( !SplitPath(pszName, &pszGisdbase, &pszLocation,
                    &pszMapset, &pszMap) )
    {
        if( !bTestOpen )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "%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 );
    CPLDebug ( "GRASS", "Map: %s", pszMap );

/* -------------------------------------------------------------------- */
/*      Init GRASS library                                              */
/* -------------------------------------------------------------------- */
    // GISBASE is path to the directory where GRASS is installed,
    // it is necessary because there are database drivers.
    if ( !getenv( "GISBASE" ) ) {
        static char* gisbaseEnv = NULL;
        const char *gisbase = GRASS_GISBASE;
        CPLError( CE_Warning, CPLE_AppDefined, "GRASS warning: GISBASE "
                "environment 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 );
    }

    // 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()
    G_no_gisinit();

    // Set error function
    G_set_error_routine ( (GrassErrorHandler) Grass2OGRErrorHook );

/* -------------------------------------------------------------------- */
/*      Set GRASS variables                                             */
/* -------------------------------------------------------------------- */
     G__setenv( "GISDBASE", pszGisdbase );
     G__setenv( "LOCATION_NAME", pszLocation );
     G__setenv( "MAPSET", pszMapset);
     G_reset_mapsets();
     G_add_mapset_to_search_path ( pszMapset );

/* -------------------------------------------------------------------- */
/*      Open GRASS vector map                                           */
/* -------------------------------------------------------------------- */
#if GRASS_VERSION_MAJOR  < 7
    Vect_set_fatal_error ( GV_FATAL_PRINT ); // Print error and continue
#endif
    Vect_set_open_level (2);
    int level = Vect_open_old ( &map, pszMap, pszMapset);

    if ( level < 2 ) {
        CPLError( CE_Failure, CPLE_AppDefined,
                 "Cannot open GRASS vector %s on level 2.\n", pszName );
        return FALSE;
    }

    CPLDebug ( "GRASS", "Num lines = %d", Vect_get_num_lines(&map) );

/* -------------------------------------------------------------------- */
/*      Build a list of layers.                                         */
/* -------------------------------------------------------------------- */
    int ncidx = Vect_cidx_get_num_fields ( &map );
    CPLDebug ( "GRASS", "Num layers = %d", ncidx );

    for ( int i = 0; i < ncidx; i++ ) {
        // Create the layer object
        OGRGRASSLayer *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;
}
void GRASS_EXPORT QgsGrass::init( void )
{
  // Warning!!!
  // G_set_error_routine() once called from plugin
  // is not valid in provider -> call it always

  // Set error function
  G_set_error_routine( &error_routine );

  if ( initialized )
    return;

  QSettings settings;

  // Is it active mode ?
  if ( getenv( "GISRC" ) )
  {
    active = true;
    // Store default values
    defaultGisdbase = G_gisdbase();
    defaultLocation = G_location();
    defaultMapset = G_mapset();
  }
  else
  {
    active = false;
  }

  // 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("libgrass++");

  // I think that mask should not be used in QGIS as it can only confuses people,
  // anyway, I don't think anybody is using MASK
  G_suppress_masking();

  // Set program name
  G_set_program_name( "QGIS" );

  // Require GISBASE to be set. This should point to the location of
  // the GRASS installation. The GRASS libraries use it to know
  // where to look for things.

  // Look first to see if GISBASE env var is already set.
  // This is set when QGIS is run from within GRASS
  // or when set explicitly by the user.
  // This value should always take precedence.
#if WIN32
  QString gisBase = getenv( "WINGISBASE" ) ? getenv( "WINGISBASE" ) : getenv( "GISBASE" );
  gisBase = shortPath( gisBase );
#else
  QString gisBase = getenv( "GISBASE" );
#endif
  QgsDebugMsg( QString( "GRASS gisBase from GISBASE env var is: %1" ).arg( gisBase ) );
  if ( !isValidGrassBaseDir( gisBase ) )
  {
    // Look for gisbase in QSettings
    gisBase = settings.value( "/GRASS/gisbase", "" ).toString();
    QgsDebugMsg( QString( "GRASS gisBase from QSettings is: %1" ).arg( gisBase ) );
  }

  if ( !isValidGrassBaseDir( gisBase ) )
  {
    // Erase gisbase from settings because it does not exists
    settings.setValue( "/GRASS/gisbase", "" );

#ifdef WIN32
    // Use the applicationDirPath()/grass
    gisBase = shortPath( QCoreApplication::applicationDirPath() + "/grass" );
    QgsDebugMsg( QString( "GRASS gisBase = %1" ).arg( gisBase ) );
#else
    // Use the location specified --with-grass during configure
    gisBase = GRASS_BASE;
    QgsDebugMsg( QString( "GRASS gisBase from configure is: %1" ).arg( gisBase ) );
#endif
  }

  bool userGisbase = false;
  bool valid = false;
  while ( !( valid = isValidGrassBaseDir( gisBase ) ) )
  {

    // ask user if he wants to specify GISBASE
    QMessageBox::StandardButton res = QMessageBox::warning( 0, QObject::tr( "GRASS plugin" ),
                                      QObject::tr( "QGIS couldn't find your GRASS installation.\n"
                                                   "Would you like to specify path (GISBASE) to your GRASS installation?" ),
                                      QMessageBox::Ok | QMessageBox::Cancel );

    if ( res != QMessageBox::Ok )
    {
      userGisbase = false;
      break;
    }

    // XXX Need to subclass this and add explantory message above to left side
    userGisbase = true;
    // For Mac, GISBASE folder may be inside GRASS bundle. Use Qt file dialog
    // since Mac native dialog doesn't allow user to browse inside bundles.
    gisBase = QFileDialog::getExistingDirectory(
                0, QObject::tr( "Choose GRASS installation path (GISBASE)" ), gisBase,
                QFileDialog::DontUseNativeDialog );
    if ( gisBase == QString::null )
    {
      // User pressed cancel. No GRASS for you!
      userGisbase = false;
      break;
    }
#if defined(WIN32)
    gisBase = shortPath( gisBase );
#endif
  }

  if ( !valid )
  {
    // warn user
    QMessageBox::information( 0, QObject::tr( "GRASS plugin" ),
                              QObject::tr( "GRASS data won't be available if GISBASE is not specified." ) );
  }

  if ( userGisbase )
  {
    settings.setValue( "/GRASS/gisbase", gisBase );
  }

  QgsDebugMsg( QString( "Valid GRASS gisBase is: %1" ).arg( gisBase ) );
  putEnv( "GISBASE", gisBase );

  // Add path to GRASS modules
#ifdef WIN32
  QString sep = ";";
#else
  QString sep = ":";
#endif
  QString path = gisBase + "/bin";
  path.append( sep + gisBase + "/scripts" );
  path.append( sep +  QgsApplication::pkgDataPath() + "/grass/scripts/" );

  // On windows the GRASS libraries are in
  // QgsApplication::prefixPath(), we have to add them
  // to PATH to enable running of GRASS modules
  // and database drivers
#ifdef WIN32
  // It seems that QgsApplication::prefixPath()
  // is not initialized at this point
  path.append( sep + shortPath( QCoreApplication::applicationDirPath() ) );

  // Add path to MSYS bin
  // Warning: MSYS sh.exe will translate this path to '/bin'
  if ( QFileInfo( QCoreApplication::applicationDirPath() + "/msys/bin/" ).isDir() )
    path.append( sep + shortPath( QCoreApplication::applicationDirPath() + "/msys/bin/" ) );
#endif

  QString p = getenv( "PATH" );
  path.append( sep + p );

  QgsDebugMsg( QString( "set PATH: %1" ).arg( path ) );
  putEnv( "PATH", path );

  // Set PYTHONPATH
  QString pythonpath = gisBase + "/etc/python";
  QString pp = getenv( "PYTHONPATH" );
  pythonpath.append( sep + pp );
  QgsDebugMsg( QString( "set PYTHONPATH: %1" ).arg( pythonpath ) );
  putEnv( "PYTHONPATH", pythonpath );

  // Set GRASS_PAGER if not set, it is necessary for some
  // modules printing to terminal, e.g. g.list
  // We use 'cat' because 'more' is not present in MSYS (Win)
  // and it doesn't work well in built in shell (Unix/Mac)
  // and 'less' is not user friendly (for example user must press
  // 'q' to quit which is definitely difficult for normal user)
  // Also scroling can be don in scrollable window in both
  // MSYS terminal and built in shell.
  if ( !getenv( "GRASS_PAGER" ) )
  {
    QString pager;
    QStringList pagers;
    //pagers << "more" << "less" << "cat"; // se notes above
    pagers << "cat";

    for ( int i = 0; i < pagers.size(); i++ )
    {
      int state;

      QProcess p;
      p.start( pagers.at( i ) );
      p.waitForStarted();
      state = p.state();
      p.write( "\004" ); // Ctrl-D
      p.closeWriteChannel();
      p.waitForFinished( 1000 );
      p.kill();

      if ( state == QProcess::Running )
      {
        pager = pagers.at( i );
        break;
      }
    }

    if ( pager.length() > 0 )
    {
      putEnv( "GRASS_PAGER", pager );
    }
  }

  initialized = 1;
}
Example #5
0
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;
}
Example #6
0
int main(int argc, char *argv[])
{
    char name[GNAME_MAX], mapset[GMAPSET_MAX], xmapset[GMAPSET_MAX];
    struct Cell_head cellhd;
    struct GModule *module;
    struct Option *grp;

    /* must run in a term window */
    G_putenv("GRASS_UI_TERM", "1");

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("imagery"));
    G_add_keyword(_("geometry"));
    module->description =
	_("Mark ground control points on image to be rectified.");

    grp = G_define_option();
    grp->key = "group";
    grp->type = TYPE_STRING;
    grp->required = YES;
    grp->gisprompt = "old,group,group";
    grp->description = _("Name of imagery group to be registered");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);


    Rast_suppress_masking();	/* need to do this for target location */

    interrupt_char = G_intr_char();
    tempfile1 = G_tempfile();
    tempfile2 = G_tempfile();
    cell_list = G_tempfile();
    vect_list = G_tempfile();
    group_list = G_tempfile();
    digit_points = G_tempfile();
    digit_results = G_tempfile();

    if (R_open_driver() != 0)
	G_fatal_error(_("No graphics device selected"));


    /* parse group name */
    /* only enforce local-mapset-only due to I_get_group_ref() not liking "@mapset" */
    if (G_name_is_fully_qualified(grp->answer, group.name, xmapset)) {
	if (0 != strcmp(G_mapset(), xmapset))
	    G_fatal_error(_("[%s] Only local groups may be used"),
			  grp->answer);
    }
    else {
	strncpy(group.name, grp->answer, GNAME_MAX - 1);
	group.name[GNAME_MAX - 1] = '\0';	/* strncpy() doesn't null terminate on overflow */
    }

    if (!I_get_group_ref(group.name, &group.ref))
	G_fatal_error(_("Group [%s] contains no maps, run i.group"),
		      group.name);

    if (group.ref.nfiles <= 0)
	G_fatal_error(_("Group [%s] contains no maps, run i.group"),
		      group.name);

    /* write group files to group list file */
    prepare_group_list();

    /* get target info and environment */
    get_target();
    find_target_files();

    /* read group control points, if any */
    G_suppress_warnings(1);
    if (!I_get_control_points(group.name, &group.points))
	group.points.count = 0;
    G_suppress_warnings(0);

    /* determine transformation equation */
    Compute_equation();


    signal(SIGINT, SIG_IGN);
    /*  signal (SIGQUIT, SIG_IGN); */

    Init_graphics();
    display_title(VIEW_MAP1);
    select_target_env();
    display_title(VIEW_MAP2);
    select_current_env();

    Begin_curses();
    G_set_error_routine(error);

    /*
       #ifdef SIGTSTP
       signal (SIGTSTP, SIG_IGN);
       #endif
     */


    /* ask user for group file to be displayed */
    do {
	if (!choose_groupfile(name, mapset))
	    quit(0);
	/* display this file in "map1" */
    }
    while (!G_find_raster2(name, mapset));
    Rast_get_cellhd(name, mapset, &cellhd);
    G_adjust_window_to_box(&cellhd, &VIEW_MAP1->cell.head, VIEW_MAP1->nrows,
			   VIEW_MAP1->ncols);
    Configure_view(VIEW_MAP1, name, mapset, cellhd.ns_res, cellhd.ew_res);

    drawcell(VIEW_MAP1);
    display_points(1);

    Curses_clear_window(PROMPT_WINDOW);

    /* determine initial input method. */
    setup_digitizer();
    if (use_digitizer) {
	from_digitizer = 1;
	from_keyboard = 0;
	from_flag = 1;
    }

    /* go do the work */
    driver();

    quit(0);
}
Example #7
0
int main(int argc, char *argv[])
{
    char mapset[GMAPSET_MAX];
    char name[GNAME_MAX];
    char *camera;

    struct GModule *module;
    struct Option *group_opt, *map_opt, *target_map_opt;
    struct Cell_head cellhd;
    int ok;
    int nfiles;

    /* must run in a term window */
    G_putenv("GRASS_UI_TERM", "1");

    G_gisinit(argv[0]);

    module = G_define_module();
    module->keywords = _("imagery, orthorectify");
    module->description = _("Creates control points on an image "
			    "to be ortho-rectified.");

    group_opt = G_define_option();
    group_opt->key = "group";
    group_opt->type = TYPE_STRING;
    group_opt->required = YES;
    group_opt->multiple = NO;
    group_opt->description = _("Name of imagery group");

    map_opt = G_define_standard_option(G_OPT_R_MAP);
    map_opt->required = NO;
    map_opt->description = _("Name of image to be rectified which will "
			     "be initially drawn on screen");

    target_map_opt = G_define_standard_option(G_OPT_R_MAP);
    target_map_opt->key = "target";
    target_map_opt->required = NO;
    target_map_opt->description = _("Name of a map from target mapset which "
				    "will be initially drawn on screen");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);


    G_suppress_masking();	/* need to do this for target location */

    camera = (char *)G_malloc(40 * sizeof(char));
    strcpy(name, group_opt->answer);

    interrupt_char = G_intr_char();
    tempfile1 = G_tempfile();
    tempfile2 = G_tempfile();
    tempfile_dot = G_tempfile();
    tempfile_dot2 = G_tempfile();
    tempfile_win = G_tempfile();
    tempfile_win2 = G_tempfile();
    cell_list = G_tempfile();
    vect_list = G_tempfile();
    group_list = G_tempfile();
    digit_points = G_tempfile();

    if (R_open_driver() != 0)
	G_fatal_error(_("No graphics device selected"));

    /* get group ref */
    strcpy(group.name, name);
    if (!I_find_group(group.name))
	G_fatal_error(_("Group [%s] not found"), group.name);

    /* get the group ref */
    I_get_group_ref(group.name, &group.group_ref);
    nfiles = group.group_ref.nfiles;

    /* write block files to block list file */
    prepare_group_list();

    /** look for camera info  for this group**/
    G_suppress_warnings(1);
    if (!I_get_group_camera(group.name, camera))
	G_fatal_error(_("No camera reference file selected for group [%s]"),
		group.name);

    if (!I_get_cam_info(camera, &group.camera_ref))
	G_fatal_error(_("Bad format in camera file for group [%s]"),
			group.name);

    G_suppress_warnings(0);

    /* get initial camera exposure station, if any */
    if (!(ok = I_find_initial(group.name)))
	G_warning(_("No initial camera exposure station for group [%s]"),
		group.name);

    if (ok && (!I_get_init_info(group.name, &group.camera_exp)) )
	G_warning(_("Bad format in initial camera exposure station for group [%s]"),
		  group.name);

    /* get target info and environment */
    G_suppress_warnings(1);
    get_target();
    find_target_files();
    G_suppress_warnings(0);

    /* read group reference points, if any */
    G_suppress_warnings(1);
    if (!I_get_ref_points(group.name, &group.photo_points)) {
	G_suppress_warnings(0);
	if (group.photo_points.count == 0)
	    G_fatal_error(_("No photo points for group [%s]"), group.name);
	else if (group.ref_equation_stat == 0)
	    G_fatal_error(_("Poorly placed photo points for group [%s]"),
			  group.name);
    }
    G_suppress_warnings(0);

    /* determine transformation equation */
    Compute_ref_equation();

    /* read group control points, format: image x,y,cfl; target E,N,Z */
    G_suppress_warnings(1);
    if (!I_get_con_points(group.name, &group.control_points))
	group.control_points.count = 0;
    G_suppress_warnings(0);

    /* compute image coordinates of photo control points */

    /********
    I_convert_con_points (group.name, &group.control_points, 
			 &group.control_points, group.E12, group.N12);
    ********/

    /* determine transformation equation */
    G_message(_("Computing equations ..."));
    if (group.control_points.count > 0)
	Compute_ortho_equation();


    /*   signal (SIGINT, SIG_IGN); */
    /*   signal (SIGQUIT, SIG_IGN); */

    select_current_env();
    Init_graphics();
    display_title(VIEW_MAP1);
    select_target_env();
    display_title(VIEW_MAP2);
    select_current_env();

    Begin_curses();
    G_set_error_routine(error);

    /*
       #ifdef SIGTSTP
       signal (SIGTSTP, SIG_IGN);
       #endif
     */

    /* Set image to be rectified */
    if (map_opt->answer) {
	char *ms;

	ms = G_find_cell(map_opt->answer, "");
	if (ms == NULL) {
	    G_fatal_error(_("Raster map <%s> not found"), map_opt->answer);
	}
	strcpy(name, map_opt->answer);
	strcpy(mapset, ms);
	if (G_get_cellhd(name, mapset, &cellhd) < 0) {
	    G_fatal_error(_("Unable to read raster header of <%s>"), map_opt->answer);
	}
    }
    else {
	/* ask user for group file to be displayed */
	do {
	    if (!choose_groupfile(name, mapset))
		quit(EXIT_SUCCESS);
	    /* display this file in "map1" */
	} while (G_get_cellhd(name, mapset, &cellhd) < 0);
    }

    G_adjust_window_to_box(&cellhd, &VIEW_MAP1->cell.head, VIEW_MAP1->nrows,
			   VIEW_MAP1->ncols);
    Configure_view(VIEW_MAP1, name, mapset, cellhd.ns_res, cellhd.ew_res);

    drawcell(VIEW_MAP1);

    /* Set target map if specified */
    if (target_map_opt->answer) {
	char *ms;

	select_target_env();
	ms = G_find_cell(target_map_opt->answer, "");
	if (ms == NULL) {
	    G_fatal_error(_("Raster map <%s> not found"),
			  target_map_opt->answer);
	}
	strcpy(name, target_map_opt->answer);
	strcpy(mapset, ms);
	if (G_get_cellhd(name, mapset, &cellhd) < 0) {
	    G_fatal_error(_("Unable to read raster header of <%s>"),
			  target_map_opt->answer);
	}

	G_adjust_window_to_box(&cellhd, &VIEW_MAP2->cell.head,
			       VIEW_MAP2->nrows, VIEW_MAP2->ncols);
	Configure_view(VIEW_MAP2, name, mapset, cellhd.ns_res, cellhd.ew_res);

	drawcell(VIEW_MAP2);

	from_flag = 1;
	from_keyboard = 0;
	from_screen = 1;
    }

    display_conz_points(1);

    Curses_clear_window(PROMPT_WINDOW);

    /* determine initial input method. */
    setup_digitizer();
    if (use_digitizer) {
	from_digitizer = 1;
	from_keyboard = 0;
	from_flag = 1;
    }

    /* go do the work */
    driver();

    quit(EXIT_SUCCESS);
}