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); }
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, ¶ms); 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); } }
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; }
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, ¶ms); 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; }
/*! \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 }
/*! \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; }
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); }
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); }