Beispiel #1
0
void make_link(const char *dsn_opt,
	       const char *format,
	       char *option_str, char **options)
{
    int use_ogr;
    char *filename, *dsn;
    FILE *fp;
    
    struct Key_Value *key_val;
    
    key_val = G_create_key_value();

    /* check for weird options */
    if (G_strncasecmp(dsn_opt, "PG:", 3) == 0 &&
        strcmp(format, "PostgreSQL") != 0)
        G_warning(_("Data source starts with \"PG:\" prefix, expecting \"PostgreSQL\" "
                    "format (\"%s\" given)"), format);
    
    /* use OGR ? */
    use_ogr = is_ogr(format);
    if (use_ogr) {
        filename = "OGR";
        G_remove("", "PG");
    }
    else {
        filename = "PG";
        G_remove("", "OGR");
    }
    
    /* be friendly, ignored 'PG:' prefix for GRASS-PostGIS data driver */
    if (!use_ogr && strcmp(format, "PostgreSQL") == 0 &&
	G_strncasecmp(dsn_opt, "PG:", 3) == 0) {
	int i, length;
	
	length = strlen(dsn_opt);
	dsn = (char *) G_malloc(length - 3);
	for (i = 3; i < length; i++)
	    dsn[i-3] = dsn_opt[i];
	dsn[length-3] = '\0';
    }
    else {
	dsn = G_store(dsn_opt);
    }
        
    /* parse options for PG data format */
    if (options && *options && !use_ogr) {
        int i;
        char *key, *value;
        
        i = 0;
        while (options[i]) {
            if (parse_option_pg(options[i++], &key, &value) != 0)
                continue;
            G_set_key_value(key, value, key_val);
        }
    }

    /* datasource section */
    if (dsn) {
	if (use_ogr)
	    G_set_key_value("dsn", dsn, key_val);
	else
	    G_set_key_value("conninfo", dsn, key_val);
    }
    
    if (use_ogr) { /* OGR */
        if (format)
            G_set_key_value("format", format, key_val);
        if (option_str)
            G_set_key_value("options", option_str, key_val);
    }
    else {        /* PG */
        G_set_key_value("format", "PostgreSQL", key_val);
    }
    /* save file - OGR or PG */
    fp = G_fopen_new("", filename);
    if (!fp)
	G_fatal_error(_("Unable to create settings file"));

    if (G_fwrite_key_value(fp, key_val) < 0)
	G_fatal_error(_("Error writing settings file"));

    fclose(fp);

    if (use_ogr)
        G_verbose_message(_("Switched to OGR format (%s)"),
                          G_find_key_value("format", key_val));
    else
        G_verbose_message(_("Switched to PostGIS format"));

    G_free_key_value(key_val);
}
Beispiel #2
0
int set_datumtrans(int datumtrans, int force)
{
    char *params, *datum = NULL;
    int paramsets, status;

    if (cellhd.proj == PROJECTION_XY)
	return 0;

    status = GPJ__get_datum_params(projinfo, &datum, &params);
    G_debug(3, "set_datumtrans(): GPJ__get_datum_params() status=%d", status);
    G_free(params);

    if (datum) {
	/* A datum name is specified; need to determine if
	 * there are parameters to choose from for this datum */
	struct gpj_datum dstruct;

	if (GPJ_get_datum_by_name(datum, &dstruct) > 0) {
	    char *defparams;

	    paramsets =
		GPJ_get_default_datum_params_by_name(dstruct.name,
						     &defparams);
	    G_free(defparams);
	    GPJ_free_datum(&dstruct);

	    G_debug(3, "set_datumtrans(): datum transform terms found "
		    "with %d options", paramsets);

	    if (status == 1 && paramsets > 1)
		/* Parameters are missing and there is a choice to be made */
		force = 1;

	}
	else {
	    /* Datum name not found in table; can't do anything. */
	    G_debug(3, "set_datumtrans(): Datum name not found in table.");
	    force = 0;
	}
    }
    else {
	/* No datum name; can't do anything. */
	G_debug(3, "set_datumtrans(): Datum name either invalid or not supplied.");
	force = 0;
    }

    if (force) {
	char *chosenparams = NULL;
	char *paramkey, *paramvalue;
	struct Key_Value *temp_projinfo;
	int i;

	/* First of all obtain the new parameters 
	 * through the supplied transform number index */
	{
	    struct gpj_datum_transform_list *list;

	    if (datumtrans > paramsets)
		G_fatal_error
		    ("Invalid transformation number %d; valid range is 1 to %d",
		     datumtrans, paramsets);

	    G_debug(3, "set_datumtrans(): looking up available datum "
		    "transforms for <%s>", datum);

	    list = GPJ_get_datum_transform_by_name(datum);

	    if (list != NULL) {
		if (datumtrans == -1) {
		    do {
			struct gpj_datum_transform_list *old = list;
			fprintf(stdout, "---\n%d\nUsed in %s\n%s\n%s\n",
				list->count, list->where_used,
				list->params, list->comment);
			list = list->next;
		        GPJ_free_datum_transform(old);
		    } while (list != NULL);

		    exit(EXIT_SUCCESS);
		}
		else {
		    do {
			struct gpj_datum_transform_list *old = list;
			if (list->count == datumtrans)
			    chosenparams = G_store(list->params);
			list = list->next;
		        GPJ_free_datum_transform(old);
		    } while (list != NULL);
		}
	    }

	}

	temp_projinfo = G_create_key_value();

	/* Copy old PROJ_INFO, skipping out any keys related
	 * to datum parameters */
	for (i = 0; i < projinfo->nitems; i++) {
	    if (strcmp(projinfo->key[i], "dx") == 0
		|| strcmp(projinfo->key[i], "dy") == 0
		|| strcmp(projinfo->key[i], "dz") == 0
		|| strcmp(projinfo->key[i], "datumparams") == 0
		|| strcmp(projinfo->key[i], "nadgrids") == 0
		|| strcmp(projinfo->key[i], "towgs84") == 0)
		continue;

	    G_set_key_value(projinfo->key[i], projinfo->value[i],
			    temp_projinfo);
	}

	/* Finally add new parameters (if we have them) */
	if (chosenparams != NULL) {
	    /* Now split 'chosenparams' into key/value format */
	    paramkey = strtok(chosenparams, "=");
	    paramvalue = chosenparams + strlen(paramkey) + 1;
	    G_set_key_value(paramkey, paramvalue, temp_projinfo);
	    G_free(chosenparams);
	}

	/* Destroy original key/value structure and replace with new one */
	G_free_key_value(projinfo);
	projinfo = temp_projinfo;

    }
    G_free(datum);

    return force;
}
OGRGRASSLayer::OGRGRASSLayer( int layerIndex,  struct Map_info * map )
{
    CPLDebug ( "GRASS", "OGRGRASSLayer::OGRGRASSLayer layerIndex = %d", layerIndex );
    
    iLayerIndex = layerIndex;
    poMap = map; 
    poSRS = NULL;
    iNextId = 0;
    poPoints = Vect_new_line_struct();
    poCats = Vect_new_cats_struct();
    pszQuery = NULL;
    paQueryMatch = NULL;
    paSpatialMatch = NULL;

    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 );	
    }
    else
    {	
	char buf[20]; 
	sprintf ( buf, "%d", iLayer ); 
	pszName = CPLStrdup( buf );
    }

    // Because we don't represent centroids as any simple feature, we have to scan
    // category index and create index of feature IDs pointing to category index
    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++ ) 
    {
	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;
    }

    poFeatureDefn = new OGRFeatureDefn( pszName );
    poFeatureDefn->Reference();

    // Get type definition
    int nTypes = Vect_cidx_get_num_types_by_index ( poMap, iLayerIndex );
    int types = 0;
    for ( int i = 0; i < nTypes; i++ ) {
	int type, count;
	Vect_cidx_get_type_count_by_index ( poMap, iLayerIndex, i, &type, &count);
	if ( !(type & (GV_POINT|GV_LINES|GV_AREA) ) ) continue;
	types |= type;
        CPLDebug ( "GRASS", "type = %d types = %d", type, types );
    }
    
    OGRwkbGeometryType eGeomType = wkbUnknown;
    if ( types == GV_LINE || types == GV_BOUNDARY || types == GV_LINES ) 
    {
        eGeomType = wkbLineString;
    } 
    else if ( types == GV_POINT )
    {
        eGeomType = wkbPoint;
    }
    else if ( types == GV_AREA )
    {
        CPLDebug ( "GRASS", "set wkbPolygon" );
        eGeomType = wkbPolygon;
    }

    if (Vect_is_3d(poMap))
        poFeatureDefn->SetGeomType ( (OGRwkbGeometryType)(eGeomType | wkb25DBit) );
    else
        poFeatureDefn->SetGeomType ( eGeomType );

    // Get attributes definition
    poDbString = (dbString*) CPLMalloc ( sizeof(dbString) );
    poCursor = (dbCursor*) CPLMalloc ( sizeof(dbCursor) );
    bCursorOpened = FALSE;

    poDriver = NULL;
    bHaveAttributes = false;
    db_init_string ( poDbString );
    if ( poLink ) 
    {
	if ( StartDbDriver() ) 
	{
	    db_set_string ( poDbString, poLink->table );
	    dbTable *table;
	    if ( db_describe_table ( poDriver, poDbString, &table) == DB_OK )
	    {
		nFields = db_get_table_number_of_columns ( table );
		iCatField = -1;
		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; 
			 case DB_C_TYPE_DOUBLE:
			    ogrFtype = OFTReal;
			    break; 
			 case DB_C_TYPE_STRING:
			    ogrFtype = OFTString;
			    break; 
			 case DB_C_TYPE_DATETIME:
			    ogrFtype = OFTDateTime;
			    break; 
		    }

		    CPLDebug ( "GRASS", "column = %s type = %d", 
			       db_get_column_name(column), ctype );
		    
		    OGRFieldDefn oField ( db_get_column_name(column), ogrFtype );
		    poFeatureDefn->AddFieldDefn( &oField );

		    if ( G_strcasecmp(db_get_column_name(column),poLink->key) == 0 )
		    {
			iCatField = i;
		    }
		}
		if ( iCatField >= 0  ) 
		{
    		    bHaveAttributes = true;
		}
		else
		{
		    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", 
			  poLink->table );

	    }
	    db_close_database_shutdown_driver ( poDriver );
	    poDriver = NULL;
	}
    } 
	
    if ( !bHaveAttributes && iLayer > 0 ) // Because features in layer 0 have no cats  
    {
	OGRFieldDefn oField("cat", OFTInteger);
	poFeatureDefn->AddFieldDefn( &oField );
    }

    if ( getenv("GISBASE") )  // We have some projection info in GISBASE
    {
        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

        projinfo = G_get_projinfo();
	projunits = G_get_projunits();

	char *srsWkt = GPJ_grass_to_wkt ( projinfo, projunits, 0, 0);
	if ( srsWkt ) 
	{
	    poSRS = new OGRSpatialReference ( srsWkt );
	    CPLFree ( srsWkt );
	}

        G_free_key_value(projinfo);
        G_free_key_value(projunits);
    }
}
Beispiel #4
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 "
                "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 );
    }

    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 = 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;
}
Beispiel #5
0
int GPJ_osr_to_grass(struct Cell_head *cellhd, struct Key_Value **projinfo,
		     struct Key_Value **projunits, OGRSpatialReferenceH hSRS,
		     int datumtrans)
{
    struct Key_Value *temp_projinfo;
    char *pszProj4 = NULL, *pszRemaining;
    char *pszProj = NULL;
    char *datum = NULL;
    struct gpj_datum dstruct;

    if (hSRS == NULL)
	goto default_to_xy;

    /* Set finder function for locating OGR csv co-ordinate system tables */
    SetCSVFilenameHook(GPJ_set_csv_loc);

    /* Hopefully this doesn't do any harm if it wasn't in ESRI format
     * to start with... */
    OSRMorphFromESRI(hSRS);

    /* -------------------------------------------------------------------- */
    /*      Set cellhd for well known coordinate systems.                   */
    /* -------------------------------------------------------------------- */
    if (!OSRIsGeographic(hSRS) && !OSRIsProjected(hSRS))
	goto default_to_xy;

    if (cellhd) {
	int bNorth;

	if (OSRIsGeographic(hSRS)) {
	    cellhd->proj = PROJECTION_LL;
	    cellhd->zone = 0;
	}
	else if (OSRGetUTMZone(hSRS, &bNorth) != 0) {
	    cellhd->proj = PROJECTION_UTM;
	    cellhd->zone = OSRGetUTMZone(hSRS, &bNorth);
	    if (!bNorth)
		cellhd->zone *= -1;
	}
	else {
	    cellhd->proj = PROJECTION_OTHER;
	    cellhd->zone = 0;
	}
    }

    /* -------------------------------------------------------------------- */
    /*      Get the coordinate system definition in PROJ.4 format.          */
    /* -------------------------------------------------------------------- */
    if (OSRExportToProj4(hSRS, &pszProj4) != OGRERR_NONE)
	goto default_to_xy;

    /* -------------------------------------------------------------------- */
    /*      Parse the PROJ.4 string into key/value pairs.  Do a bit of      */
    /*      extra work to "GRASSify" the result.                            */
    /* -------------------------------------------------------------------- */
    temp_projinfo = G_create_key_value();

    /* Create "local" copy of proj4 string so we can modify and free it
     * using GRASS functions */
    pszRemaining = G_store(pszProj4);
    CPLFree(pszProj4);
    pszProj4 = pszRemaining;
    while ((pszRemaining = strstr(pszRemaining, "+")) != NULL) {
	char *pszToken, *pszValue;

	pszRemaining++;

	/* Advance pszRemaining to end of this token[=value] pair */
	pszToken = pszRemaining;
	while (*pszRemaining != ' ' && *pszRemaining != '\0')
	    pszRemaining++;

	if (*pszRemaining == ' ') {
	    *pszRemaining = '\0';
	    pszRemaining++;
	}

	/* parse token, and value */
	if (strstr(pszToken, "=") != NULL) {
	    pszValue = strstr(pszToken, "=");
	    *pszValue = '\0';
	    pszValue++;
	}
	else
	    pszValue = "defined";


	if (G_strcasecmp(pszToken, "proj") == 0) {
	    /* The ll projection is known as longlat in PROJ.4 */
	    if (G_strcasecmp(pszValue, "longlat") == 0)
		pszValue = "ll";

	    pszProj = pszValue;
	    continue;
	}

	/* Ellipsoid and datum handled separately below */
	if (G_strcasecmp(pszToken, "ellps") == 0
	    || G_strcasecmp(pszToken, "a") == 0
	    || G_strcasecmp(pszToken, "b") == 0
	    || G_strcasecmp(pszToken, "es") == 0
	    || G_strcasecmp(pszToken, "rf") == 0
	    || G_strcasecmp(pszToken, "datum") == 0)
	    continue;

	/* We will handle units separately */
	if (G_strcasecmp(pszToken, "to_meter") == 0
	    || G_strcasecmp(pszToken, "units") == 0)
	    continue;

	G_set_key_value(pszToken, pszValue, temp_projinfo);
    }

    *projinfo = G_create_key_value();

    /* -------------------------------------------------------------------- */
    /*      Derive the user name for the projection.                        */
    /* -------------------------------------------------------------------- */
    if (pszProj) {
	char path[4095];
	char name[80];

	sprintf(path, "%s/etc/projections", G_gisbase());
	if (G_lookup_key_value_from_file(path, pszProj, name, sizeof(name)) >
	    0)
	    G_set_key_value("name", name, *projinfo);
	else
	    G_set_key_value("name", pszProj, *projinfo);

	G_set_key_value("proj", pszProj, *projinfo);
    }
    else
	G_warning(_("No projection name! Projection parameters likely to be meaningless."));


    /* -------------------------------------------------------------------- */
    /*      Find the GRASS datum name and choose parameters either          */
    /*      interactively or not.                                           */
    /* -------------------------------------------------------------------- */

    {
	const char *pszDatumNameConst = OSRGetAttrValue(hSRS, "DATUM", 0);
	struct datum_list *list, *listhead;
	char *dum1, *dum2, *pszDatumName;
	int paramspresent =
	    GPJ__get_datum_params(temp_projinfo, &dum1, &dum2);

	if (pszDatumNameConst) {
	    /* Need to make a new copy of the string so we don't mess
	     * around with the memory inside the OGRSpatialReferenceH? */

	    pszDatumName = G_store(pszDatumNameConst);
	    DatumNameMassage(&pszDatumName);

	    list = listhead = read_datum_table();

	    while (list != NULL) {
		if (G_strcasecmp(pszDatumName, list->longname) == 0) {
		    datum = G_store(list->name);
		    break;
		}
		list = list->next;
	    }
	    free_datum_list(listhead);

	    if (datum == NULL) {
		if (paramspresent < 2)
		    /* Only give warning if no parameters present */
		    G_warning(_("Datum <%s> not recognised by GRASS and no parameters found"),
			      pszDatumName);
	    }
	    else {
		G_set_key_value("datum", datum, *projinfo);

		if (paramspresent < 2) {
		    /* If no datum parameters were imported from the OSR
		     * object then we should use the set specified by datumtrans */
		    char *params, *chosenparams = NULL;
		    int paramsets;

		    paramsets =
			GPJ_get_default_datum_params_by_name(datum, &params);

		    if (paramsets < 0)
			G_warning(_("Datum <%s> apparently recognised by GRASS but no parameters found. "
				   "You may want to look into this."), datum);
		    else if (datumtrans > paramsets) {

			G_warning(_("Invalid transformation number %d; valid range is 1 to %d. "
				   "Leaving datum transform parameters unspecified."),
				  datumtrans, paramsets);
			datumtrans = 0;
		    }

		    if (paramsets > 0) {
			struct gpj_datum_transform_list *list, *old;

			list = GPJ_get_datum_transform_by_name(datum);

			if (list != NULL) {
			    do {
				if (list->count == datumtrans)
				    chosenparams = G_store(list->params);
				old = list;
				list = list->next;
				GPJ_free_datum_transform(old);
			    } while (list != NULL);
			}
		    }

		    if (chosenparams != NULL) {
			char *paramkey, *paramvalue;

			paramkey = strtok(chosenparams, "=");
			paramvalue = chosenparams + strlen(paramkey) + 1;
			G_set_key_value(paramkey, paramvalue, *projinfo);
			G_free(chosenparams);
		    }

		    if (paramsets > 0)
			G_free(params);
		}

	    }
	    G_free(pszDatumName);
	}
    }

    /* -------------------------------------------------------------------- */
    /*   Determine an appropriate GRASS ellipsoid name if possible, or      */
    /*   else just put a and es values into PROJ_INFO                       */
    /* -------------------------------------------------------------------- */

    if ((datum != NULL) && (GPJ_get_datum_by_name(datum, &dstruct) > 0)) {
	/* Use ellps name associated with datum */
	G_set_key_value("ellps", dstruct.ellps, *projinfo);
	GPJ_free_datum(&dstruct);
	G_free(datum);
    }
    else {
	/* If we can't determine the ellipsoid from the datum, derive it
	 * directly from "SPHEROID" parameters in WKT */
	const char *pszSemiMajor = OSRGetAttrValue(hSRS, "SPHEROID", 1);
	const char *pszInvFlat = OSRGetAttrValue(hSRS, "SPHEROID", 2);

	if (pszSemiMajor != NULL && pszInvFlat != NULL) {
	    char *ellps = NULL;
	    struct ellps_list *list, *listhead;
	    double a = atof(pszSemiMajor), invflat = atof(pszInvFlat), flat;
	    double es;

	    /* Allow for incorrect WKT describing a sphere where InvFlat 
	     * is given as 0 rather than inf */
	    if (invflat > 0)
		flat = 1 / invflat;
	    else
		flat = 0;

	    es = flat * (2.0 - flat);

	    list = listhead = read_ellipsoid_table(0);

	    while (list != NULL) {
		/* Try and match a and es against GRASS defined ellipsoids;
		 * accept first one that matches. These numbers were found
		 * by trial and error and could be fine-tuned, or possibly
		 * a direct comparison of IEEE floating point values used. */
		if ((a == list->a || fabs(a - list->a) < 0.1 || fabs(1 - a / list->a) < 0.0000001) && ((es == 0 && list->es == 0) ||	/* Special case for sphere */
												       (invflat == list->rf || fabs(invflat - list->rf) < 0.0000001))) {
		    ellps = G_store(list->name);
		    break;
		}
		list = list->next;
	    }
	    if (listhead != NULL)
		free_ellps_list(listhead);

	    if (ellps == NULL) {
		/* If we weren't able to find a matching ellps name, set
		 * a and es values directly from WKT-derived data */
		char es_str[100];

		G_set_key_value("a", (char *)pszSemiMajor, *projinfo);

		sprintf(es_str, "%.16g", es);
		G_set_key_value("es", es_str, *projinfo);
	    }
	    else {
		/* else specify the GRASS ellps name for readability */
		G_set_key_value("ellps", ellps, *projinfo);
		G_free(ellps);
	    }

	}

    }

    /* -------------------------------------------------------------------- */
    /*      Finally append the detailed projection parameters to the end    */
    /* -------------------------------------------------------------------- */

    {
	int i;

	for (i = 0; i < temp_projinfo->nitems; i++)
	    G_set_key_value(temp_projinfo->key[i],
			    temp_projinfo->value[i], *projinfo);

	G_free_key_value(temp_projinfo);
    }

    G_free(pszProj4);

    /* -------------------------------------------------------------------- */
    /*      Set the linear units.                                           */
    /* -------------------------------------------------------------------- */
    *projunits = G_create_key_value();

    if (OSRIsGeographic(hSRS)) {
	/* We assume degrees ... someday we will be wrong! */
	G_set_key_value("unit", "degree", *projunits);
	G_set_key_value("units", "degrees", *projunits);
	G_set_key_value("meters", "1.0", *projunits);
    }
    else {
	char szFormatBuf[256];
	char *pszUnitsName = NULL;
	double dfToMeters;
	char *pszUnitsPlural, *pszStringEnd;

	dfToMeters = OSRGetLinearUnits(hSRS, &pszUnitsName);

	/* Workaround for the most obvious case when unit name is unknown */
	if ((G_strcasecmp(pszUnitsName, "unknown") == 0) &&
	    (dfToMeters == 1.))
	    G_asprintf(&pszUnitsName, "meter");

	G_set_key_value("unit", pszUnitsName, *projunits);

	/* Attempt at plural formation (WKT format doesn't store plural
	 * form of unit name) */
	pszUnitsPlural = G_malloc(strlen(pszUnitsName) + 3);
	strcpy(pszUnitsPlural, pszUnitsName);
	pszStringEnd = pszUnitsPlural + strlen(pszUnitsPlural) - 4;
	if (G_strcasecmp(pszStringEnd, "foot") == 0) {
	    /* Special case for foot - change two o's to e's */
	    pszStringEnd[1] = 'e';
	    pszStringEnd[2] = 'e';
	}
	else if (G_strcasecmp(pszStringEnd, "inch") == 0) {
	    /* Special case for inch - add es */
	    pszStringEnd[4] = 'e';
	    pszStringEnd[5] = 's';
	    pszStringEnd[6] = '\0';
	}
	else {
	    /* For anything else add an s at the end */
	    pszStringEnd[4] = 's';
	    pszStringEnd[5] = '\0';
	}

	G_set_key_value("units", pszUnitsPlural, *projunits);
	G_free(pszUnitsPlural);

	sprintf(szFormatBuf, "%.16g", dfToMeters);
	G_set_key_value("meters", szFormatBuf, *projunits);

    }

    return 2;

    /* -------------------------------------------------------------------- */
    /*      Fallback to returning an ungeoreferenced definition.            */
    /* -------------------------------------------------------------------- */
  default_to_xy:
    if (cellhd != NULL) {
	cellhd->proj = PROJECTION_XY;
	cellhd->zone = 0;
    }

    *projinfo = NULL;
    *projunits = NULL;

    return 1;
}
Beispiel #6
0
/*!
  \brief Create GDAL settings for given raster map

  \param name map name
  \param map_type map type (CELL, FCELL, DCELL)

  \return pointer to allocated GDAL_link structure
  \return NULL on error
*/
struct GDAL_link *Rast_create_gdal_link(const char *name,
					RASTER_MAP_TYPE map_type)
{
#ifdef GDAL_LINK
    char path[GPATH_MAX];
    GDALDriverH driver;
    double transform[6];
    struct GDAL_link *gdal;
    FILE *fp;
    struct Key_Value *key_val;
    char buf[32];

    Rast__init_window();

    Rast_init_gdal();

    if (!G_is_initialized(&st->initialized)) {
	read_gdal_options();
	st->projinfo = G_get_projinfo();
	st->projunits = G_get_projunits();
#if 0
	/* We cannot use GPJ_grass_to_wkt() here because that would create a
	   circular dependency between libgis and libgproj */
	if (st->projinfo && st->projunits)
	    st->srswkt = GPJ_grass_to_wkt(st->projinfo, st->projunits);
#endif
	G_initialize_done(&st->initialized);
    }

    gdal = G_calloc(1, sizeof(struct GDAL_link));

    sprintf(path, "%s/%s%s", st->opts.dir, name, st->opts.ext);
    gdal->filename = G_store(path);
    gdal->band_num = 1;
    gdal->hflip = 0;
    gdal->vflip = 0;

    switch (map_type) {
    case CELL_TYPE:
	switch (R__.nbytes) {
	case 1:
	    gdal->type = GDT_Byte;
	    gdal->null_val = (DCELL) 0xFF;
	    break;
	case 2:
	    gdal->type = GDT_UInt16;
	    gdal->null_val = (DCELL) 0xFFFF;
	    break;
	case 3:
	case 4:
	    gdal->type = GDT_Int32;
	    gdal->null_val = (DCELL) 0x80000000U;
	    break;
	}
	break;
    case FCELL_TYPE:
	gdal->type = GDT_Float32;
	Rast_set_d_null_value(&gdal->null_val, 1);
	break;
    case DCELL_TYPE:
	gdal->type = GDT_Float64;
	Rast_set_d_null_value(&gdal->null_val, 1);
	break;
    default:
	G_fatal_error(_("Invalid map type <%d>"), map_type);
	break;
    }

    driver = (*pGDALGetDriverByName) (st->opts.format);
    if (!driver)
	G_fatal_error(_("Unable to get <%s> driver"), st->opts.format);

    /* Does driver support GDALCreate ? */
    if ((*pGDALGetMetadataItem) (driver, GDAL_DCAP_CREATE, NULL)) {
	gdal->data =
	    (*pGDALCreate)(driver, gdal->filename,
			   R__.wr_window.cols, R__.wr_window.rows,
			   1, gdal->type, st->opts.options);
	if (!gdal->data)
	    G_fatal_error(_("Unable to create <%s> dataset using <%s> driver"),
			  name, st->opts.format);
    }
    /* If not - create MEM driver for intermediate dataset. 
     * Check if raster can be created at all (with GDALCreateCopy) */
    else if ((*pGDALGetMetadataItem) (driver, GDAL_DCAP_CREATECOPY, NULL)) {
	GDALDriverH mem_driver;

	G_message(_("Driver <%s> does not support direct writing. "
		    "Using MEM driver for intermediate dataset."),
		  st->opts.format);

	mem_driver = (*pGDALGetDriverByName) ("MEM");
	if (!mem_driver)
	    G_fatal_error(_("Unable to get in-memory raster driver"));

	gdal->data =
	    (*pGDALCreate)(mem_driver, "",
			   R__.wr_window.cols, R__.wr_window.rows,
			   1, gdal->type, st->opts.options);
	if (!gdal->data)
	    G_fatal_error(_("Unable to create <%s> dataset using memory driver"),
			  name);
    }
    else
	G_fatal_error(_("Driver <%s> does not support creating rasters"),
		      st->opts.format);

    gdal->band = (*pGDALGetRasterBand) (gdal->data, gdal->band_num);

    (*pGDALSetRasterNoDataValue) (gdal->band, gdal->null_val);

    /* Set Geo Transform  */
    transform[0] = R__.wr_window.west;
    transform[1] = R__.wr_window.ew_res;
    transform[2] = 0.0;
    transform[3] = R__.wr_window.north;
    transform[4] = 0.0;
    transform[5] = -R__.wr_window.ns_res;

    if ((*pGDALSetGeoTransform) (gdal->data, transform) >= CE_Failure)
	G_warning(_("Unable to set geo transform"));

    if (st->srswkt)
	if ((*pGDALSetProjection) (gdal->data, st->srswkt) == CE_Failure)
	    G_warning(_("Unable to set projection"));

    fp = G_fopen_new_misc("cell_misc", "gdal", name);
    if (!fp)
	G_fatal_error(_("Unable to create cell_misc/%s/gdal file"), name);

    key_val = G_create_key_value();

    G_set_key_value("file", gdal->filename, key_val);

    sprintf(buf, "%d", gdal->band_num);
    G_set_key_value("band", buf, key_val);

    sprintf(buf, "%.22g", gdal->null_val);
    G_set_key_value("null", buf, key_val);

    sprintf(buf, "%d", gdal->type);
    G_set_key_value("type", buf, key_val);

    if (G_fwrite_key_value(fp, key_val) < 0)
	G_fatal_error(_("Error writing cell_misc/%s/gdal file"), name);

    G_free_key_value(key_val);

    fclose(fp);

    return gdal;
#else
    return NULL;
#endif
}
Beispiel #7
0
/*!
   \brief Create new OGR layer in given OGR datasource (internal use only)

   V1_open_new_ogr() is required to be called before this function.

   List of currently supported types:
    - GV_POINT     (wkbPoint)
    - GV_LINE      (wkbLineString)
    - GV_BOUNDARY  (wkb_Polygon)
   \param[in,out] Map pointer to Map_info structure
   \param type feature type (GV_POINT, GV_LINE, ...)

   \return 0 success
   \return -1 error 
*/
int create_ogr_layer(struct Map_info *Map, int type)
{
    int ndblinks;
    OGRLayerH            Ogr_layer;
    OGRSpatialReferenceH Ogr_spatial_ref;
    
    struct field_info *Fi;
    struct Key_Value *projinfo, *projunits;
    struct Format_info_ogr *ogr_info;
    
    OGRwkbGeometryType Ogr_geom_type;
    char             **Ogr_layer_options;
    
    ogr_info = &(Map->fInfo.ogr);
    
    if (!ogr_info->driver_name ||
	!ogr_info->layer_name ||
	!ogr_info->ds)
	return -1;
    
    /* get spatial reference */
    projinfo  = G_get_projinfo();
    projunits = G_get_projunits();
    Ogr_spatial_ref = GPJ_grass_to_osr(projinfo, projunits);
    G_free_key_value(projinfo);
    G_free_key_value(projunits);
    
    /* determine geometry type */
    switch(type) {
    case GV_POINT:
	Ogr_geom_type = wkbPoint;
	break;
    case GV_LINE:
	Ogr_geom_type = wkbLineString;
	break;
    case GV_BOUNDARY:
	Ogr_geom_type = wkbPolygon;
	break;
    default:
	G_warning(_("Unsupported geometry type (%d)"), type);
	return -1;
    }
    
    /* check creation options */
    Ogr_layer_options = ogr_info->layer_options;
    if (Vect_is_3d(Map)) {
	if (strcmp(ogr_info->driver_name, "PostgreSQL") == 0) {
	    Ogr_layer_options = CSLSetNameValue(Ogr_layer_options, "DIM", "3");
	}
    }
    else {
	if (strcmp(ogr_info->driver_name, "PostgreSQL") == 0) {
	    Ogr_layer_options = CSLSetNameValue(Ogr_layer_options, "DIM", "2");
	}
    }

    /* create new OGR layer */
    Ogr_layer = OGR_DS_CreateLayer(ogr_info->ds, ogr_info->layer_name,
				   Ogr_spatial_ref, Ogr_geom_type, Ogr_layer_options);
    CSLDestroy(Ogr_layer_options);
    if (!Ogr_layer) {
	G_warning(_("Unable to create OGR layer <%s> in '%s'"),
		  ogr_info->layer_name, ogr_info->dsn);
	return -1;
    }
    ogr_info->layer = Ogr_layer;

    ndblinks = Vect_get_num_dblinks(Map);
    if (ndblinks > 0) {
	/* write also attributes */
	Fi = Vect_get_dblink(Map, 0);
	if (Fi) {
	    if (ndblinks > 1)
		G_warning(_("More layers defined, using driver <%s> and "
			    "database <%s>"), Fi->driver, Fi->database);
	    ogr_info->dbdriver = create_table(ogr_info->layer, Fi);
	    G_free(Fi);
	}
	else
	  G_warning(_("Database connection not defined. "
		      "Unable to write attributes."));
    }
    
    if (OGR_L_TestCapability(ogr_info->layer, OLCTransactions))
	OGR_L_StartTransaction(ogr_info->layer);

    return 0;
}
Beispiel #8
0
int main(int argc, char **argv)
{
    char *mapname,		/* ptr to name of output layer  */
     *setname,			/* ptr to name of input mapset  */
     *ipolname;			/* name of interpolation method */

    int fdi,			/* input map file descriptor    */
      fdo,			/* output map file descriptor   */
      method,			/* position of method in table  */
      permissions,		/* mapset permissions           */
      cell_type,		/* output celltype              */
      cell_size,		/* size of a cell in bytes      */
      row, col,			/* counters                     */
      irows, icols,		/* original rows, cols          */
      orows, ocols, have_colors,	/* Input map has a colour table */
      overwrite,		/* Overwrite                    */
      curr_proj;		/* output projection (see gis.h) */

    void *obuffer;		/* buffer that holds one output row     */

    struct cache *ibuffer;	/* buffer that holds the input map      */
    func interpolate;		/* interpolation routine        */

    double xcoord2,		/* temporary x coordinates      */
      ycoord2,			/* temporary y coordinates      */
      onorth, osouth,		/* save original border coords  */
      oeast, owest, inorth, isouth, ieast, iwest;
    char north_str[30], south_str[30], east_str[30], west_str[30];

    struct Colors colr;		/* Input map colour table       */
    struct History history;

    struct pj_info iproj,	/* input map proj parameters    */
      oproj;			/* output map proj parameters   */

    struct Key_Value *in_proj_info,	/* projection information of    */
     *in_unit_info,		/* input and output mapsets     */
     *out_proj_info, *out_unit_info;

    struct GModule *module;

    struct Flag *list,		/* list files in source location */
     *nocrop,			/* don't crop output map        */
     *print_bounds,		/* print output bounds and exit */
     *gprint_bounds;		/* same but print shell style	*/

    struct Option *imapset,	/* name of input mapset         */
     *inmap,			/* name of input layer          */
     *inlocation,		/* name of input location       */
     *outmap,			/* name of output layer         */
     *indbase,			/* name of input database       */
     *interpol,			/* interpolation method:
				   nearest neighbor, bilinear, cubic */
     *memory,			/* amount of memory for cache   */
     *res;			/* resolution of target map     */
    struct Cell_head incellhd,	/* cell header of input map     */
      outcellhd;		/* and output map               */


    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("projection"));
    G_add_keyword(_("transformation"));
    module->description =
	_("Re-projects a raster map from given location to the current location.");

    inmap = G_define_standard_option(G_OPT_R_INPUT);
    inmap->description = _("Name of input raster map to re-project");
    inmap->required = NO;
    inmap->guisection = _("Source");

    inlocation = G_define_option();
    inlocation->key = "location";
    inlocation->type = TYPE_STRING;
    inlocation->required = YES;
    inlocation->description = _("Location containing input raster map");
    inlocation->gisprompt = "old,location,location";
    inlocation->key_desc = "name";

    imapset = G_define_standard_option(G_OPT_M_MAPSET);
    imapset->label = _("Mapset containing input raster map");
    imapset->description = _("Default: name of current mapset");
    imapset->guisection = _("Source");

    indbase = G_define_option();
    indbase->key = "dbase";
    indbase->type = TYPE_STRING;
    indbase->required = NO;
    indbase->description = _("Path to GRASS database of input location");
    indbase->gisprompt = "old,dbase,dbase";
    indbase->key_desc = "path";
    indbase->guisection = _("Source");

    outmap = G_define_standard_option(G_OPT_R_OUTPUT);
    outmap->required = NO;
    outmap->description = _("Name for output raster map (default: same as 'input')");
    outmap->guisection = _("Target");

    ipolname = make_ipol_list();
    
    interpol = G_define_option();
    interpol->key = "method";
    interpol->type = TYPE_STRING;
    interpol->required = NO;
    interpol->answer = "nearest";
    interpol->options = ipolname;
    interpol->description = _("Interpolation method to use");
    interpol->guisection = _("Target");
    interpol->descriptions = make_ipol_desc();

    memory = G_define_option();
    memory->key = "memory";
    memory->type = TYPE_INTEGER;
    memory->required = NO;
    memory->answer = "300";
    memory->label = _("Maximum memory to be used (in MB)");
    memory->description = _("Cache size for raster rows");

    res = G_define_option();
    res->key = "resolution";
    res->type = TYPE_DOUBLE;
    res->required = NO;
    res->description = _("Resolution of output raster map");
    res->guisection = _("Target");

    list = G_define_flag();
    list->key = 'l';
    list->description = _("List raster maps in input mapset and exit");
    list->guisection = _("Print");
    
    nocrop = G_define_flag();
    nocrop->key = 'n';
    nocrop->description = _("Do not perform region cropping optimization");

    print_bounds = G_define_flag();
    print_bounds->key = 'p';
    print_bounds->description =
	_("Print input map's bounds in the current projection and exit");
    print_bounds->guisection = _("Print");
    
    gprint_bounds = G_define_flag();
    gprint_bounds->key = 'g';
    gprint_bounds->description =
	_("Print input map's bounds in the current projection and exit (shell style)");
    gprint_bounds->guisection = _("Print");

    /* The parser checks if the map already exists in current mapset,
       we switch out the check and do it
       in the module after the parser */
    overwrite = G_check_overwrite(argc, argv);

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


    /* get the method */
    for (method = 0; (ipolname = menu[method].name); method++)
	if (strcmp(ipolname, interpol->answer) == 0)
	    break;

    if (!ipolname)
	G_fatal_error(_("<%s=%s> unknown %s"),
		      interpol->key, interpol->answer, interpol->key);
    interpolate = menu[method].method;

    mapname = outmap->answer ? outmap->answer : inmap->answer;
    if (mapname && !list->answer && !overwrite &&
	!print_bounds->answer && !gprint_bounds->answer &&
	G_find_raster(mapname, G_mapset()))
	G_fatal_error(_("option <%s>: <%s> exists."), "output", mapname);

    setname = imapset->answer ? imapset->answer : G_store(G_mapset());
    if (strcmp(inlocation->answer, G_location()) == 0 &&
        (!indbase->answer || strcmp(indbase->answer, G_gisdbase()) == 0))
#if 0
	G_fatal_error(_("Input and output locations can not be the same"));
#else
	G_warning(_("Input and output locations are the same"));
#endif
    G_get_window(&outcellhd);

    if(gprint_bounds->answer && !print_bounds->answer)
	print_bounds->answer = gprint_bounds->answer;
    curr_proj = G_projection();

    /* Get projection info for output mapset */
    if ((out_proj_info = G_get_projinfo()) == NULL)
	G_fatal_error(_("Unable to get projection info of output raster map"));

    if ((out_unit_info = G_get_projunits()) == NULL)
	G_fatal_error(_("Unable to get projection units of output raster map"));

    if (pj_get_kv(&oproj, out_proj_info, out_unit_info) < 0)
	G_fatal_error(_("Unable to get projection key values of output raster map"));

    /* Change the location           */
    G_create_alt_env();
    G__setenv("GISDBASE", indbase->answer ? indbase->answer : G_gisdbase());
    G__setenv("LOCATION_NAME", inlocation->answer);

    permissions = G__mapset_permissions(setname);
    if (permissions < 0)	/* can't access mapset       */
	G_fatal_error(_("Mapset <%s> in input location <%s> - %s"),
		      setname, inlocation->answer,
		      permissions == 0 ? _("permission denied")
		      : _("not found"));

    /* if requested, list the raster maps in source location - MN 5/2001 */
    if (list->answer) {
	int i;
	char **list;
	G_verbose_message(_("Checking location <%s> mapset <%s>"),
			  inlocation->answer, setname);
	list = G_list(G_ELEMENT_RASTER, G__getenv("GISDBASE"),
		      G__getenv("LOCATION_NAME"), setname);
	for (i = 0; list[i]; i++) {
	    fprintf(stdout, "%s\n", list[i]);
	}
	fflush(stdout);
	exit(EXIT_SUCCESS);	/* leave r.proj after listing */
    }

    if (!inmap->answer)
	G_fatal_error(_("Required parameter <%s> not set"), inmap->key);

    if (!G_find_raster(inmap->answer, setname))
	G_fatal_error(_("Raster map <%s> in location <%s> in mapset <%s> not found"),
		      inmap->answer, inlocation->answer, setname);

    /* Read input map colour table */
    have_colors = Rast_read_colors(inmap->answer, setname, &colr);

    /* Get projection info for input mapset */
    if ((in_proj_info = G_get_projinfo()) == NULL)
	G_fatal_error(_("Unable to get projection info of input map"));

    if ((in_unit_info = G_get_projunits()) == NULL)
	G_fatal_error(_("Unable to get projection units of input map"));

    if (pj_get_kv(&iproj, in_proj_info, in_unit_info) < 0)
	G_fatal_error(_("Unable to get projection key values of input map"));

    G_free_key_value(in_proj_info);
    G_free_key_value(in_unit_info);
    G_free_key_value(out_proj_info);
    G_free_key_value(out_unit_info);
    if (G_verbose() > G_verbose_std())
	pj_print_proj_params(&iproj, &oproj);

    /* this call causes r.proj to read the entire map into memeory */
    Rast_get_cellhd(inmap->answer, setname, &incellhd);

    Rast_set_input_window(&incellhd);

    if (G_projection() == PROJECTION_XY)
	G_fatal_error(_("Unable to work with unprojected data (xy location)"));

    /* Save default borders so we can show them later */
    inorth = incellhd.north;
    isouth = incellhd.south;
    ieast = incellhd.east;
    iwest = incellhd.west;
    irows = incellhd.rows;
    icols = incellhd.cols;

    onorth = outcellhd.north;
    osouth = outcellhd.south;
    oeast = outcellhd.east;
    owest = outcellhd.west;
    orows = outcellhd.rows;
    ocols = outcellhd.cols;


    if (print_bounds->answer) {
	G_message(_("Input map <%s@%s> in location <%s>:"),
	    inmap->answer, setname, inlocation->answer);

	outcellhd.north = -1e9;
	outcellhd.south =  1e9;
	outcellhd.east  = -1e9;
	outcellhd.west  =  1e9;
	bordwalk2(&incellhd, &outcellhd, &iproj, &oproj);
	inorth = outcellhd.north;
	isouth = outcellhd.south;
	ieast  = outcellhd.east;
	iwest  = outcellhd.west;

	G_format_northing(inorth, north_str, curr_proj);
	G_format_northing(isouth, south_str, curr_proj);
	G_format_easting(ieast, east_str, curr_proj);
	G_format_easting(iwest, west_str, curr_proj);

	if(gprint_bounds->answer) {
	    fprintf(stdout, "n=%s s=%s w=%s e=%s rows=%d cols=%d\n",
		north_str, south_str, west_str, east_str, irows, icols);
	}
	else {
	    fprintf(stdout, "Source cols: %d\n", icols);
	    fprintf(stdout, "Source rows: %d\n", irows);
	    fprintf(stdout, "Local north: %s\n",  north_str);
	    fprintf(stdout, "Local south: %s\n", south_str);
	    fprintf(stdout, "Local west: %s\n", west_str);
	    fprintf(stdout, "Local east: %s\n", east_str);
	}

	/* somehow approximate local ewres, nsres ?? (use 'g.region -m' on lat/lon side) */

	exit(EXIT_SUCCESS);
    }


    /* Cut non-overlapping parts of input map */
    if (!nocrop->answer)
	bordwalk(&outcellhd, &incellhd, &oproj, &iproj);

    /* Add 2 cells on each side for bilinear/cubic & future interpolation methods */
    /* (should probably be a factor based on input and output resolution) */
    incellhd.north += 2 * incellhd.ns_res;
    incellhd.east += 2 * incellhd.ew_res;
    incellhd.south -= 2 * incellhd.ns_res;
    incellhd.west -= 2 * incellhd.ew_res;
    if (incellhd.north > inorth)
	incellhd.north = inorth;
    if (incellhd.east > ieast)
	incellhd.east = ieast;
    if (incellhd.south < isouth)
	incellhd.south = isouth;
    if (incellhd.west < iwest)
	incellhd.west = iwest;

    Rast_set_input_window(&incellhd);

    /* And switch back to original location */

    G_switch_env();

    /* Adjust borders of output map */

    if (!nocrop->answer)
	bordwalk(&incellhd, &outcellhd, &iproj, &oproj);

#if 0
    outcellhd.west = outcellhd.south = HUGE_VAL;
    outcellhd.east = outcellhd.north = -HUGE_VAL;
    for (row = 0; row < incellhd.rows; row++) {
	ycoord1 = Rast_row_to_northing((double)(row + 0.5), &incellhd);
	for (col = 0; col < incellhd.cols; col++) {
	    xcoord1 = Rast_col_to_easting((double)(col + 0.5), &incellhd);
	    pj_do_proj(&xcoord1, &ycoord1, &iproj, &oproj);
	    if (xcoord1 > outcellhd.east)
		outcellhd.east = xcoord1;
	    if (ycoord1 > outcellhd.north)
		outcellhd.north = ycoord1;
	    if (xcoord1 < outcellhd.west)
		outcellhd.west = xcoord1;
	    if (ycoord1 < outcellhd.south)
		outcellhd.south = ycoord1;
	}
    }
#endif

    if (res->answer != NULL)	/* set user defined resolution */
	outcellhd.ns_res = outcellhd.ew_res = atof(res->answer);

    G_adjust_Cell_head(&outcellhd, 0, 0);
    Rast_set_output_window(&outcellhd);

    G_message(" ");
    G_message(_("Input:"));
    G_message(_("Cols: %d (%d)"), incellhd.cols, icols);
    G_message(_("Rows: %d (%d)"), incellhd.rows, irows);
    G_message(_("North: %f (%f)"), incellhd.north, inorth);
    G_message(_("South: %f (%f)"), incellhd.south, isouth);
    G_message(_("West: %f (%f)"), incellhd.west, iwest);
    G_message(_("East: %f (%f)"), incellhd.east, ieast);
    G_message(_("EW-res: %f"), incellhd.ew_res);
    G_message(_("NS-res: %f"), incellhd.ns_res);
    G_message(" ");

    G_message(_("Output:"));
    G_message(_("Cols: %d (%d)"), outcellhd.cols, ocols);
    G_message(_("Rows: %d (%d)"), outcellhd.rows, orows);
    G_message(_("North: %f (%f)"), outcellhd.north, onorth);
    G_message(_("South: %f (%f)"), outcellhd.south, osouth);
    G_message(_("West: %f (%f)"), outcellhd.west, owest);
    G_message(_("East: %f (%f)"), outcellhd.east, oeast);
    G_message(_("EW-res: %f"), outcellhd.ew_res);
    G_message(_("NS-res: %f"), outcellhd.ns_res);
    G_message(" ");

    /* open and read the relevant parts of the input map and close it */
    G_switch_env();
    Rast_set_input_window(&incellhd);
    fdi = Rast_open_old(inmap->answer, setname);
    cell_type = Rast_get_map_type(fdi);
    ibuffer = readcell(fdi, memory->answer);
    Rast_close(fdi);

    G_switch_env();
    Rast_set_output_window(&outcellhd);

    if (strcmp(interpol->answer, "nearest") == 0) {
	fdo = Rast_open_new(mapname, cell_type);
	obuffer = (CELL *) Rast_allocate_output_buf(cell_type);
    }
    else {
	fdo = Rast_open_fp_new(mapname);
	cell_type = FCELL_TYPE;
	obuffer = (FCELL *) Rast_allocate_output_buf(cell_type);
    }

    cell_size = Rast_cell_size(cell_type);

    xcoord2 = outcellhd.west + (outcellhd.ew_res / 2);
    ycoord2 = outcellhd.north - (outcellhd.ns_res / 2);

    G_important_message(_("Projecting..."));
    for (row = 0; row < outcellhd.rows; row++) {
	/* obufptr = obuffer */;

        G_percent(row, outcellhd.rows - 1, 2);

#if 0
	/* parallelization does not always work,
	 * segfaults in the interpolation functions 
	 * can happen */
        #pragma omp parallel for schedule (static)
#endif

	for (col = 0; col < outcellhd.cols; col++) {
	    void *obufptr = (void *)((const unsigned char *)obuffer + col * cell_size);

	    double xcoord1 = xcoord2 + (col) * outcellhd.ew_res;
	    double ycoord1 = ycoord2;

	    /* project coordinates in output matrix to       */
	    /* coordinates in input matrix                   */
	    if (pj_do_proj(&xcoord1, &ycoord1, &oproj, &iproj) < 0)
		Rast_set_null_value(obufptr, 1, cell_type);
	    else {
		/* convert to row/column indices of input matrix */

		/* column index in input matrix */
		double col_idx = (xcoord1 - incellhd.west) / incellhd.ew_res;
		/* row index in input matrix    */
		double row_idx = (incellhd.north - ycoord1) / incellhd.ns_res;

		/* and resample data point               */
		interpolate(ibuffer, obufptr, cell_type,
			    col_idx, row_idx, &incellhd);
	    }

	    /* obufptr = G_incr_void_ptr(obufptr, cell_size); */
	}

	Rast_put_row(fdo, obuffer, cell_type);

	xcoord2 = outcellhd.west + (outcellhd.ew_res / 2);
	ycoord2 -= outcellhd.ns_res;
    }

    Rast_close(fdo);
    release_cache(ibuffer);

    if (have_colors > 0) {
	Rast_write_colors(mapname, G_mapset(), &colr);
	Rast_free_colors(&colr);
    }

    Rast_short_history(mapname, "raster", &history);
    Rast_command_history(&history);
    Rast_write_history(mapname, &history);

    G_done_msg(" ");
    exit(EXIT_SUCCESS);
}
Beispiel #9
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);

}