Пример #1
0
void R_G_init(char *name) {

/*	G_set_error_routine(R_handler);
	G_sleep_on_error(0); */
       if (G_set_program_name(name) != 0)
	      G_fatal_error("R_G_init: error setting name");
	G_no_gisinit();
}
Пример #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;
}
Пример #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;
}
Пример #4
0
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;
}
Пример #5
0
int main(int argc, char *argv[])
{
    struct Flag *tostdout, *overwrite;
    struct Option *extradirs;
    struct GModule *module;

    FILE *outstream;
    char *fontcapfile;
    struct stat status;
    int i;

    G_set_program_name(argv[0]);
    G_no_gisinit();
    G_set_gisrc_mode(G_GISRC_MODE_MEMORY);

    module = G_define_module();
    module->keywords = "general";
    module->description =
	"Generates the font configuration file by scanning various directories "
	"for fonts";

    overwrite = G_define_flag();
    overwrite->key = 'o';
    overwrite->description =
	"Overwrite font configuration file if already existing";

    tostdout = G_define_flag();
    tostdout->key = 's';
    tostdout->description =
	"Write font configuration file to standard output instead of "
	"$GISBASE/etc";

    extradirs = G_define_option();
    extradirs->key = "extradirs";
    extradirs->type = TYPE_STRING;
    extradirs->required = NO;
    extradirs->description =
	"Comma-separated list of extra directories to scan for "
	"Freetype-compatible fonts as well as the defaults (see documentation)";

    if (argc > 1 && G_parser(argc, argv))
	exit(EXIT_FAILURE);

    if (!tostdout->answer) {
	const char *gisbase = G_gisbase();
	const char *alt_file = getenv("GRASS_FONT_CAP");

	if (alt_file)
	    fontcapfile = G_store(alt_file);
	else
	    G_asprintf(&fontcapfile, "%s/etc/fontcap", gisbase);

	if (!stat(fontcapfile, &status)) {	/* File exists? */
	    if (!overwrite->answer)
		G_fatal_error
		    ("Fontcap file %s already exists; use -%c flag if you "
		     "wish to overwrite it", fontcapfile, overwrite->key);
	}
    }

    searchdirs = NULL;
    numsearchdirs = 0;

    /* Prepare list of directories to search */
    if (extradirs->answer) {
#ifndef HAVE_FT2BUILD_H
	G_warning("This GRASS installation was compiled without Freetype support, extradirs parameter ignored");
#endif
	char *str = G_store(extradirs->answer);

	while ((str = strtok(str, ","))) {
	    add_search_dir(str);
	    str = NULL;
	}
    }
    i = -1;
    while (standarddirs[++i])
	add_search_dir(standarddirs[i]);

    totalfonts = maxfonts = 0;
    fontcap = NULL;

    find_stroke_fonts();
    find_freetype_fonts();

    qsort(fontcap, totalfonts, sizeof(struct GFONT_CAP), compare_fonts);

    if (tostdout->answer)
	outstream = stdout;
    else {
	outstream = fopen(fontcapfile, "w");
	if (outstream == NULL)
	    G_fatal_error("Cannot open %s for writing: %s", fontcapfile,
			  strerror(errno));
    }

    for (i = 0; i < totalfonts; i++)
	fprintf(outstream, "%s|%s|%d|%s|%d|%s|\n", fontcap[i].name,
		fontcap[i].longname, fontcap[i].type, fontcap[i].path,
		fontcap[i].index, fontcap[i].encoding);

    fclose(outstream);

    exit(EXIT_SUCCESS);

}
Пример #6
0
int main(int argc, char *argv[])
{
    struct Flag *printinfo,	/* Print contents of PROJ_INFO & PROJ_UNITS */
               *shellinfo,             /* Print in shell script style              */
               *printproj4,		/* Print projection in PROJ.4 format        */
               *datuminfo,		/* Check if datum information is present    */
               *create,		/* Create new projection files              */
#ifdef HAVE_OGR
               *printwkt,		/* Print projection in WKT format           */
               *esristyle,		/* Use ESRI-style WKT format                */
#endif
               *dontprettify,		/* Print 'flat' output (no linebreaks)      */
               *forcedatumtrans;	/* Force override of datumtrans parameters  */

    struct Option *location,	/* Name of new location to create           */
#ifdef HAVE_OGR
               *inepsg,		/* EPSG projection code                     */
               *inwkt,			/* Input file with projection in WKT format */
               *inproj4,		/* Projection in PROJ.4 format              */
               *ingeo,			/* Input geo-referenced file readable by
				 * GDAL or OGR                              */
#endif
               *dtrans;		/* index to datum transform option          */
    struct GModule *module;

    int formats;

    G_set_program_name(argv[0]);
    G_no_gisinit();		/* We don't call G_gisinit() here because it validates the
				 * mapset, whereas this module may legitmately be used
				 * (to create a new location) when none exists */

    module = G_define_module();
    G_add_keyword(_("general"));
    G_add_keyword(_("projection"));
    G_add_keyword(_("create location"));
#ifdef HAVE_OGR
    module->label =
        _("Prints and manipulates GRASS projection information files "
          "(in various co-ordinate system descriptions).");
    module->description =
        _("Can also be used to create new GRASS locations.");
#else
    module->description =
        _("Prints and manipulates GRASS projection information files.");
#endif

    printinfo = G_define_flag();
    printinfo->key = 'p';
    printinfo->guisection = _("Print");
    printinfo->description =
        _("Print projection information in conventional GRASS format");

    shellinfo = G_define_flag();
    shellinfo->key = 'g';
    shellinfo->guisection = _("Print");
    shellinfo->description =
        _("Print projection information in shell script style");

    datuminfo = G_define_flag();
    datuminfo->key = 'd';
    datuminfo->guisection = _("Print");
    datuminfo->description =
        _("Verify datum information and print transformation parameters");

    printproj4 = G_define_flag();
    printproj4->key = 'j';
    printproj4->guisection = _("Print");
    printproj4->description =
        _("Print projection information in PROJ.4 format");

    dontprettify = G_define_flag();
    dontprettify->key = 'f';
    dontprettify->guisection = _("Print");
    dontprettify->description =
        _("Print 'flat' output with no linebreaks (applies to "
#ifdef HAVE_OGR
          "WKT and "
#endif
          "PROJ.4 output)");

#ifdef HAVE_OGR
    printwkt = G_define_flag();
    printwkt->key = 'w';
    printwkt->guisection = _("Print");
    printwkt->description = _("Print projection information in WKT format");

    esristyle = G_define_flag();
    esristyle->key = 'e';
    esristyle->guisection = _("Print");
    esristyle->description =
        _("Use ESRI-style format (applies to WKT output only)");

    ingeo = G_define_option();
    ingeo->key = "georef";
    ingeo->type = TYPE_STRING;
    ingeo->key_desc = "file";
    ingeo->required = NO;
    ingeo->guisection = _("Specification");
    ingeo->description = _("Name of georeferenced data file to read projection "
                           "information from");

    inwkt = G_define_option();
    inwkt->key = "wkt";
    inwkt->type = TYPE_STRING;
    inwkt->key_desc = "file";
    inwkt->required = NO;
    inwkt->guisection = _("Specification");
    inwkt->label = _("Name of ASCII file containing a WKT projection "
                     "description");
    inwkt->description = _("'-' for standard input");

    inproj4 = G_define_option();
    inproj4->key = "proj4";
    inproj4->type = TYPE_STRING;
    inproj4->key_desc = "params";
    inproj4->required = NO;
    inproj4->guisection = _("Specification");
    inproj4->label = _("PROJ.4 projection description");
    inproj4->description = _("'-' for standard input");

    inepsg = G_define_option();
    inepsg->key = "epsg";
    inepsg->type = TYPE_INTEGER;
    inepsg->required = NO;
    inepsg->options = "1-1000000";
    inepsg->guisection = _("Specification");
    inepsg->description = _("EPSG projection code");
#endif

    dtrans = G_define_option();
    dtrans->key = "datumtrans";
    dtrans->type = TYPE_INTEGER;
    dtrans->required = NO;
    dtrans->options = "-1-100";
    dtrans->answer = "0";
    dtrans->guisection = _("Datum");
    dtrans->label = _("Index number of datum transform parameters");
    dtrans->description = _("\"0\" for unspecified or \"-1\" to list and exit");

    forcedatumtrans = G_define_flag();
    forcedatumtrans->key = 't';
    forcedatumtrans->guisection = _("Datum");
    forcedatumtrans->description =
        _("Force override of datum transformation information in input "
          "co-ordinate system");

    create = G_define_flag();
    create->key = 'c';
    create->guisection = _("Modify");
    create->description = _("Create new projection files (modifies current "
                            "location)");

    location = G_define_option();
    location->key = "location";
    location->type = TYPE_STRING;
    location->key_desc = "name";
    location->required = NO;
    location->guisection = _("Create");
    location->description = _("Name of new location to create");

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


    /* Initialisation & Validation */

#ifdef HAVE_OGR
    /* -e implies -w */
    if (esristyle->answer && !printwkt->answer)
        printwkt->answer = 1;

    formats = ((ingeo->answer ? 1 : 0) + (inwkt->answer ? 1 : 0) +
               (inproj4->answer ? 1 : 0) + (inepsg->answer ? 1 : 0));
    if (formats > 1)
        G_fatal_error(_("Only one of '%s', '%s', '%s' or '%s' options may be specified"),
                      ingeo->key, inwkt->key, inproj4->key, inepsg->key);

    /* Input */
    /* We can only have one input source, hence if..else construct */

    if (formats == 0)
#endif
        /* Input is projection of current location */
        input_currloc();
#ifdef HAVE_OGR
    else if (inwkt->answer)
        /* Input in WKT format */
        input_wkt(inwkt->answer);
    else if (inproj4->answer)
        /* Input in PROJ.4 format */
        input_proj4(inproj4->answer);
    else if (inepsg->answer)
        /* Input from EPSG code */
        input_epsg(atoi(inepsg->answer));
    else
        /* Input from georeferenced file */
        input_georef(ingeo->answer);
#endif

    /* Consistency Check */

    if ((cellhd.proj != PROJECTION_XY)
            && (projinfo == NULL || projunits == NULL))
        G_fatal_error(_("Projection files missing"));

    /* Set Datum Parameters if necessary or requested */
    set_datumtrans(atoi(dtrans->answer), forcedatumtrans->answer);


    /* Output */
    /* Only allow one output format at a time, to reduce confusion */
    formats = ((printinfo->answer ? 1 : 0) + (shellinfo->answer ? 1 : 0) +
               (datuminfo->answer ? 1 : 0) +
               (printproj4->answer ? 1 : 0) +
#ifdef HAVE_OGR
               (printwkt->answer ? 1 : 0) +
#endif
               (create->answer ? 1 : 0));
    if (formats > 1)
        G_fatal_error(_("Only one of -%c, -%c, -%c, -%c"
#ifdef HAVE_OGR
                        ", -%c"
#endif
                        " or -%c flags may be specified"),
                      printinfo->key, shellinfo->key, datuminfo->key, printproj4->key,
#ifdef HAVE_OGR
                      printwkt->key,
#endif
                      create->key);

    if (printinfo->answer || shellinfo->answer)
        print_projinfo(shellinfo->answer);
    else if (datuminfo->answer)
        print_datuminfo();
    else if (printproj4->answer)
        print_proj4(dontprettify->answer);
#ifdef HAVE_OGR
    else if (printwkt->answer)
        print_wkt(esristyle->answer, dontprettify->answer);
#endif
    else if (location->answer)
        create_location(location->answer);
    else if (create->answer)
        modify_projinfo();
    else
        G_fatal_error(_("No output format specified, define one "
                        "of flags -%c, -%c, -%c, or -%c"),
                      printinfo->key, shellinfo->key, printproj4->key, printwkt->key);


    /* Tidy Up */

    if (projinfo != NULL)
        G_free_key_value(projinfo);
    if (projunits != NULL)
        G_free_key_value(projunits);

    exit(EXIT_SUCCESS);

}