int OGRCSVDataSource::Open( const char * pszFilename, int bUpdateIn, int bForceOpen ) { pszName = CPLStrdup( pszFilename ); bUpdate = bUpdateIn; if (bUpdateIn && bForceOpen && EQUAL(pszFilename, "/vsistdout/")) return TRUE; /* For writable /vsizip/, do nothing more */ if (bUpdateIn && bForceOpen && strncmp(pszFilename, "/vsizip/", 8) == 0) return TRUE; CPLString osFilename(pszFilename); CPLString osBaseFilename = CPLGetFilename(pszFilename); CPLString osExt = GetRealExtension(osFilename); pszFilename = NULL; int bIgnoreExtension = EQUALN(osFilename, "CSV:", 4); int bUSGeonamesFile = FALSE; int bGeonamesOrgFile = FALSE; if (bIgnoreExtension) { osFilename = osFilename + 4; } /* Those are *not* real .XLS files, but text file with tab as column separator */ if (EQUAL(osBaseFilename, "NfdcFacilities.xls") || EQUAL(osBaseFilename, "NfdcRunways.xls") || EQUAL(osBaseFilename, "NfdcRemarks.xls") || EQUAL(osBaseFilename, "NfdcSchedules.xls")) { if (bUpdateIn) return FALSE; bIgnoreExtension = TRUE; } else if ((EQUALN(osBaseFilename, "NationalFile_", 13) || EQUALN(osBaseFilename, "POP_PLACES_", 11) || EQUALN(osBaseFilename, "HIST_FEATURES_", 14) || EQUALN(osBaseFilename, "US_CONCISE_", 11) || EQUALN(osBaseFilename, "AllNames_", 9) || EQUALN(osBaseFilename, "Feature_Description_History_", 28) || EQUALN(osBaseFilename, "ANTARCTICA_", 11) || EQUALN(osBaseFilename, "GOVT_UNITS_", 11) || EQUALN(osBaseFilename, "NationalFedCodes_", 17) || EQUALN(osBaseFilename, "AllStates_", 10) || EQUALN(osBaseFilename, "AllStatesFedCodes_", 18) || (strlen(osBaseFilename) > 2 && EQUALN(osBaseFilename+2, "_Features_", 10)) || (strlen(osBaseFilename) > 2 && EQUALN(osBaseFilename+2, "_FedCodes_", 10))) && (EQUAL(osExt, "txt") || EQUAL(osExt, "zip")) ) { if (bUpdateIn) return FALSE; bIgnoreExtension = TRUE; bUSGeonamesFile = TRUE; if (EQUAL(osExt, "zip") && strstr(osFilename, "/vsizip/") == NULL ) { osFilename = "/vsizip/" + osFilename; } } else if (EQUAL(osBaseFilename, "allCountries.txt") || EQUAL(osBaseFilename, "allCountries.zip")) { if (bUpdateIn) return FALSE; bIgnoreExtension = TRUE; bGeonamesOrgFile = TRUE; if (EQUAL(osExt, "zip") && strstr(osFilename, "/vsizip/") == NULL ) { osFilename = "/vsizip/" + osFilename; } } /* -------------------------------------------------------------------- */ /* Determine what sort of object this is. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStatBuf; if( VSIStatExL( osFilename, &sStatBuf, VSI_STAT_NATURE_FLAG ) != 0 ) return FALSE; /* -------------------------------------------------------------------- */ /* Is this a single CSV file? */ /* -------------------------------------------------------------------- */ if( VSI_ISREG(sStatBuf.st_mode) && (bIgnoreExtension || EQUAL(osExt,"csv") || EQUAL(osExt,"tsv")) ) { if (EQUAL(CPLGetFilename(osFilename), "NfdcFacilities.xls")) { return OpenTable( osFilename, "ARP"); } else if (EQUAL(CPLGetFilename(osFilename), "NfdcRunways.xls")) { OpenTable( osFilename, "BaseEndPhysical"); OpenTable( osFilename, "BaseEndDisplaced"); OpenTable( osFilename, "ReciprocalEndPhysical"); OpenTable( osFilename, "ReciprocalEndDisplaced"); return nLayers != 0; } else if (bUSGeonamesFile) { /* GNIS specific */ if (EQUALN(osBaseFilename, "NationalFedCodes_", 17) || EQUALN(osBaseFilename, "AllStatesFedCodes_", 18) || EQUALN(osBaseFilename, "ANTARCTICA_", 11) || (strlen(osBaseFilename) > 2 && EQUALN(osBaseFilename+2, "_FedCodes_", 10))) { OpenTable( osFilename, NULL, "PRIMARY"); } else if (EQUALN(osBaseFilename, "GOVT_UNITS_", 11) || EQUALN(osBaseFilename, "Feature_Description_History_", 28)) { OpenTable( osFilename, NULL, ""); } else { OpenTable( osFilename, NULL, "PRIM"); OpenTable( osFilename, NULL, "SOURCE"); } return nLayers != 0; } return OpenTable( osFilename ); } /* -------------------------------------------------------------------- */ /* Is this a single a ZIP file with only a CSV file inside ? */ /* -------------------------------------------------------------------- */ if( strncmp(osFilename, "/vsizip/", 8) == 0 && EQUAL(osExt, "zip") && VSI_ISREG(sStatBuf.st_mode) ) { char** papszFiles = VSIReadDir(osFilename); if (CSLCount(papszFiles) != 1 || !EQUAL(CPLGetExtension(papszFiles[0]), "CSV")) { CSLDestroy(papszFiles); return FALSE; } osFilename = CPLFormFilename(osFilename, papszFiles[0], NULL); CSLDestroy(papszFiles); return OpenTable( osFilename ); } /* -------------------------------------------------------------------- */ /* Otherwise it has to be a directory. */ /* -------------------------------------------------------------------- */ if( !VSI_ISDIR(sStatBuf.st_mode) ) return FALSE; /* -------------------------------------------------------------------- */ /* Scan through for entries ending in .csv. */ /* -------------------------------------------------------------------- */ int nNotCSVCount = 0, i; char **papszNames = CPLReadDir( osFilename ); for( i = 0; papszNames != NULL && papszNames[i] != NULL; i++ ) { CPLString oSubFilename = CPLFormFilename( osFilename, papszNames[i], NULL ); if( EQUAL(papszNames[i],".") || EQUAL(papszNames[i],"..") ) continue; if (EQUAL(CPLGetExtension(oSubFilename),"csvt")) continue; if( VSIStatL( oSubFilename, &sStatBuf ) != 0 || !VSI_ISREG(sStatBuf.st_mode) ) { nNotCSVCount++; continue; } if (EQUAL(CPLGetExtension(oSubFilename),"csv")) { if( !OpenTable( oSubFilename ) ) { CPLDebug("CSV", "Cannot open %s", oSubFilename.c_str()); nNotCSVCount++; continue; } } /* GNIS specific */ else if ( strlen(papszNames[i]) > 2 && EQUALN(papszNames[i]+2, "_Features_", 10) && EQUAL(CPLGetExtension(papszNames[i]), "txt") ) { int bRet = OpenTable( oSubFilename, NULL, "PRIM"); bRet |= OpenTable( oSubFilename, NULL, "SOURCE"); if ( !bRet ) { CPLDebug("CSV", "Cannot open %s", oSubFilename.c_str()); nNotCSVCount++; continue; } } /* GNIS specific */ else if ( strlen(papszNames[i]) > 2 && EQUALN(papszNames[i]+2, "_FedCodes_", 10) && EQUAL(CPLGetExtension(papszNames[i]), "txt") ) { if ( !OpenTable( oSubFilename, NULL, "PRIMARY") ) { CPLDebug("CSV", "Cannot open %s", oSubFilename.c_str()); nNotCSVCount++; continue; } } else { nNotCSVCount++; continue; } } CSLDestroy( papszNames ); /* -------------------------------------------------------------------- */ /* We presume that this is indeed intended to be a CSV */ /* datasource if over half the files were .csv files. */ /* -------------------------------------------------------------------- */ return bForceOpen || nNotCSVCount < nLayers; }
static void OGR2SQLITE_ogr_geocode_reverse(sqlite3_context* pContext, int argc, sqlite3_value** argv) { OGRSQLiteExtensionData* poModule = (OGRSQLiteExtensionData*) sqlite3_user_data(pContext); double dfLon = 0.0, dfLat = 0.0; int iAfterGeomIdx = 0; int bGotLon = FALSE, bGotLat = FALSE; if( argc >= 2 ) { dfLon = OGR2SQLITE_GetValAsDouble(argv[0], &bGotLon); dfLat = OGR2SQLITE_GetValAsDouble(argv[1], &bGotLat); } if( argc >= 3 && bGotLon && bGotLat && sqlite3_value_type (argv[2]) == SQLITE_TEXT ) { iAfterGeomIdx = 2; } else if( argc >= 2 && sqlite3_value_type (argv[0]) == SQLITE_BLOB && sqlite3_value_type (argv[1]) == SQLITE_TEXT ) { OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, NULL); if( poGeom != NULL && wkbFlatten(poGeom->getGeometryType()) == wkbPoint ) { OGRPoint* poPoint = (OGRPoint*) poGeom; dfLon = poPoint->getX(); dfLat = poPoint->getY(); delete poGeom; } else { delete poGeom; sqlite3_result_null (pContext); return; } iAfterGeomIdx = 1; } else { sqlite3_result_null (pContext); return; } const char* pszField = (const char*)sqlite3_value_text(argv[iAfterGeomIdx]); int i; char** papszOptions = NULL; for(i = iAfterGeomIdx + 1; i < argc; i++) { if( sqlite3_value_type (argv[i]) == SQLITE_TEXT ) { papszOptions = CSLAddString(papszOptions, (const char*)sqlite3_value_text(argv[i])); } } OGRGeocodingSessionH hSession = poModule->GetGeocodingSession(); if( hSession == NULL ) { hSession = OGRGeocodeCreateSession(papszOptions); if( hSession == NULL ) { sqlite3_result_null (pContext); CSLDestroy(papszOptions); return; } poModule->SetGeocodingSession(hSession); } if( strcmp(pszField, "raw") == 0 ) papszOptions = CSLAddString(papszOptions, "RAW_FEATURE=YES"); OGRLayerH hLayer = OGRGeocodeReverse(hSession, dfLon, dfLat, papszOptions); OGR2SQLITE_ogr_geocode_set_result(pContext, hLayer, pszField); CSLDestroy(papszOptions); return; }
void *GDALDeserializeRPCTransformer( CPLXMLNode *psTree ) { void *pResult; char **papszOptions = NULL; /* -------------------------------------------------------------------- */ /* Collect metadata. */ /* -------------------------------------------------------------------- */ char **papszMD = NULL; CPLXMLNode *psMDI, *psMetadata; GDALRPCInfo sRPC; psMetadata = CPLGetXMLNode( psTree, "Metadata" ); if( psMetadata == NULL || psMetadata->eType != CXT_Element || !EQUAL(psMetadata->pszValue,"Metadata") ) return NULL; for( psMDI = psMetadata->psChild; psMDI != NULL; psMDI = psMDI->psNext ) { if( !EQUAL(psMDI->pszValue,"MDI") || psMDI->eType != CXT_Element || psMDI->psChild == NULL || psMDI->psChild->psNext == NULL || psMDI->psChild->eType != CXT_Attribute || psMDI->psChild->psChild == NULL ) continue; papszMD = CSLSetNameValue( papszMD, psMDI->psChild->psChild->pszValue, psMDI->psChild->psNext->pszValue ); } if( !GDALExtractRPCInfo( papszMD, &sRPC ) ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to reconstitute RPC transformer." ); CSLDestroy( papszMD ); return NULL; } CSLDestroy( papszMD ); /* -------------------------------------------------------------------- */ /* Get other flags. */ /* -------------------------------------------------------------------- */ double dfPixErrThreshold; int bReversed; bReversed = atoi(CPLGetXMLValue(psTree,"Reversed","0")); dfPixErrThreshold = CPLAtof(CPLGetXMLValue(psTree,"PixErrThreshold","0.25")); papszOptions = CSLSetNameValue( papszOptions, "RPC_HEIGHT", CPLGetXMLValue(psTree,"HeightOffset","0")); papszOptions = CSLSetNameValue( papszOptions, "RPC_HEIGHT_SCALE", CPLGetXMLValue(psTree,"HeightScale","1")); const char* pszDEMPath = CPLGetXMLValue(psTree,"DEMPath",NULL); if (pszDEMPath != NULL) papszOptions = CSLSetNameValue( papszOptions, "RPC_DEM", pszDEMPath); const char* pszDEMInterpolation = CPLGetXMLValue(psTree,"DEMInterpolation", "bilinear"); if (pszDEMInterpolation != NULL) papszOptions = CSLSetNameValue( papszOptions, "RPC_DEMINTERPOLATION", pszDEMInterpolation); /* -------------------------------------------------------------------- */ /* Generate transformation. */ /* -------------------------------------------------------------------- */ pResult = GDALCreateRPCTransformer( &sRPC, bReversed, dfPixErrThreshold, papszOptions ); CSLDestroy( papszOptions ); return pResult; }
static GDALDataset *OGRCADDriverOpen( GDALOpenInfo* poOpenInfo ) { long nSubRasterLayer = -1; long nSubRasterFID = -1; CADFileIO* pFileIO; if ( STARTS_WITH_CI(poOpenInfo->pszFilename, "CAD:") ) { char** papszTokens = CSLTokenizeString2( poOpenInfo->pszFilename, ":", 0 ); int nTokens = CSLCount( papszTokens ); if( nTokens < 4 ) { CSLDestroy(papszTokens); return NULL; } CPLString osFilename; for( int i = 1; i < nTokens - 2; ++i ) { if( osFilename.empty() ) osFilename += ":"; osFilename += papszTokens[i]; } pFileIO = new VSILFileIO( osFilename ); nSubRasterLayer = atol( papszTokens[nTokens - 2] ); nSubRasterFID = atol( papszTokens[nTokens - 1] ); CSLDestroy( papszTokens ); } else { pFileIO = new VSILFileIO( poOpenInfo->pszFilename ); } if ( IdentifyCADFile( pFileIO, false ) == FALSE ) { delete pFileIO; return NULL; } /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The CAD driver does not support update access to existing" " datasets.\n" ); delete pFileIO; return NULL; } GDALCADDataset *poDS = new GDALCADDataset(); if( !poDS->Open( poOpenInfo, pFileIO, nSubRasterLayer, nSubRasterFID ) ) { delete poDS; return NULL; } else return poDS; }
int main( int nArgc, char ** papszArgv ) { OGRSpatialReference oSRS; int i; int bReportXML = FALSE; /* -------------------------------------------------------------------- */ /* Processing command line arguments. */ /* -------------------------------------------------------------------- */ nArgc = OGRGeneralCmdLineProcessor( nArgc, &papszArgv, 0 ); if( nArgc < 2 ) Usage(); for( i = 1; i < nArgc; i++ ) { if( EQUAL(papszArgv[i],"-xml") ) bReportXML = TRUE; else if( EQUAL(papszArgv[i],"-t") && i < nArgc - 4 ) { OGRSpatialReference oSourceSRS, oTargetSRS; OGRCoordinateTransformation *poCT; double x, y, z_orig, z; int nArgsUsed = 4; if( oSourceSRS.SetFromUserInput(papszArgv[i+1]) != OGRERR_NONE ) { CPLError( CE_Failure, CPLE_AppDefined, "SetFromUserInput(%s) failed.", papszArgv[i+1] ); continue; } if( oTargetSRS.SetFromUserInput(papszArgv[i+2]) != OGRERR_NONE ) { CPLError( CE_Failure, CPLE_AppDefined, "SetFromUserInput(%s) failed.", papszArgv[i+2] ); continue; } poCT = OGRCreateCoordinateTransformation( &oSourceSRS, &oTargetSRS ); x = atof( papszArgv[i+3] ); y = atof( papszArgv[i+4] ); if( i < nArgc - 5 && (atof(papszArgv[i+5]) > 0.0 || papszArgv[i+5][0] == '0') ) { z_orig = z = atof(papszArgv[i+5]); nArgsUsed++; } else z_orig = z = 0; if( poCT == NULL || !poCT->Transform( 1, &x, &y, &z ) ) printf( "Transformation failed.\n" ); else printf( "(%f,%f,%f) -> (%f,%f,%f)\n", atof( papszArgv[i+3] ), atof( papszArgv[i+4] ), z_orig, x, y, z ); i += nArgsUsed; } else { if( oSRS.SetFromUserInput(papszArgv[i]) != OGRERR_NONE ) CPLError( CE_Failure, CPLE_AppDefined, "Error occured translating %s.\n", papszArgv[i] ); else { char *pszWKT = NULL; if( oSRS.Validate() != OGRERR_NONE ) printf( "Validate Fails.\n" ); else printf( "Validate Succeeds.\n" ); oSRS.exportToPrettyWkt( &pszWKT, FALSE ); printf( "WKT[%s] =\n%s\n", papszArgv[i], pszWKT ); CPLFree( pszWKT ); printf( "\n" ); oSRS.exportToPrettyWkt( &pszWKT, TRUE ); printf( "Simplified WKT[%s] =\n%s\n", papszArgv[i], pszWKT ); CPLFree( pszWKT ); printf( "\n" ); OGRSpatialReference *poSRS2; poSRS2 = oSRS.Clone(); poSRS2->StripCTParms(); poSRS2->exportToWkt( &pszWKT ); printf( "Old Style WKT[%s] = %s\n", papszArgv[i], pszWKT ); CPLFree( pszWKT ); OGRSpatialReference::DestroySpatialReference( poSRS2 ); poSRS2 = oSRS.Clone(); poSRS2->morphToESRI(); poSRS2->exportToPrettyWkt( &pszWKT, FALSE ); printf( "ESRI'ified WKT[%s] = \n%s\n", papszArgv[i], pszWKT ); CPLFree( pszWKT ); OGRSpatialReference::DestroySpatialReference( poSRS2 ); oSRS.exportToProj4( &pszWKT ); printf( "PROJ.4 rendering of [%s] = %s\n", papszArgv[i], pszWKT ); CPLFree( pszWKT ); if( bReportXML ) { char *pszRawXML; if( oSRS.exportToXML(&pszRawXML) == OGRERR_NONE ) { printf( "XML[%s] =\n%s\n", papszArgv[i], pszRawXML ); CPLFree( pszRawXML ); } else { printf( "XML translation failed\n" ); } } printf( "\n" ); } } } CSLDestroy( papszArgv ); OSRCleanup(); CPLFinderClean(); CPLCleanupTLS(); return 0; }
int FindSRS( const char *pszInput, OGRSpatialReference &oSRS ) { int bGotSRS = FALSE; VSILFILE *fp = NULL; GDALDataset *poGDALDS = NULL; OGRLayer *poLayer = NULL; const char *pszProjection = NULL; CPLErrorHandler oErrorHandler = NULL; int bIsFile = FALSE; OGRErr eErr = OGRERR_NONE; int bDebug = FALSE; /* temporarily suppress error messages we may get from xOpen() */ bDebug = CSLTestBoolean(CPLGetConfigOption("CPL_DEBUG", "OFF")); if ( ! bDebug ) oErrorHandler = CPLSetErrorHandler ( CPLQuietErrorHandler ); /* Test if argument is a file */ fp = VSIFOpenL( pszInput, "r" ); if ( fp ) { bIsFile = TRUE; VSIFCloseL( fp ); CPLDebug( "gdalsrsinfo", "argument is a file" ); } /* try to open with GDAL */ if( strncmp(pszInput, "http://spatialreference.org/", strlen("http://spatialreference.org/")) != 0 ) { CPLDebug( "gdalsrsinfo", "trying to open with GDAL" ); poGDALDS = (GDALDataset *) GDALOpenEx( pszInput, 0, NULL, NULL, NULL ); } if ( poGDALDS != NULL ) { pszProjection = poGDALDS->GetProjectionRef( ); if( pszProjection != NULL && pszProjection[0] != '\0' ) { char* pszProjectionTmp = (char*) pszProjection; if( oSRS.importFromWkt( &pszProjectionTmp ) == OGRERR_NONE ) { CPLDebug( "gdalsrsinfo", "got SRS from GDAL" ); bGotSRS = TRUE; } } else if( poGDALDS->GetLayerCount() > 0 ) { poLayer = poGDALDS->GetLayer( 0 ); if ( poLayer != NULL ) { OGRSpatialReference *poSRS = poLayer->GetSpatialRef( ); if ( poSRS != NULL ) { CPLDebug( "gdalsrsinfo", "got SRS from OGR" ); bGotSRS = TRUE; OGRSpatialReference* poSRSClone = poSRS->Clone(); oSRS = *poSRSClone; OGRSpatialReference::DestroySpatialReference( poSRSClone ); } } } GDALClose( (GDALDatasetH) poGDALDS ); if ( ! bGotSRS ) CPLDebug( "gdalsrsinfo", "did not open with GDAL" ); } /* Try ESRI file */ if ( ! bGotSRS && bIsFile && (strstr(pszInput,".prj") != NULL) ) { CPLDebug( "gdalsrsinfo", "trying to get SRS from ESRI .prj file [%s]", pszInput ); char **pszTemp; if ( strstr(pszInput,"ESRI::") != NULL ) pszTemp = CSLLoad( pszInput+6 ); else pszTemp = CSLLoad( pszInput ); if( pszTemp ) { eErr = oSRS.importFromESRI( pszTemp ); CSLDestroy( pszTemp ); } else eErr = OGRERR_UNSUPPORTED_SRS; if( eErr != OGRERR_NONE ) { CPLDebug( "gdalsrsinfo", "did not get SRS from ESRI .prj file" ); } else { CPLDebug( "gdalsrsinfo", "got SRS from ESRI .prj file" ); bGotSRS = TRUE; } } /* Last resort, try OSRSetFromUserInput() */ if ( ! bGotSRS ) { CPLDebug( "gdalsrsinfo", "trying to get SRS from user input [%s]", pszInput ); eErr = oSRS.SetFromUserInput( pszInput ); if( eErr != OGRERR_NONE ) { CPLDebug( "gdalsrsinfo", "did not get SRS from user input" ); } else { CPLDebug( "gdalsrsinfo", "got SRS from user input" ); bGotSRS = TRUE; } } /* restore error messages */ if ( ! bDebug ) CPLSetErrorHandler ( oErrorHandler ); return bGotSRS; }
OGRErr OGRSpatialReference::importFromOzi( const char *pszDatum, const char *pszProj, const char *pszProjParms ) { Clear(); /* -------------------------------------------------------------------- */ /* Operate on the basis of the projection name. */ /* -------------------------------------------------------------------- */ char **papszProj = CSLTokenizeStringComplex( pszProj, ",", TRUE, TRUE ); char **papszProjParms = CSLTokenizeStringComplex( pszProjParms, ",", TRUE, TRUE ); char **papszDatum = NULL; if (CSLCount(papszProj) < 2) { goto not_enough_data; } if ( EQUALN(papszProj[1], "Latitude/Longitude", 18) ) { } else if ( EQUALN(papszProj[1], "Mercator", 8) ) { if (CSLCount(papszProjParms) < 6) goto not_enough_data; double dfScale = CPLAtof(papszProjParms[3]); if (papszProjParms[3][0] == 0) dfScale = 1; /* if unset, default to scale = 1 */ SetMercator( CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), dfScale, CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Transverse Mercator", 19) ) { if (CSLCount(papszProjParms) < 6) goto not_enough_data; SetTM( CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[3]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Lambert Conformal Conic", 23) ) { if (CSLCount(papszProjParms) < 8) goto not_enough_data; SetLCC( CPLAtof(papszProjParms[6]), CPLAtof(papszProjParms[7]), CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Sinusoidal", 10) ) { if (CSLCount(papszProjParms) < 6) goto not_enough_data; SetSinusoidal( CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Albers Equal Area", 17) ) { if (CSLCount(papszProjParms) < 8) goto not_enough_data; SetACEA( CPLAtof(papszProjParms[6]), CPLAtof(papszProjParms[7]), CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else { CPLDebug( "OSR_Ozi", "Unsupported projection: \"%s\"", papszProj[1] ); SetLocalCS( CPLString().Printf("\"Ozi\" projection \"%s\"", papszProj[1]) ); } /* -------------------------------------------------------------------- */ /* Try to translate the datum/spheroid. */ /* -------------------------------------------------------------------- */ papszDatum = CSLTokenizeString2( pszDatum, ",", CSLT_ALLOWEMPTYTOKENS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES ); if ( papszDatum == NULL) goto not_enough_data; if ( !IsLocal() ) { /* -------------------------------------------------------------------- */ /* Verify that we can find the CSV file containing the datums */ /* -------------------------------------------------------------------- */ if( CSVScanFileByName( CSVFilename( "ozi_datum.csv" ), "EPSG_DATUM_CODE", "4326", CC_Integer ) == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to open OZI support file %s.\n" "Try setting the GDAL_DATA environment variable to point\n" "to the directory containing OZI csv files.", CSVFilename( "ozi_datum.csv" ) ); goto other_error; } /* -------------------------------------------------------------------- */ /* Search for matching datum */ /* -------------------------------------------------------------------- */ const char *pszOziDatum = CSVFilename( "ozi_datum.csv" ); CPLString osDName = CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "NAME" ); if( strlen(osDName) == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to find datum %s in ozi_datum.csv.", papszDatum[0] ); goto other_error; } int nDatumCode = atoi( CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "EPSG_DATUM_CODE" ) ); if ( nDatumCode > 0 ) // There is a matching EPSG code { OGRSpatialReference oGCS; oGCS.importFromEPSG( nDatumCode ); CopyGeogCSFrom( &oGCS ); } else // We use the parameters from the CSV files { CPLString osEllipseCode = CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "ELLIPSOID_CODE" ); double dfDeltaX = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "DELTAX" ) ); double dfDeltaY = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "DELTAY" ) ); double dfDeltaZ = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "DELTAZ" ) ); /* -------------------------------------------------------------------- */ /* Verify that we can find the CSV file containing the ellipsoids */ /* -------------------------------------------------------------------- */ if( CSVScanFileByName( CSVFilename( "ozi_ellips.csv" ), "ELLIPSOID_CODE", "20", CC_Integer ) == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to open OZI support file %s.\n" "Try setting the GDAL_DATA environment variable to point\n" "to the directory containing OZI csv files.", CSVFilename( "ozi_ellips.csv" ) ); goto other_error; } /* -------------------------------------------------------------------- */ /* Lookup the ellipse code. */ /* -------------------------------------------------------------------- */ const char *pszOziEllipse = CSVFilename( "ozi_ellips.csv" ); CPLString osEName = CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode, CC_ApproxString, "NAME" ); if( strlen(osEName) == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to find ellipsoid %s in ozi_ellips.csv.", osEllipseCode.c_str() ); goto other_error; } double dfA = CPLAtof(CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode, CC_ApproxString, "A" )); double dfInvF = CPLAtof(CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode, CC_ApproxString, "INVF" )); /* -------------------------------------------------------------------- */ /* Create geographic coordinate system. */ /* -------------------------------------------------------------------- */ SetGeogCS( osDName, osDName, osEName, dfA, dfInvF ); SetTOWGS84( dfDeltaX, dfDeltaY, dfDeltaZ ); } } /* -------------------------------------------------------------------- */ /* Grid units translation */ /* -------------------------------------------------------------------- */ if( IsLocal() || IsProjected() ) SetLinearUnits( SRS_UL_METER, 1.0 ); FixupOrdering(); CSLDestroy(papszProj); CSLDestroy(papszProjParms); CSLDestroy(papszDatum); return OGRERR_NONE; not_enough_data: CSLDestroy(papszProj); CSLDestroy(papszProjParms); CSLDestroy(papszDatum); return OGRERR_NOT_ENOUGH_DATA; other_error: CSLDestroy(papszProj); CSLDestroy(papszProjParms); CSLDestroy(papszDatum); return OGRERR_FAILURE; }
int OGRCARTODBDataSource::Open( const char * pszFilename, char** papszOpenOptions, int bUpdateIn ) { bReadWrite = bUpdateIn; bBatchInsert = CSLTestBoolean(CSLFetchNameValueDef(papszOpenOptions, "BATCH_INSERT", "YES")); pszName = CPLStrdup( pszFilename ); if( CSLFetchNameValue(papszOpenOptions, "ACCOUNT") ) pszAccount = CPLStrdup(CSLFetchNameValue(papszOpenOptions, "ACCOUNT")); else { pszAccount = CPLStrdup(pszFilename + strlen("CARTODB:")); char* pchSpace = strchr(pszAccount, ' '); if( pchSpace ) *pchSpace = '\0'; if( pszAccount[0] == 0 ) { CPLError(CE_Failure, CPLE_AppDefined, "Missing account name"); return FALSE; } } osAPIKey = CSLFetchNameValueDef(papszOpenOptions, "API_KEY", CPLGetConfigOption("CARTODB_API_KEY", "")); CPLString osTables = OGRCARTODBGetOptionValue(pszFilename, "tables"); /*if( osTables.size() == 0 && osAPIKey.size() == 0 ) { CPLError(CE_Failure, CPLE_AppDefined, "When not specifying tables option, CARTODB_API_KEY must be defined"); return FALSE; }*/ bUseHTTPS = CSLTestBoolean(CPLGetConfigOption("CARTODB_HTTPS", "YES")); OGRLayer* poSchemaLayer = ExecuteSQLInternal("SELECT current_schema()"); if( poSchemaLayer ) { OGRFeature* poFeat = poSchemaLayer->GetNextFeature(); if( poFeat ) { if( poFeat->GetFieldCount() == 1 ) { osCurrentSchema = poFeat->GetFieldAsString(0); } delete poFeat; } ReleaseResultSet(poSchemaLayer); } if( osCurrentSchema.size() == 0 ) return FALSE; if( osAPIKey.size() && bUpdateIn ) { ExecuteSQLInternal( "DROP FUNCTION IF EXISTS ogr_table_metadata(TEXT,TEXT); " "CREATE OR REPLACE FUNCTION ogr_table_metadata(schema_name TEXT, table_name TEXT) RETURNS TABLE " "(attname TEXT, typname TEXT, attlen INT, format_type TEXT, " "attnum INT, attnotnull BOOLEAN, indisprimary BOOLEAN, " "defaultexpr TEXT, dim INT, srid INT, geomtyp TEXT, srtext TEXT) AS $$ " "SELECT a.attname::text, t.typname::text, a.attlen::int, " "format_type(a.atttypid,a.atttypmod)::text, " "a.attnum::int, " "a.attnotnull::boolean, " "i.indisprimary::boolean, " "pg_get_expr(def.adbin, c.oid)::text AS defaultexpr, " "(CASE WHEN t.typname = 'geometry' THEN postgis_typmod_dims(a.atttypmod) ELSE NULL END)::int dim, " "(CASE WHEN t.typname = 'geometry' THEN postgis_typmod_srid(a.atttypmod) ELSE NULL END)::int srid, " "(CASE WHEN t.typname = 'geometry' THEN postgis_typmod_type(a.atttypmod) ELSE NULL END)::text geomtyp, " "srtext " "FROM pg_class c " "JOIN pg_attribute a ON a.attnum > 0 AND " "a.attrelid = c.oid AND c.relname = $2 " "AND c.relname IN (SELECT CDB_UserTables())" "JOIN pg_type t ON a.atttypid = t.oid " "JOIN pg_namespace n ON c.relnamespace=n.oid AND n.nspname = $1 " "LEFT JOIN pg_index i ON c.oid = i.indrelid AND " "i.indisprimary = 't' AND a.attnum = ANY(i.indkey) " "LEFT JOIN pg_attrdef def ON def.adrelid = c.oid AND " "def.adnum = a.attnum " "LEFT JOIN spatial_ref_sys srs ON srs.srid = postgis_typmod_srid(a.atttypmod) " "ORDER BY a.attnum " "$$ LANGUAGE SQL"); } if (osTables.size() != 0) { char** papszTables = CSLTokenizeString2(osTables, ",", 0); for(int i=0;papszTables && papszTables[i];i++) { papoLayers = (OGRCARTODBTableLayer**) CPLRealloc( papoLayers, (nLayers + 1) * sizeof(OGRCARTODBTableLayer*)); papoLayers[nLayers ++] = new OGRCARTODBTableLayer(this, papszTables[i]); } CSLDestroy(papszTables); return TRUE; } OGRLayer* poTableListLayer = ExecuteSQLInternal("SELECT CDB_UserTables()"); if( poTableListLayer ) { OGRFeature* poFeat; while( (poFeat = poTableListLayer->GetNextFeature()) != NULL ) { if( poFeat->GetFieldCount() == 1 ) { papoLayers = (OGRCARTODBTableLayer**) CPLRealloc( papoLayers, (nLayers + 1) * sizeof(OGRCARTODBTableLayer*)); papoLayers[nLayers ++] = new OGRCARTODBTableLayer( this, poFeat->GetFieldAsString(0)); } delete poFeat; } ReleaseResultSet(poTableListLayer); } else if( osCurrentSchema == "public" ) return FALSE; /* There's currently a bug with CDB_UserTables() on multi-user accounts */ if( nLayers == 0 && osCurrentSchema != "public" ) { CPLString osSQL; osSQL.Printf("SELECT c.relname FROM pg_class c, pg_namespace n " "WHERE c.relkind in ('r', 'v') AND c.relname !~ '^pg_' AND c.relnamespace=n.oid AND n.nspname = '%s'", OGRCARTODBEscapeLiteral(osCurrentSchema).c_str()); poTableListLayer = ExecuteSQLInternal(osSQL); if( poTableListLayer ) { OGRFeature* poFeat; while( (poFeat = poTableListLayer->GetNextFeature()) != NULL ) { if( poFeat->GetFieldCount() == 1 ) { papoLayers = (OGRCARTODBTableLayer**) CPLRealloc( papoLayers, (nLayers + 1) * sizeof(OGRCARTODBTableLayer*)); papoLayers[nLayers ++] = new OGRCARTODBTableLayer( this, poFeat->GetFieldAsString(0)); } delete poFeat; } ReleaseResultSet(poTableListLayer); } else return FALSE; } return TRUE; }
json_object* OGRCARTODBDataSource::RunSQL(const char* pszUnescapedSQL) { CPLString osSQL("POSTFIELDS=q="); /* Do post escaping */ for(int i=0;pszUnescapedSQL[i] != 0;i++) { const int ch = ((unsigned char*)pszUnescapedSQL)[i]; if (ch != '&' && ch >= 32 && ch < 128) osSQL += (char)ch; else osSQL += CPLSPrintf("%%%02X", ch); } /* -------------------------------------------------------------------- */ /* Provide the API Key */ /* -------------------------------------------------------------------- */ if( osAPIKey.size() ) { osSQL += "&api_key="; osSQL += osAPIKey; } /* -------------------------------------------------------------------- */ /* Collection the header options and execute request. */ /* -------------------------------------------------------------------- */ const char* pszAPIURL = GetAPIURL(); char** papszOptions = CSLAddString( strncmp(pszAPIURL, "/vsimem/", strlen("/vsimem/")) != 0 ? AddHTTPOptions(): NULL, osSQL); CPLHTTPResult * psResult = CPLHTTPFetch( GetAPIURL(), papszOptions); CSLDestroy(papszOptions); /* -------------------------------------------------------------------- */ /* Check for some error conditions and report. HTML Messages */ /* are transformed info failure. */ /* -------------------------------------------------------------------- */ if (psResult && psResult->pszContentType && strncmp(psResult->pszContentType, "text/html", 9) == 0) { CPLDebug( "CARTODB", "RunSQL HTML Response:%s", psResult->pabyData ); CPLError(CE_Failure, CPLE_AppDefined, "HTML error page returned by server"); CPLHTTPDestroyResult(psResult); return NULL; } if (psResult && psResult->pszErrBuf != NULL) { CPLDebug( "CARTODB", "RunSQL Error Message:%s", psResult->pszErrBuf ); } else if (psResult && psResult->nStatus != 0) { CPLDebug( "CARTODB", "RunSQL Error Status:%d", psResult->nStatus ); } if( psResult->pabyData == NULL ) { CPLHTTPDestroyResult(psResult); return NULL; } if( strlen((const char*)psResult->pabyData) < 1000 ) CPLDebug( "CARTODB", "RunSQL Response:%s", psResult->pabyData ); json_tokener* jstok = NULL; json_object* poObj = NULL; jstok = json_tokener_new(); poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1); if( jstok->err != json_tokener_success) { CPLError( CE_Failure, CPLE_AppDefined, "JSON parsing error: %s (at offset %d)", json_tokener_error_desc(jstok->err), jstok->char_offset); json_tokener_free(jstok); CPLHTTPDestroyResult(psResult); return NULL; } json_tokener_free(jstok); CPLHTTPDestroyResult(psResult); if( poObj != NULL ) { if( json_object_get_type(poObj) == json_type_object ) { json_object* poError = json_object_object_get(poObj, "error"); if( poError != NULL && json_object_get_type(poError) == json_type_array && json_object_array_length(poError) > 0 ) { poError = json_object_array_get_idx(poError, 0); if( poError != NULL && json_object_get_type(poError) == json_type_string ) { CPLError(CE_Failure, CPLE_AppDefined, "Error returned by server : %s", json_object_get_string(poError)); json_object_put(poObj); return NULL; } } } else { json_object_put(poObj); return NULL; } } return poObj; }
int ILI1Reader::ReadTable(CPL_UNUSED const char *layername) { char **tokens = NULL; int ret = TRUE; int warned = FALSE; int geomIdx = -1; OGRFeatureDefn *featureDef = curLayer->GetLayerDefn(); OGRFeature *feature = NULL; bool bFeatureAdded = false; while (ret && (tokens = ReadParseLine()) != NULL) { const char *firsttok = CSLGetField(tokens, 0); if (EQUAL(firsttok, "OBJE")) { if (featureDef->GetFieldCount() == 0) { CPLError( CE_Warning, CPLE_AppDefined, "No field definition found for table: %s", featureDef->GetName() ); // Model not read - use heuristics. for( int fIndex=1; fIndex<CSLCount(tokens); fIndex++ ) { char szFieldName[32]; snprintf(szFieldName, sizeof(szFieldName), "Field%02d", fIndex); OGRFieldDefn oFieldDefn(szFieldName, OFTString); featureDef->AddFieldDefn(&oFieldDefn); } } //start new feature if( !bFeatureAdded ) delete feature; feature = new OGRFeature(featureDef); for( int fIndex=1, fieldno = 0; fIndex<CSLCount(tokens) && fieldno < featureDef->GetFieldCount(); fIndex++, fieldno++ ) { if (!(tokens[fIndex][0] == codeUndefined && tokens[fIndex][1] == '\0')) { #ifdef DEBUG_VERBOSE CPLDebug( "READ TABLE OGR_ILI", "Setting Field %d (Type %d): %s", fieldno, featureDef->GetFieldDefn(fieldno)->GetType(), tokens[fIndex] ); #endif if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTString) { // Interlis 1 encoding is ISO 8859-1 (Latin1) -> Recode to UTF-8 char* pszRecoded = CPLRecode( tokens[fIndex], CPL_ENC_ISO8859_1, CPL_ENC_UTF8); // Replace space marks for( char* pszString = pszRecoded; *pszString != '\0'; pszString++ ) { if (*pszString == codeBlank) *pszString = ' '; } feature->SetField(fieldno, pszRecoded); CPLFree(pszRecoded); } else { feature->SetField(fieldno, tokens[fIndex]); } if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTReal && fieldno > 0 && featureDef->GetFieldDefn(fieldno-1)->GetType() == OFTReal) { // Check for Point geometry (Coord type). // If there is no ili model read, // we have no chance to detect the // geometry column. CPLString geomfldname = featureDef->GetFieldDefn(fieldno)->GetNameRef(); // Check if name ends with _1. if (geomfldname.size() >= 2 && geomfldname[geomfldname.size()-2] == '_') { geomfldname = geomfldname.substr(0, geomfldname.size()-2); geomIdx = featureDef->GetGeomFieldIndex(geomfldname.c_str()); if (geomIdx == -1) { CPLError( CE_Warning, CPLE_AppDefined, "No matching definition for field '%s' of " "table %s found", geomfldname.c_str(), featureDef->GetName() ); } } else { geomIdx = -1; } if (geomIdx >= 0) { if (featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint) { // Add Point geometry. OGRPoint *ogrPoint = new OGRPoint( CPLAtof(tokens[fIndex-1]), CPLAtof(tokens[fIndex])); feature->SetGeomFieldDirectly(geomIdx, ogrPoint); } else if (featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint25D && fieldno > 1 && featureDef->GetFieldDefn(fieldno-2)->GetType() == OFTReal) { // Add 3D Point geometry. OGRPoint *ogrPoint = new OGRPoint( CPLAtof(tokens[fIndex-2]), CPLAtof(tokens[fIndex-1]), CPLAtof(tokens[fIndex]) ); feature->SetGeomFieldDirectly(geomIdx, ogrPoint); } } } } } if (!warned && featureDef->GetFieldCount() != CSLCount(tokens)-1) { CPLError( CE_Warning, CPLE_AppDefined, "Field count of table %s doesn't match. %d declared, " "%d found (e.g. ignored LINEATTR)", featureDef->GetName(), featureDef->GetFieldCount(), CSLCount(tokens) - 1 ); warned = TRUE; } if (feature->GetFieldCount() > 0) { // USE _TID as FID. TODO: respect IDENT field from model. feature->SetFID(feature->GetFieldAsInteger64(0)); } curLayer->AddFeature(feature); bFeatureAdded = true; geomIdx = -1; //Reset } else if (EQUAL(firsttok, "STPT") && feature != NULL) { //Find next non-Point geometry if (geomIdx < 0) geomIdx = 0; while (geomIdx < featureDef->GetGeomFieldCount() && featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint) { geomIdx++; } OGRwkbGeometryType geomType = (geomIdx < featureDef->GetGeomFieldCount()) ? featureDef->GetGeomFieldDefn(geomIdx)->GetType() : wkbNone; ReadGeom(tokens, geomIdx, geomType, feature); } else if (EQUAL(firsttok, "ELIN")) { // Empty geom. } else if (EQUAL(firsttok, "EDGE") && feature != NULL) { CSLDestroy(tokens); tokens = ReadParseLine(); //STPT //Find next non-Point geometry do { geomIdx++; } while (geomIdx < featureDef->GetGeomFieldCount() && featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint); ReadGeom(tokens, geomIdx, wkbMultiLineString, feature); } else if (EQUAL(firsttok, "PERI")) { } else if (EQUAL(firsttok, "ETAB")) { CPLDebug( "OGR_ILI", "Total features: " CPL_FRMT_GIB, curLayer->GetFeatureCount() ); CSLDestroy(tokens); if( !bFeatureAdded ) delete feature; return TRUE; } else { CPLError( CE_Warning, CPLE_AppDefined, "Unexpected token: %s", firsttok ); } CSLDestroy(tokens); } if( !bFeatureAdded ) delete feature; return ret; }
void ILI1Reader::ReadGeom( char **stgeom, int geomIdx, OGRwkbGeometryType eType, OGRFeature *feature ) { #ifdef DEBUG_VERBOSE CPLDebug( "OGR_ILI", "ILI1Reader::ReadGeom geomIdx: %d OGRGeometryType: %s", geomIdx, OGRGeometryTypeToName(eType) ); #endif if (eType == wkbNone) { CPLError( CE_Warning, CPLE_AppDefined, "Calling ILI1Reader::ReadGeom with wkbNone" ); } // Initialize geometry. OGRCompoundCurve *ogrCurve = new OGRCompoundCurve(); OGRCurvePolygon *ogrPoly = NULL; //current polygon OGRMultiCurve *ogrMultiLine = NULL; //current multi line if (eType == wkbMultiCurve || eType == wkbMultiLineString) { ogrMultiLine = new OGRMultiCurve(); } else if (eType == wkbPolygon || eType == wkbCurvePolygon) { ogrPoly = new OGRCurvePolygon(); } OGRPoint ogrPoint; // Current point. ogrPoint.setX(CPLAtof(stgeom[1])); ogrPoint.setY(CPLAtof(stgeom[2])); OGRLineString *ogrLine = new OGRLineString(); ogrLine->addPoint(&ogrPoint); // Parse geometry. char **tokens = NULL; bool end = false; OGRCircularString *arc = NULL; //current arc while (!end && (tokens = ReadParseLine()) != NULL) { const char *firsttok = CSLGetField(tokens, 0); if (EQUAL(firsttok, "LIPT")) { ogrPoint.setX(CPLAtof(tokens[1])); ogrPoint.setY(CPLAtof(tokens[2])); if (arc) { arc->addPoint(&ogrPoint); OGRErr error = ogrCurve->addCurveDirectly(arc); if (error != OGRERR_NONE) { CPLError(CE_Warning, CPLE_AppDefined, "Added geometry: %s", arc->exportToJson() ); } arc = NULL; } ogrLine->addPoint(&ogrPoint); } else if (EQUAL(firsttok, "ARCP")) { //Finish line and start arc if (ogrLine->getNumPoints() > 1) { OGRErr error = ogrCurve->addCurveDirectly(ogrLine); if (error != OGRERR_NONE) { CPLError(CE_Warning, CPLE_AppDefined, "Added geometry: %s", ogrLine->exportToJson() ); } ogrLine = new OGRLineString(); } else { ogrLine->empty(); } arc = new OGRCircularString(); arc->addPoint(&ogrPoint); ogrPoint.setX(CPLAtof(tokens[1])); ogrPoint.setY(CPLAtof(tokens[2])); arc->addPoint(&ogrPoint); } else if (EQUAL(firsttok, "ELIN")) { if (ogrLine->getNumPoints() > 1) { // Ignore single LIPT after ARCP OGRErr error = ogrCurve->addCurveDirectly(ogrLine); if (error != OGRERR_NONE) { CPLError(CE_Warning, CPLE_AppDefined, "Added geometry: %s", ogrLine->exportToJson() ); } ogrLine = NULL; } if (!ogrCurve->IsEmpty()) { if (ogrMultiLine) { OGRErr error = ogrMultiLine->addGeometryDirectly(ogrCurve); if (error != OGRERR_NONE) { CPLError(CE_Warning, CPLE_AppDefined, "Added geometry: %s", ogrCurve->exportToJson() ); } ogrCurve = NULL; } if (ogrPoly) { OGRErr error = ogrPoly->addRingDirectly(ogrCurve); if (error != OGRERR_NONE) { CPLError(CE_Warning, CPLE_AppDefined, "Added geometry: %s", ogrCurve->exportToJson() ); } ogrCurve = NULL; } } end = true; } else if (EQUAL(firsttok, "EEDG")) { end = true; } else if (EQUAL(firsttok, "LATT")) { //Line Attributes (ignored) } else if (EQUAL(firsttok, "EFLA")) { end = true; } else if (EQUAL(firsttok, "ETAB")) { end = true; } else { CPLError( CE_Warning, CPLE_AppDefined, "Unexpected token: %s", firsttok ); } CSLDestroy(tokens); } delete ogrLine; //Set feature geometry if (eType == wkbMultiCurve) { feature->SetGeomFieldDirectly(geomIdx, ogrMultiLine); delete ogrCurve; } else if (eType == wkbMultiLineString) { feature->SetGeomFieldDirectly(geomIdx, ogrMultiLine->getLinearGeometry()); delete ogrMultiLine; delete ogrCurve; } else if (eType == wkbCurvePolygon) { feature->SetGeomFieldDirectly(geomIdx, ogrPoly); delete ogrCurve; } else if (eType == wkbPolygon) { feature->SetGeomFieldDirectly(geomIdx, ogrPoly->getLinearGeometry()); delete ogrPoly; delete ogrCurve; } else { feature->SetGeomFieldDirectly(geomIdx, ogrCurve); } }
int ILI1Reader::ReadFeatures() { char **tokens = NULL; const char *pszLine = NULL; char *topic = CPLStrdup("(null)"); int ret = TRUE; while (ret && (tokens = ReadParseLine()) != NULL) { const char *firsttok = tokens[0]; if (EQUAL(firsttok, "SCNT")) { //read description do { pszLine = CPLReadLine( fpItf ); } while (pszLine && !STARTS_WITH_CI(pszLine, "////")); ret = (pszLine != NULL); } else if (EQUAL(firsttok, "MOTR")) { //read model do { pszLine = CPLReadLine( fpItf ); } while (pszLine && !STARTS_WITH_CI(pszLine, "////")); ret = (pszLine != NULL); } else if (EQUAL(firsttok, "MTID")) { } else if (EQUAL(firsttok, "MODL")) { } else if (EQUAL(firsttok, "TOPI") && CSLCount(tokens) >= 2) { CPLFree(topic); topic = CPLStrdup(CSLGetField(tokens, 1)); } else if (EQUAL(firsttok, "TABL") && CSLCount(tokens) >= 2) { const char *layername = GetLayerNameString(topic, CSLGetField(tokens, 1)); CPLDebug( "OGR_ILI", "Reading table '%s'", layername ); curLayer = GetLayerByName(layername); if (curLayer == NULL) { //create one CPLError( CE_Warning, CPLE_AppDefined, "No model definition for table '%s' found, " "using default field names.", layername ); OGRFeatureDefn* poFeatureDefn = new OGRFeatureDefn( GetLayerNameString(topic, CSLGetField(tokens, 1))); poFeatureDefn->SetGeomType( wkbUnknown ); GeomFieldInfos oGeomFieldInfos; curLayer = new OGRILI1Layer(poFeatureDefn, oGeomFieldInfos, NULL); AddLayer(curLayer); } if(curLayer != NULL) { for (int i=0; i < curLayer->GetLayerDefn()->GetFieldCount(); i++) { CPLDebug( "OGR_ILI", "Field %d: %s", i, curLayer->GetLayerDefn()->GetFieldDefn(i)->GetNameRef()); } } ret = ReadTable(layername); } else if (EQUAL(firsttok, "ETOP")) { } else if (EQUAL(firsttok, "EMOD")) { } else if (EQUAL(firsttok, "ENDE")) { CSLDestroy(tokens); CPLFree(topic); return TRUE; } else { CPLError( CE_Warning, CPLE_AppDefined, "Unexpected token: %s", firsttok ); } CSLDestroy(tokens); tokens = NULL; } CSLDestroy(tokens); CPLFree(topic); return ret; }
int main( int argc, char ** argv ) { int i, b3D = FALSE; int bInverse = FALSE; const char *pszSrcFilename = NULL; const char *pszDstFilename = NULL; char **papszLayers = NULL; const char *pszSQL = NULL; const char *pszBurnAttribute = NULL; const char *pszWHERE = NULL; std::vector<int> anBandList; std::vector<double> adfBurnValues; char **papszRasterizeOptions = NULL; double dfXRes = 0, dfYRes = 0; int bCreateOutput = FALSE; const char* pszFormat = "GTiff"; int bFormatExplicitelySet = FALSE; char **papszCreateOptions = NULL; GDALDriverH hDriver = NULL; GDALDataType eOutputType = GDT_Float64; std::vector<double> adfInitVals; int bNoDataSet = FALSE; double dfNoData = 0; OGREnvelope sEnvelop; int bGotBounds = FALSE; int nXSize = 0, nYSize = 0; int bQuiet = FALSE; GDALProgressFunc pfnProgress = GDALTermProgress; OGRSpatialReferenceH hSRS = NULL; int bTargetAlignedPixels = FALSE; /* Check that we are running against at least GDAL 1.4 */ /* Note to developers : if we use newer API, please change the requirement */ if (atoi(GDALVersionInfo("VERSION_NUM")) < 1400) { fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } GDALAllRegister(); OGRRegisterAll(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(argv[i],"-q") || EQUAL(argv[i],"-quiet") ) { bQuiet = TRUE; pfnProgress = GDALDummyProgress; } else if( EQUAL(argv[i],"-a") && i < argc-1 ) { pszBurnAttribute = argv[++i]; } else if( EQUAL(argv[i],"-b") && i < argc-1 ) { if (strchr(argv[i+1], ' ')) { char** papszTokens = CSLTokenizeString( argv[i+1] ); char** papszIter = papszTokens; while(papszIter && *papszIter) { anBandList.push_back(atoi(*papszIter)); papszIter ++; } CSLDestroy(papszTokens); i += 1; } else { while(i < argc-1 && ArgIsNumeric(argv[i+1])) { anBandList.push_back(atoi(argv[i+1])); i += 1; } } } else if( EQUAL(argv[i],"-3d") ) { b3D = TRUE; papszRasterizeOptions = CSLSetNameValue( papszRasterizeOptions, "BURN_VALUE_FROM", "Z"); } else if( EQUAL(argv[i],"-i") ) { bInverse = TRUE; } else if( EQUAL(argv[i],"-at") ) { papszRasterizeOptions = CSLSetNameValue( papszRasterizeOptions, "ALL_TOUCHED", "TRUE" ); } else if( EQUAL(argv[i],"-burn") && i < argc-1 ) { if (strchr(argv[i+1], ' ')) { char** papszTokens = CSLTokenizeString( argv[i+1] ); char** papszIter = papszTokens; while(papszIter && *papszIter) { adfBurnValues.push_back(atof(*papszIter)); papszIter ++; } CSLDestroy(papszTokens); i += 1; } else { while(i < argc-1 && ArgIsNumeric(argv[i+1])) { adfBurnValues.push_back(atof(argv[i+1])); i += 1; } } } else if( EQUAL(argv[i],"-where") && i < argc-1 ) { pszWHERE = argv[++i]; } else if( EQUAL(argv[i],"-l") && i < argc-1 ) { papszLayers = CSLAddString( papszLayers, argv[++i] ); } else if( EQUAL(argv[i],"-sql") && i < argc-1 ) { pszSQL = argv[++i]; } else if( EQUAL(argv[i],"-of") && i < argc-1 ) { pszFormat = argv[++i]; bFormatExplicitelySet = TRUE; bCreateOutput = TRUE; } else if( EQUAL(argv[i],"-init") && i < argc - 1 ) { if (strchr(argv[i+1], ' ')) { char** papszTokens = CSLTokenizeString( argv[i+1] ); char** papszIter = papszTokens; while(papszIter && *papszIter) { adfInitVals.push_back(atof(*papszIter)); papszIter ++; } CSLDestroy(papszTokens); i += 1; } else { while(i < argc-1 && ArgIsNumeric(argv[i+1])) { adfInitVals.push_back(atof(argv[i+1])); i += 1; } } bCreateOutput = TRUE; } else if( EQUAL(argv[i],"-a_nodata") && i < argc - 1 ) { dfNoData = atof(argv[i+1]); bNoDataSet = TRUE; i += 1; bCreateOutput = TRUE; } else if( EQUAL(argv[i],"-a_srs") && i < argc-1 ) { hSRS = OSRNewSpatialReference( NULL ); if( OSRSetFromUserInput(hSRS, argv[i+1]) != OGRERR_NONE ) { fprintf( stderr, "Failed to process SRS definition: %s\n", argv[i+1] ); exit( 1 ); } i++; bCreateOutput = TRUE; } else if( EQUAL(argv[i],"-te") && i < argc - 4 ) { sEnvelop.MinX = atof(argv[++i]); sEnvelop.MinY = atof(argv[++i]); sEnvelop.MaxX = atof(argv[++i]); sEnvelop.MaxY = atof(argv[++i]); bGotBounds = TRUE; bCreateOutput = TRUE; } else if( EQUAL(argv[i],"-a_ullr") && i < argc - 4 ) { sEnvelop.MinX = atof(argv[++i]); sEnvelop.MaxY = atof(argv[++i]); sEnvelop.MaxX = atof(argv[++i]); sEnvelop.MinY = atof(argv[++i]); bGotBounds = TRUE; bCreateOutput = TRUE; } else if( EQUAL(argv[i],"-co") && i < argc-1 ) { papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] ); bCreateOutput = TRUE; } else if( EQUAL(argv[i],"-ot") && i < argc-1 ) { int iType; for( iType = 1; iType < GDT_TypeCount; iType++ ) { if( GDALGetDataTypeName((GDALDataType)iType) != NULL && EQUAL(GDALGetDataTypeName((GDALDataType)iType), argv[i+1]) ) { eOutputType = (GDALDataType) iType; } } if( eOutputType == GDT_Unknown ) { printf( "Unknown output pixel type: %s\n", argv[i+1] ); Usage(); } i++; bCreateOutput = TRUE; } else if( (EQUAL(argv[i],"-ts") || EQUAL(argv[i],"-outsize")) && i < argc-2 ) { nXSize = atoi(argv[++i]); nYSize = atoi(argv[++i]); if (nXSize <= 0 || nYSize <= 0) { printf( "Wrong value for -outsize parameters\n"); Usage(); } bCreateOutput = TRUE; } else if( EQUAL(argv[i],"-tr") && i < argc-2 ) { dfXRes = atof(argv[++i]); dfYRes = fabs(atof(argv[++i])); if( dfXRes == 0 || dfYRes == 0 ) { printf( "Wrong value for -tr parameters\n"); Usage(); } bCreateOutput = TRUE; } else if( EQUAL(argv[i],"-tap") ) { bTargetAlignedPixels = TRUE; bCreateOutput = TRUE; } else if( pszSrcFilename == NULL ) { pszSrcFilename = argv[i]; } else if( pszDstFilename == NULL ) { pszDstFilename = argv[i]; } else Usage(); } if( pszSrcFilename == NULL || pszDstFilename == NULL ) { fprintf( stderr, "Missing source or destination.\n\n" ); Usage(); } if( adfBurnValues.size() == 0 && pszBurnAttribute == NULL && !b3D ) { fprintf( stderr, "At least one of -3d, -burn or -a required.\n\n" ); Usage(); } if( bCreateOutput ) { if( dfXRes == 0 && dfYRes == 0 && nXSize == 0 && nYSize == 0 ) { fprintf( stderr, "'-tr xres yes' or '-ts xsize ysize' is required.\n\n" ); Usage(); } if (bTargetAlignedPixels && dfXRes == 0 && dfYRes == 0) { fprintf( stderr, "-tap option cannot be used without using -tr\n"); Usage(); } if( anBandList.size() != 0 ) { fprintf( stderr, "-b option cannot be used when creating a GDAL dataset.\n\n" ); Usage(); } int nBandCount = 1; if (adfBurnValues.size() != 0) nBandCount = adfBurnValues.size(); if ((int)adfInitVals.size() > nBandCount) nBandCount = adfInitVals.size(); if (adfInitVals.size() == 1) { for(i=1;i<=nBandCount - 1;i++) adfInitVals.push_back( adfInitVals[0] ); } int i; for(i=1;i<=nBandCount;i++) anBandList.push_back( i ); } else { if( anBandList.size() == 0 ) anBandList.push_back( 1 ); } /* -------------------------------------------------------------------- */ /* Open source vector dataset. */ /* -------------------------------------------------------------------- */ OGRDataSourceH hSrcDS; hSrcDS = OGROpen( pszSrcFilename, FALSE, NULL ); if( hSrcDS == NULL ) { fprintf( stderr, "Failed to open feature source: %s\n", pszSrcFilename); exit( 1 ); } if( pszSQL == NULL && papszLayers == NULL ) { if( OGR_DS_GetLayerCount(hSrcDS) == 1 ) { papszLayers = CSLAddString(NULL, OGR_L_GetName(OGR_DS_GetLayer(hSrcDS, 0))); } else { fprintf( stderr, "At least one of -l or -sql required.\n\n" ); Usage(); } } /* -------------------------------------------------------------------- */ /* Open target raster file. Eventually we will add optional */ /* creation. */ /* -------------------------------------------------------------------- */ GDALDatasetH hDstDS = NULL; if (bCreateOutput) { /* -------------------------------------------------------------------- */ /* Find the output driver. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDriverByName( pszFormat ); if( hDriver == NULL || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) == NULL ) { int iDr; printf( "Output driver `%s' not recognised or does not support\n", pszFormat ); printf( "direct output file creation. The following format drivers are configured\n" "and support direct output:\n" ); for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ ) { GDALDriverH hDriver = GDALGetDriver(iDr); if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL) != NULL ) { printf( " %s: %s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); } } printf( "\n" ); exit( 1 ); } if (!bQuiet && !bFormatExplicitelySet) CheckExtensionConsistency(pszDstFilename, pszFormat); } else { hDstDS = GDALOpen( pszDstFilename, GA_Update ); if( hDstDS == NULL ) exit( 2 ); } /* -------------------------------------------------------------------- */ /* Process SQL request. */ /* -------------------------------------------------------------------- */ if( pszSQL != NULL ) { OGRLayerH hLayer; hLayer = OGR_DS_ExecuteSQL( hSrcDS, pszSQL, NULL, NULL ); if( hLayer != NULL ) { if (bCreateOutput) { std::vector<OGRLayerH> ahLayers; ahLayers.push_back(hLayer); hDstDS = CreateOutputDataset(ahLayers, hSRS, bGotBounds, sEnvelop, hDriver, pszDstFilename, nXSize, nYSize, dfXRes, dfYRes, bTargetAlignedPixels, anBandList.size(), eOutputType, papszCreateOptions, adfInitVals, bNoDataSet, dfNoData); } ProcessLayer( hLayer, hSRS != NULL, hDstDS, anBandList, adfBurnValues, b3D, bInverse, pszBurnAttribute, papszRasterizeOptions, pfnProgress, NULL ); OGR_DS_ReleaseResultSet( hSrcDS, hLayer ); } } /* -------------------------------------------------------------------- */ /* Create output file if necessary. */ /* -------------------------------------------------------------------- */ int nLayerCount = CSLCount(papszLayers); if (bCreateOutput && hDstDS == NULL) { std::vector<OGRLayerH> ahLayers; for( i = 0; i < nLayerCount; i++ ) { OGRLayerH hLayer = OGR_DS_GetLayerByName( hSrcDS, papszLayers[i] ); if( hLayer == NULL ) { continue; } ahLayers.push_back(hLayer); } hDstDS = CreateOutputDataset(ahLayers, hSRS, bGotBounds, sEnvelop, hDriver, pszDstFilename, nXSize, nYSize, dfXRes, dfYRes, bTargetAlignedPixels, anBandList.size(), eOutputType, papszCreateOptions, adfInitVals, bNoDataSet, dfNoData); } /* -------------------------------------------------------------------- */ /* Process each layer. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nLayerCount; i++ ) { OGRLayerH hLayer = OGR_DS_GetLayerByName( hSrcDS, papszLayers[i] ); if( hLayer == NULL ) { fprintf( stderr, "Unable to find layer %s, skipping.\n", papszLayers[i] ); continue; } if( pszWHERE ) { if( OGR_L_SetAttributeFilter( hLayer, pszWHERE ) != OGRERR_NONE ) break; } void *pScaledProgress; pScaledProgress = GDALCreateScaledProgress( 0.0, 1.0 * (i + 1) / nLayerCount, pfnProgress, NULL ); ProcessLayer( hLayer, hSRS != NULL, hDstDS, anBandList, adfBurnValues, b3D, bInverse, pszBurnAttribute, papszRasterizeOptions, GDALScaledProgress, pScaledProgress ); GDALDestroyScaledProgress( pScaledProgress ); } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ OGR_DS_Destroy( hSrcDS ); GDALClose( hDstDS ); OSRDestroySpatialReference(hSRS); CSLDestroy( argv ); CSLDestroy( papszRasterizeOptions ); CSLDestroy( papszLayers ); CSLDestroy( papszCreateOptions ); GDALDestroyDriverManager(); OGRCleanupAll(); return 0; }
int OGRCSVDataSource::OpenTable( const char * pszFilename, const char* pszNfdcRunwaysGeomField, const char* pszGeonamesGeomFieldPrefix) { /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ VSILFILE * fp; if( bUpdate ) fp = VSIFOpenL( pszFilename, "rb+" ); else fp = VSIFOpenL( pszFilename, "rb" ); if( fp == NULL ) { CPLError( CE_Warning, CPLE_OpenFailed, "Failed to open %s, %s.", pszFilename, VSIStrerror( errno ) ); return FALSE; } if( !bUpdate && strstr(pszFilename, "/vsigzip/") == NULL && strstr(pszFilename, "/vsizip/") == NULL ) fp = (VSILFILE*) VSICreateBufferedReaderHandle((VSIVirtualHandle*)fp); CPLString osLayerName = CPLGetBasename(pszFilename); CPLString osExt = CPLGetExtension(pszFilename); if( strncmp(pszFilename, "/vsigzip/", 9) == 0 && EQUAL(osExt, "gz") ) { if( strlen(pszFilename) > 7 && EQUAL(pszFilename + strlen(pszFilename) - 7, ".csv.gz") ) { osLayerName = osLayerName.substr(0, osLayerName.size() - 4); osExt = "csv"; } else if( strlen(pszFilename) > 7 && EQUAL(pszFilename + strlen(pszFilename) - 7, ".tsv.gz") ) { osLayerName = osLayerName.substr(0, osLayerName.size() - 4); osExt = "tsv"; } } /* -------------------------------------------------------------------- */ /* Read and parse a line. Did we get multiple fields? */ /* -------------------------------------------------------------------- */ const char* pszLine = CPLReadLineL( fp ); if (pszLine == NULL) { VSIFCloseL( fp ); return FALSE; } char chDelimiter = CSVDetectSeperator(pszLine); /* Force the delimiter to be TAB for a .tsv file that has a tabulation */ /* in its first line */ if( EQUAL(osExt, "tsv") && chDelimiter != '\t' && strchr(pszLine, '\t') != NULL ) { chDelimiter = '\t'; } VSIRewindL( fp ); /* GNIS specific */ if (pszGeonamesGeomFieldPrefix != NULL && strchr(pszLine, '|') != NULL) chDelimiter = '|'; char **papszFields = OGRCSVReadParseLineL( fp, chDelimiter, FALSE ); if( CSLCount(papszFields) < 2 ) { VSIFCloseL( fp ); CSLDestroy( papszFields ); return FALSE; } VSIRewindL( fp ); CSLDestroy( papszFields ); /* -------------------------------------------------------------------- */ /* Create a layer. */ /* -------------------------------------------------------------------- */ nLayers++; papoLayers = (OGRCSVLayer **) CPLRealloc(papoLayers, sizeof(void*) * nLayers); if (pszNfdcRunwaysGeomField != NULL) { osLayerName += "_"; osLayerName += pszNfdcRunwaysGeomField; } else if (pszGeonamesGeomFieldPrefix != NULL && !EQUAL(pszGeonamesGeomFieldPrefix, "")) { osLayerName += "_"; osLayerName += pszGeonamesGeomFieldPrefix; } if (EQUAL(pszFilename, "/vsistdin/")) osLayerName = "layer"; papoLayers[nLayers-1] = new OGRCSVLayer( osLayerName, fp, pszFilename, FALSE, bUpdate, chDelimiter, pszNfdcRunwaysGeomField, pszGeonamesGeomFieldPrefix ); return TRUE; }
NASAKeywordHandler::~NASAKeywordHandler() { CSLDestroy( papszKeywordList ); papszKeywordList = NULL; }
GDALDataset *XYZDataset::Open( GDALOpenInfo * poOpenInfo ) { int i; int bHasHeaderLine; int nCommentLineCount = 0; if (!IdentifyEx(poOpenInfo, bHasHeaderLine, nCommentLineCount)) return NULL; CPLString osFilename(poOpenInfo->pszFilename); /* GZipped .xyz files are common, so automagically open them */ /* if the /vsigzip/ has not been explicitely passed */ if (strlen(poOpenInfo->pszFilename) > 6 && EQUAL(poOpenInfo->pszFilename + strlen(poOpenInfo->pszFilename) - 6, "xyz.gz") && !EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9)) { osFilename = "/vsigzip/"; osFilename += poOpenInfo->pszFilename; } /* -------------------------------------------------------------------- */ /* Find dataset characteristics */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "rb"); if (fp == NULL) return NULL; /* For better performance of CPLReadLine2L() we create a buffered reader */ /* (except for /vsigzip/ since it has one internally) */ if (!EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9)) fp = (VSILFILE*) VSICreateBufferedReaderHandle((VSIVirtualHandle*)fp); const char* pszLine; int nXIndex = -1, nYIndex = -1, nZIndex = -1; int nMinTokens = 0; for(i=0;i<nCommentLineCount;i++) CPLReadLine2L(fp, 100, NULL); /* -------------------------------------------------------------------- */ /* Parse header line */ /* -------------------------------------------------------------------- */ if (bHasHeaderLine) { pszLine = CPLReadLine2L(fp, 100, NULL); if (pszLine == NULL) { VSIFCloseL(fp); return NULL; } char** papszTokens = CSLTokenizeString2( pszLine, " ,\t;", CSLT_HONOURSTRINGS ); int nTokens = CSLCount(papszTokens); if (nTokens < 3) { CPLError(CE_Failure, CPLE_AppDefined, "At line %d, found %d tokens. Expected 3 at least", 1, nTokens); CSLDestroy(papszTokens); VSIFCloseL(fp); return NULL; } int i; for(i=0;i<nTokens;i++) { if (EQUAL(papszTokens[i], "x") || EQUALN(papszTokens[i], "lon", 3) || EQUALN(papszTokens[i], "east", 4)) nXIndex = i; else if (EQUAL(papszTokens[i], "y") || EQUALN(papszTokens[i], "lat", 3) || EQUALN(papszTokens[i], "north", 5)) nYIndex = i; else if (EQUAL(papszTokens[i], "z") || EQUALN(papszTokens[i], "alt", 3) || EQUAL(papszTokens[i], "height")) nZIndex = i; } CSLDestroy(papszTokens); papszTokens = NULL; if (nXIndex < 0 || nYIndex < 0 || nZIndex < 0) { CPLError(CE_Warning, CPLE_AppDefined, "Could not find one of the X, Y or Z column names in header line. Defaulting to the first 3 columns"); nXIndex = 0; nYIndex = 1; nZIndex = 2; } nMinTokens = 1 + MAX(MAX(nXIndex, nYIndex), nZIndex); } else { nXIndex = 0; nYIndex = 1; nZIndex = 2; nMinTokens = 3; } /* -------------------------------------------------------------------- */ /* Parse data lines */ /* -------------------------------------------------------------------- */ int nLineNum = 0; int nDataLineNum = 0; double dfX = 0, dfY = 0, dfZ = 0; double dfMinX = 0, dfMinY = 0, dfMaxX = 0, dfMaxY = 0; double dfMinZ = 0, dfMaxZ = 0; double dfLastX = 0, dfLastY = 0; std::vector<double> adfStepX, adfStepY; GDALDataType eDT = GDT_Byte; int bSameNumberOfValuesPerLine = TRUE; char chDecimalSep = '\0'; int bStepYSign = 0; while((pszLine = CPLReadLine2L(fp, 100, NULL)) != NULL) { nLineNum ++; const char* pszPtr = pszLine; char ch; int nCol = 0; int bLastWasSep = TRUE; if( chDecimalSep == '\0' ) { int nCountComma = 0; int nCountFieldSep = 0; while((ch = *pszPtr) != '\0') { if( ch == '.' ) { chDecimalSep = '.'; break; } else if( ch == ',' ) { nCountComma ++; bLastWasSep = FALSE; } else if( ch == ' ' ) { if (!bLastWasSep) nCountFieldSep ++; bLastWasSep = TRUE; } else if( ch == '\t' || ch == ';' ) { nCountFieldSep ++; bLastWasSep = TRUE; } else bLastWasSep = FALSE; pszPtr ++; } if( chDecimalSep == '\0' ) { /* 1,2,3 */ if( nCountComma >= 2 && nCountFieldSep == 0 ) chDecimalSep = '.'; /* 23,5;33;45 */ else if ( nCountComma > 0 && nCountFieldSep > 0 ) chDecimalSep = ','; } pszPtr = pszLine; bLastWasSep = TRUE; } char chLocalDecimalSep = chDecimalSep ? chDecimalSep : '.'; while((ch = *pszPtr) != '\0') { if (ch == ' ') { if (!bLastWasSep) nCol ++; bLastWasSep = TRUE; } else if ((ch == ',' && chLocalDecimalSep != ',') || ch == '\t' || ch == ';') { nCol ++; bLastWasSep = TRUE; } else { if (bLastWasSep) { if (nCol == nXIndex) dfX = CPLAtofDelim(pszPtr, chLocalDecimalSep); else if (nCol == nYIndex) dfY = CPLAtofDelim(pszPtr, chLocalDecimalSep); else if (nCol == nZIndex) { dfZ = CPLAtofDelim(pszPtr, chLocalDecimalSep); if( nDataLineNum == 0 ) dfMinZ = dfMaxZ = dfZ; else if( dfZ < dfMinZ ) dfMinZ = dfZ; else if( dfZ > dfMaxZ ) dfMaxZ = dfZ; int nZ = (int)dfZ; if ((double)nZ != dfZ) { eDT = GDT_Float32; } else if ((eDT == GDT_Byte || eDT == GDT_Int16) && (nZ < 0 || nZ > 255)) { if (nZ < -32768 || nZ > 32767) eDT = GDT_Int32; else eDT = GDT_Int16; } } } bLastWasSep = FALSE; } pszPtr ++; } /* skip empty lines */ if (bLastWasSep && nCol == 0) { continue; } nDataLineNum ++; nCol ++; if (nCol < nMinTokens) { CPLError(CE_Failure, CPLE_AppDefined, "At line %d, found %d tokens. Expected %d at least", nLineNum, nCol, nMinTokens); VSIFCloseL(fp); return NULL; } if (nDataLineNum == 1) { dfMinX = dfMaxX = dfX; dfMinY = dfMaxY = dfY; } else { double dfStepY = dfY - dfLastY; if( dfStepY == 0.0 ) { double dfStepX = dfX - dfLastX; if( dfStepX <= 0 ) { CPLError(CE_Failure, CPLE_AppDefined, "Ungridded dataset: At line %d, X spacing was %f. Expected >0 value", nLineNum, dfStepX); VSIFCloseL(fp); return NULL; } if( std::find(adfStepX.begin(), adfStepX.end(), dfStepX) == adfStepX.end() ) { int bAddNewValue = TRUE; std::vector<double>::iterator oIter = adfStepX.begin(); while( oIter != adfStepX.end() ) { if( dfStepX < *oIter && fmod( *oIter, dfStepX ) < 1e-8 ) { adfStepX.erase(oIter); } else if( dfStepX > *oIter && fmod( dfStepX, *oIter ) < 1e-8 ) { bAddNewValue = FALSE; break; } else { ++ oIter; } } if( bAddNewValue ) { adfStepX.push_back(dfStepX); if( adfStepX.size() == 10 ) { CPLError(CE_Failure, CPLE_AppDefined, "Ungridded dataset: too many stepX values"); VSIFCloseL(fp); return NULL; } } } } else { int bNewStepYSign = (dfStepY < 0.0) ? -1 : 1; if( bStepYSign == 0 ) bStepYSign = bNewStepYSign; else if( bStepYSign != bNewStepYSign ) { CPLError(CE_Failure, CPLE_AppDefined, "Ungridded dataset: At line %d, change of Y direction", nLineNum); VSIFCloseL(fp); return NULL; } if( bNewStepYSign < 0 ) dfStepY = -dfStepY; if( adfStepY.size() == 0 ) adfStepY.push_back(dfStepY); else if( adfStepY[0] != dfStepY ) { CPLError(CE_Failure, CPLE_AppDefined, "Ungridded dataset: At line %d, too many stepY values", nLineNum); VSIFCloseL(fp); return NULL; } } if (dfX < dfMinX) dfMinX = dfX; if (dfX > dfMaxX) dfMaxX = dfX; if (dfY < dfMinY) dfMinY = dfY; if (dfY > dfMaxY) dfMaxY = dfY; } dfLastX = dfX; dfLastY = dfY; } if (adfStepX.size() != 1) { CPLError(CE_Failure, CPLE_AppDefined, "Couldn't determine X spacing"); VSIFCloseL(fp); return NULL; } if (adfStepY.size() != 1) { CPLError(CE_Failure, CPLE_AppDefined, "Couldn't determine Y spacing"); VSIFCloseL(fp); return NULL; } double dfStepX = adfStepX[0]; double dfStepY = adfStepY[0] * bStepYSign; int nXSize = 1 + int((dfMaxX - dfMinX) / dfStepX + 0.5); int nYSize = 1 + int((dfMaxY - dfMinY) / fabs(dfStepY) + 0.5); //CPLDebug("XYZ", "minx=%f maxx=%f stepx=%f", dfMinX, dfMaxX, dfStepX); //CPLDebug("XYZ", "miny=%f maxy=%f stepy=%f", dfMinY, dfMaxY, dfStepY); if (nDataLineNum != nXSize * nYSize) { bSameNumberOfValuesPerLine = FALSE; } if (poOpenInfo->eAccess == GA_Update) { CPLError( CE_Failure, CPLE_NotSupported, "The XYZ driver does not support update access to existing" " datasets.\n" ); VSIFCloseL(fp); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ XYZDataset *poDS; poDS = new XYZDataset(); poDS->fp = fp; poDS->bHasHeaderLine = bHasHeaderLine; poDS->nCommentLineCount = nCommentLineCount; poDS->chDecimalSep = chDecimalSep ? chDecimalSep : '.'; poDS->nXIndex = nXIndex; poDS->nYIndex = nYIndex; poDS->nZIndex = nZIndex; poDS->nMinTokens = nMinTokens; poDS->nRasterXSize = nXSize; poDS->nRasterYSize = nYSize; poDS->adfGeoTransform[0] = dfMinX - dfStepX / 2; poDS->adfGeoTransform[1] = dfStepX; poDS->adfGeoTransform[3] = (dfStepY < 0) ? dfMaxY - dfStepY / 2 : dfMinY - dfStepY / 2; poDS->adfGeoTransform[5] = dfStepY; poDS->bSameNumberOfValuesPerLine = bSameNumberOfValuesPerLine; poDS->dfMinZ = dfMinZ; poDS->dfMaxZ = dfMaxZ; //CPLDebug("XYZ", "bSameNumberOfValuesPerLine = %d", bSameNumberOfValuesPerLine); if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize)) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->nBands = 1; for( i = 0; i < poDS->nBands; i++ ) poDS->SetBand( i+1, new XYZRasterBand( poDS, i+1, eDT ) ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Support overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
GDALDataset *ISIS2Dataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Does this look like a CUBE dataset? */ /* -------------------------------------------------------------------- */ if( poOpenInfo->pabyHeader == NULL || strstr((const char *)poOpenInfo->pabyHeader,"^QUBE") == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Open the file using the large file API. */ /* -------------------------------------------------------------------- */ FILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); if( fpQube == NULL ) return NULL; ISIS2Dataset *poDS; poDS = new ISIS2Dataset(); if( ! poDS->oKeywords.Ingest( fpQube, 0 ) ) { VSIFCloseL( fpQube ); delete poDS; return NULL; } VSIFCloseL( fpQube ); /* -------------------------------------------------------------------- */ /* We assume the user is pointing to the label (ie. .lab) file. */ /* -------------------------------------------------------------------- */ // QUBE can be inline or detached and point to an image name // ^QUBE = 76 // ^QUBE = ("ui31s015.img",6441<BYTES>) - has another label on the image // ^QUBE = "ui31s015.img" - which implies no label or skip value const char *pszQube = poDS->GetKeyword( "^QUBE" ); int nQube = atoi(pszQube); if( pszQube[0] == '"' || pszQube[0] == '(' ) { CPLError( CE_Failure, CPLE_AppDefined, "ISIS2 driver does not support detached images." ); return NULL; } /* -------------------------------------------------------------------- */ /* Check if file an ISIS2 header file? Read a few lines of text */ /* searching for something starting with nrows or ncols. */ /* -------------------------------------------------------------------- */ GDALDataType eDataType = GDT_Byte; OGRSpatialReference oSRS; //image parameters int nRows, nCols, nBands = 1; int nSkipBytes = 0; int itype; int s_ix, s_iy, s_iz; // check SUFFIX_ITEMS params. int record_bytes; int bNoDataSet = FALSE; char chByteOrder = 'M'; //default to MSB //Georef parameters double dfULXMap=0.5; double dfULYMap = 0.5; double dfXDim = 1.0; double dfYDim = 1.0; double dfNoData = 0.0; double xulcenter = 0.0; double yulcenter = 0.0; //projection parameters int bProjectionSet = TRUE; double semi_major = 0.0; double semi_minor = 0.0; double iflattening = 0.0; float center_lat = 0.0; float center_lon = 0.0; float first_std_parallel = 0.0; float second_std_parallel = 0.0; FILE *fp; /* -------------------------------------------------------------------- */ /* Checks to see if this is valid ISIS2 cube */ /* SUFFIX_ITEM tag in .cub file should be (0,0,0); no side-planes */ /* -------------------------------------------------------------------- */ s_ix = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 1 )); s_iy = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 2 )); s_iz = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 3 )); if( s_ix != 0 || s_iy != 0 || s_iz != 0 ) { CPLError( CE_Failure, CPLE_OpenFailed, "*** ISIS 2 cube file has invalid SUFFIX_ITEMS parameters:\n" "*** gdal isis2 driver requires (0, 0, 0), thus no sideplanes or backplanes\n" "found: (%i, %i, %i)\n\n", s_ix, s_iy, s_iz ); return NULL; } /**************** end SUFFIX_ITEM check ***********************/ /*********** Grab layout type (BSQ, BIP, BIL) ************/ // AXIS_NAME = (SAMPLE,LINE,BAND) /***********************************************************/ const char *value; char szLayout[10] = "BSQ"; //default to band seq. value = poDS->GetKeyword( "QUBE.AXIS_NAME", "" ); if (EQUAL(value,"(SAMPLE,LINE,BAND)") ) strcpy(szLayout,"BSQ"); else if (EQUAL(value,"(BAND,LINE,SAMPLE)") ) strcpy(szLayout,"BIP"); else if (EQUAL(value,"(SAMPLE,BAND,LINE)") || EQUAL(value,"") ) strcpy(szLayout,"BSQ"); else { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); return NULL; } /*********** Grab samples lines band ************/ nCols = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",1)); nRows = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",2)); nBands = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",3)); /*********** Grab Qube record bytes **********/ record_bytes = atoi(poDS->GetKeyword("RECORD_BYTES")); if (nQube > 0) nSkipBytes = (nQube - 1) * record_bytes; else nSkipBytes = 0; /******** Grab format type - isis2 only supports 8,16,32 *******/ itype = atoi(poDS->GetKeyword("QUBE.CORE_ITEM_BYTES","")); switch(itype) { case 1 : eDataType = GDT_Byte; dfNoData = NULL1; bNoDataSet = TRUE; break; case 2 : eDataType = GDT_Int16; dfNoData = NULL2; bNoDataSet = TRUE; break; case 4 : eDataType = GDT_Float32; dfNoData = NULL3; bNoDataSet = TRUE; break; default : CPLError( CE_Failure, CPLE_AppDefined, "Itype of %d is not supported in ISIS 2.", itype); delete poDS; return NULL; } /*********** Grab samples lines band ************/ value = poDS->GetKeyword( "QUBE.CORE_ITEM_TYPE" ); if( (EQUAL(value,"PC_INTEGER")) || (EQUAL(value,"PC_UNSIGNED_INTEGER")) || (EQUAL(value,"PC_REAL")) ) { chByteOrder = 'I'; } /*********** Grab Cellsize ************/ value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.MAP_SCALE"); if (strlen(value) > 0 ) { dfXDim = (float) atof(value) * 1000.0; /* convert from km to m */ dfYDim = (float) atof(value) * 1000.0 * -1; } /*********** Grab LINE_PROJECTION_OFFSET ************/ value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.LINE_PROJECTION_OFFSET"); if (strlen(value) > 0) { yulcenter = (float) atof(value); yulcenter = ((yulcenter) * dfYDim); dfULYMap = yulcenter - (dfYDim/2); } /*********** Grab SAMPLE_PROJECTION_OFFSET ************/ value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.SAMPLE_PROJECTION_OFFSET"); if( strlen(value) > 0 ) { xulcenter = (float) atof(value); xulcenter = ((xulcenter) * dfXDim); dfULXMap = xulcenter - (dfXDim/2); } /*********** Grab TARGET_NAME ************/ /**** This is the planets name i.e. MARS ***/ CPLString target_name = poDS->GetKeyword("QUBE.TARGET_NAME"); /*********** Grab MAP_PROJECTION_TYPE ************/ CPLString map_proj_name = poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.MAP_PROJECTION_TYPE"); poDS->CleanString( map_proj_name ); /*********** Grab SEMI-MAJOR ************/ semi_major = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.A_AXIS_RADIUS")) * 1000.0; /*********** Grab semi-minor ************/ semi_minor = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.C_AXIS_RADIUS")) * 1000.0; /*********** Grab CENTER_LAT ************/ center_lat = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LATITUDE")); /*********** Grab CENTER_LON ************/ center_lon = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LONGITUDE")); /*********** Grab 1st std parallel ************/ first_std_parallel = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.FIRST_STANDARD_PARALLEL")); /*********** Grab 2nd std parallel ************/ second_std_parallel = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.SECOND_STANDARD_PARALLEL")); /*** grab PROJECTION_LATITUDE_TYPE = "PLANETOCENTRIC" ****/ // Need to further study how ocentric/ographic will effect the gdal library. // So far we will use this fact to define a sphere or ellipse for some projections // Frank - may need to talk this over char bIsGeographic = TRUE; value = poDS->GetKeyword("CUBE.IMAGE_MAP_PROJECTION.PROJECTION_LATITUDE_TYPE"); if (EQUAL( value, "\"PLANETOCENTRIC\"" )) bIsGeographic = FALSE; CPLDebug("ISIS2","using projection %s", map_proj_name.c_str() ); //Set oSRS projection and parameters if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) || (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) || (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) ) { oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 ); } else if (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) { oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 ); } else if ((EQUAL( map_proj_name, "SINUSOIDAL" )) || (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" ))) { oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "MERCATOR" )) { oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )) { oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "TRANSVERSE_MERCATOR" )) { oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "LAMBERT_CONFORMAL_CONIC" )) { oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 ); } else { CPLDebug( "ISIS2", "Dataset projection %s is not supported. Continuing...", map_proj_name.c_str() ); bProjectionSet = FALSE; } if (bProjectionSet) { //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword CPLString proj_target_name = map_proj_name + " " + target_name; oSRS.SetProjCS(proj_target_name); //set ProjCS keyword //The geographic/geocentric name will be the same basic name as the body name //'GCS' = Geographic/Geocentric Coordinate System CPLString geog_name = "GCS_" + target_name; //The datum and sphere names will be the same basic name aas the planet CPLString datum_name = "D_" + target_name; CPLString sphere_name = target_name; // + "_IAU_IAG"); //Might not be IAU defined so don't add //calculate inverse flattening from major and minor axis: 1/f = a/(a-b) if ((semi_major - semi_minor) < 0.0000001) iflattening = 0; else iflattening = semi_major / (semi_major - semi_minor); //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally if ( ( (EQUAL( map_proj_name, "STEREOGRAPHIC" ) && (fabs(center_lat) == 90)) ) || (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" ))) { if (bIsGeographic) { //Geograpraphic, so set an ellipse oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere using the semi-minor axis. I hope... sphere_name += "_polarRadius"; oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_minor, 0.0, "Reference_Meridian", 0.0 ); } } else if ( (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) || (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) || (EQUAL( map_proj_name, "STEREOGRAPHIC" )) || (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" )) || (EQUAL( map_proj_name, "SINUSOIDAL" )) ) { //isis uses the sphereical equation for these projections so force a sphere oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) || (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ) { //Calculate localRadius using ISIS3 simple elliptical method // not the more standard Radius of Curvature method //PI = 4 * atan(1); double radLat, localRadius; if (center_lon == 0) { //No need to calculate local radius oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else { radLat = center_lat * PI / 180; // in radians localRadius = semi_major * semi_minor / sqrt(pow(semi_minor*cos(radLat),2) + pow(semi_major*sin(radLat),2) ); sphere_name += "_localRadius"; oSRS.SetGeogCS( geog_name, datum_name, sphere_name, localRadius, 0.0, "Reference_Meridian", 0.0 ); CPLDebug( "ISIS2", "local radius: %f", localRadius); } } else { //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc. //Geographic, so set an ellipse if (bIsGeographic) { oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere. I hope... oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } } // translate back into a projection string. char *pszResult = NULL; oSRS.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } /* END ISIS2 Label Read */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* -------------------------------------------------------------------- */ /* Did we get the required keywords? If not we return with */ /* this never having been considered to be a match. This isn't */ /* an error! */ /* -------------------------------------------------------------------- */ if( nRows < 1 || nCols < 1 || nBands < 1 ) { return NULL; } /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; /* -------------------------------------------------------------------- */ /* Open target binary file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); else poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "r+b" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s with write permission.\n%s", poOpenInfo->pszFilename, VSIStrerror( errno ) ); delete poDS; return NULL; } poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Compute the line offset. */ /* -------------------------------------------------------------------- */ int nItemSize = GDALGetDataTypeSize(eDataType)/8; int nLineOffset, nPixelOffset, nBandOffset; if( EQUAL(szLayout,"BIP") ) { nPixelOffset = nItemSize * nBands; nLineOffset = nPixelOffset * nCols; nBandOffset = nItemSize; } else if( EQUAL(szLayout,"BSQ") ) { nPixelOffset = nItemSize; nLineOffset = nPixelOffset * nCols; nBandOffset = nLineOffset * nRows; } else /* assume BIL */ { nPixelOffset = nItemSize; nLineOffset = nItemSize * nBands * nCols; nBandOffset = nItemSize * nCols; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ int i; poDS->nBands = nBands;; for( i = 0; i < poDS->nBands; i++ ) { RawRasterBand *poBand; poBand = new RawRasterBand( poDS, i+1, poDS->fpImage, nSkipBytes + nBandOffset * i, nPixelOffset, nLineOffset, eDataType, #ifdef CPL_LSB chByteOrder == 'I' || chByteOrder == 'L', #else chByteOrder == 'M', #endif TRUE ); if( bNoDataSet ) poBand->SetNoDataValue( dfNoData ); poDS->SetBand( i+1, poBand ); // Set offset/scale values at the PAM level. poBand->SetOffset( CPLAtofM(poDS->GetKeyword("QUBE.CORE_BASE","0.0"))); poBand->SetScale( CPLAtofM(poDS->GetKeyword("QUBE.CORE_MULTIPLIER","1.0"))); } /* -------------------------------------------------------------------- */ /* Check for a .prj file. For isis2 I would like to keep this in */ /* -------------------------------------------------------------------- */ CPLString osPath, osName; osPath = CPLGetPath( poOpenInfo->pszFilename ); osName = CPLGetBasename(poOpenInfo->pszFilename); const char *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" ); fp = VSIFOpen( pszPrjFile, "r" ); if( fp != NULL ) { char **papszLines; OGRSpatialReference oSRS; VSIFClose( fp ); papszLines = CSLLoad( pszPrjFile ); if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE ) { char *pszResult = NULL; oSRS.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } CSLDestroy( papszLines ); } if( dfULYMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 ) { poDS->bGotTransform = TRUE; poDS->adfGeoTransform[0] = dfULXMap; poDS->adfGeoTransform[1] = dfXDim; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = dfULYMap; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = dfYDim; } if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( poOpenInfo->pszFilename, "cbw", poDS->adfGeoTransform ); if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( poOpenInfo->pszFilename, "wld", poDS->adfGeoTransform ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
static int ProxyMain(int argc, char **argv) { GDALDatasetH hDataset, hOutDS; int i; int nRasterXSize, nRasterYSize; const char *pszSource = NULL, *pszDest = NULL, *pszFormat = "GTiff"; GDALDriverH hDriver; int *panBandList = NULL; /* negative value of panBandList[i] means mask band of ABS(panBandList[i]) */ int nBandCount = 0, bDefBands = TRUE; double adfGeoTransform[6]; GDALDataType eOutputType = GDT_Unknown; int nOXSize = 0, nOYSize = 0; char *pszOXSize = NULL, *pszOYSize = NULL; char **papszCreateOptions = NULL; int anSrcWin[4], bStrict = FALSE; const char *pszProjection; int bScale = FALSE, bHaveScaleSrc = FALSE, bUnscale = FALSE; double dfScaleSrcMin = 0.0, dfScaleSrcMax = 255.0; double dfScaleDstMin = 0.0, dfScaleDstMax = 255.0; double dfULX, dfULY, dfLRX, dfLRY; char **papszMetadataOptions = NULL; char *pszOutputSRS = NULL; int bQuiet = FALSE, bGotBounds = FALSE; GDALProgressFunc pfnProgress = GDALTermProgress; int nGCPCount = 0; GDAL_GCP *pasGCPs = NULL; int iSrcFileArg = -1, iDstFileArg = -1; int bCopySubDatasets = FALSE; double adfULLR[4] = { 0, 0, 0, 0 }; int bSetNoData = FALSE; int bUnsetNoData = FALSE; double dfNoDataReal = 0.0; int nRGBExpand = 0; int bParsedMaskArgument = FALSE; int eMaskMode = MASK_AUTO; int nMaskBand = 0; /* negative value means mask band of ABS(nMaskBand) */ int bStats = FALSE, bApproxStats = FALSE; anSrcWin[0] = 0; anSrcWin[1] = 0; anSrcWin[2] = 0; anSrcWin[3] = 0; dfULX = dfULY = dfLRX = dfLRY = 0.0; /* Check strict compilation and runtime library version as we use C++ API */ if (!GDAL_CHECK_VERSION(argv[0])) exit(1); /* Must process GDAL_SKIP before GDALAllRegister(), but we can't call */ /* GDALGeneralCmdLineProcessor before it needs the drivers to be registered */ /* for the --format or --formats options */ for (i = 1; i < argc; i++) { if (EQUAL(argv[i], "--config") && i + 2 < argc && EQUAL(argv[i + 1], "GDAL_SKIP")) { CPLSetConfigOption(argv[i + 1], argv[i + 2]); i += 2; } } /* -------------------------------------------------------------------- */ /* Register standard GDAL drivers, and process generic GDAL */ /* command options. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); argc = GDALGeneralCmdLineProcessor(argc, &argv, 0); if (argc < 1) exit(-argc); /* -------------------------------------------------------------------- */ /* Handle command line arguments. */ /* -------------------------------------------------------------------- */ for (i = 1; i < argc; i++) { if (EQUAL(argv[i], "--utility_version")) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if (EQUAL(argv[i], "-of") && i < argc - 1) pszFormat = argv[++i]; else if (EQUAL(argv[i], "-q") || EQUAL(argv[i], "-quiet")) { bQuiet = TRUE; pfnProgress = GDALDummyProgress; } else if (EQUAL(argv[i], "-ot") && i < argc - 1) { int iType; for (iType = 1; iType < GDT_TypeCount; iType++) { if (GDALGetDataTypeName((GDALDataType)iType) != NULL && EQUAL(GDALGetDataTypeName((GDALDataType)iType), argv[i + 1])) { eOutputType = (GDALDataType) iType; } } if (eOutputType == GDT_Unknown) { printf("Unknown output pixel type: %s\n", argv[i + 1]); Usage(); GDALDestroyDriverManager(); exit(2); } i++; } else if (EQUAL(argv[i], "-b") && i < argc - 1) { const char *pszBand = argv[i + 1]; int bMask = FALSE; if (EQUAL(pszBand, "mask")) pszBand = "mask,1"; if (EQUALN(pszBand, "mask,", 5)) { bMask = TRUE; pszBand += 5; /* If we use tha source mask band as a regular band */ /* don't create a target mask band by default */ if (!bParsedMaskArgument) eMaskMode = MASK_DISABLED; } int nBand = atoi(pszBand); if (nBand < 1) { printf("Unrecognizable band number (%s).\n", argv[i + 1]); Usage(); GDALDestroyDriverManager(); exit(2); } i++; nBandCount++; panBandList = (int*) CPLRealloc(panBandList, sizeof(int) * nBandCount); panBandList[nBandCount - 1] = nBand; if (bMask) panBandList[nBandCount - 1] *= -1; if (panBandList[nBandCount - 1] != nBandCount) bDefBands = FALSE; } else if (EQUAL(argv[i], "-mask") && i < argc - 1) { bParsedMaskArgument = TRUE; const char *pszBand = argv[i + 1]; if (EQUAL(pszBand, "none")) { eMaskMode = MASK_DISABLED; } else if (EQUAL(pszBand, "auto")) { eMaskMode = MASK_AUTO; } else { int bMask = FALSE; if (EQUAL(pszBand, "mask")) pszBand = "mask,1"; if (EQUALN(pszBand, "mask,", 5)) { bMask = TRUE; pszBand += 5; } int nBand = atoi(pszBand); if (nBand < 1) { printf("Unrecognizable band number (%s).\n", argv[i + 1]); Usage(); GDALDestroyDriverManager(); exit(2); } eMaskMode = MASK_USER; nMaskBand = nBand; if (bMask) nMaskBand *= -1; } i++; } else if (EQUAL(argv[i], "-not_strict")) bStrict = FALSE; else if (EQUAL(argv[i], "-strict")) bStrict = TRUE; else if (EQUAL(argv[i], "-sds")) bCopySubDatasets = TRUE; else if (EQUAL(argv[i], "-gcp") && i < argc - 4) { char *endptr = NULL; /* -gcp pixel line easting northing [elev] */ nGCPCount++; pasGCPs = (GDAL_GCP*) CPLRealloc(pasGCPs, sizeof(GDAL_GCP) * nGCPCount); GDALInitGCPs(1, pasGCPs + nGCPCount - 1); pasGCPs[nGCPCount - 1].dfGCPPixel = CPLAtofM(argv[++i]); pasGCPs[nGCPCount - 1].dfGCPLine = CPLAtofM(argv[++i]); pasGCPs[nGCPCount - 1].dfGCPX = CPLAtofM(argv[++i]); pasGCPs[nGCPCount - 1].dfGCPY = CPLAtofM(argv[++i]); if (argv[i + 1] != NULL && (CPLStrtod(argv[i + 1], &endptr) != 0.0 || argv[i + 1][0] == '0')) { /* Check that last argument is really a number and not a filename */ /* looking like a number (see ticket #863) */ if (endptr && *endptr == 0) pasGCPs[nGCPCount - 1].dfGCPZ = CPLAtofM(argv[++i]); } /* should set id and info? */ } else if (EQUAL(argv[i], "-a_nodata") && i < argc - 1) { if (EQUAL(argv[i + 1], "none")) { bUnsetNoData = TRUE; } else { bSetNoData = TRUE; dfNoDataReal = CPLAtofM(argv[i + 1]); } i += 1; } else if (EQUAL(argv[i], "-a_ullr") && i < argc - 4) { adfULLR[0] = CPLAtofM(argv[i + 1]); adfULLR[1] = CPLAtofM(argv[i + 2]); adfULLR[2] = CPLAtofM(argv[i + 3]); adfULLR[3] = CPLAtofM(argv[i + 4]); bGotBounds = TRUE; i += 4; } else if (EQUAL(argv[i], "-co") && i < argc - 1) { papszCreateOptions = CSLAddString(papszCreateOptions, argv[++i]); } else if (EQUAL(argv[i], "-scale")) { bScale = TRUE; if (i < argc - 2 && ArgIsNumeric(argv[i + 1])) { bHaveScaleSrc = TRUE; dfScaleSrcMin = CPLAtofM(argv[i + 1]); dfScaleSrcMax = CPLAtofM(argv[i + 2]); i += 2; } if (i < argc - 2 && bHaveScaleSrc && ArgIsNumeric(argv[i + 1])) { dfScaleDstMin = CPLAtofM(argv[i + 1]); dfScaleDstMax = CPLAtofM(argv[i + 2]); i += 2; } else { dfScaleDstMin = 0.0; dfScaleDstMax = 255.999; } } else if (EQUAL(argv[i], "-unscale")) { bUnscale = TRUE; } else if (EQUAL(argv[i], "-mo") && i < argc - 1) { papszMetadataOptions = CSLAddString(papszMetadataOptions, argv[++i]); } else if (EQUAL(argv[i], "-outsize") && i < argc - 2) { pszOXSize = argv[++i]; pszOYSize = argv[++i]; } else if (EQUAL(argv[i], "-srcwin") && i < argc - 4) { anSrcWin[0] = atoi(argv[++i]); anSrcWin[1] = atoi(argv[++i]); anSrcWin[2] = atoi(argv[++i]); anSrcWin[3] = atoi(argv[++i]); } else if (EQUAL(argv[i], "-projwin") && i < argc - 4) { dfULX = CPLAtofM(argv[++i]); dfULY = CPLAtofM(argv[++i]); dfLRX = CPLAtofM(argv[++i]); dfLRY = CPLAtofM(argv[++i]); } else if (EQUAL(argv[i], "-a_srs") && i < argc - 1) { OGRSpatialReference oOutputSRS; if (oOutputSRS.SetFromUserInput(argv[i + 1]) != OGRERR_NONE) { fprintf(stderr, "Failed to process SRS definition: %s\n", argv[i + 1]); GDALDestroyDriverManager(); exit(1); } oOutputSRS.exportToWkt(&pszOutputSRS); i++; } else if (EQUAL(argv[i], "-expand") && i < argc - 1) { if (EQUAL(argv[i + 1], "gray")) nRGBExpand = 1; else if (EQUAL(argv[i + 1], "rgb")) nRGBExpand = 3; else if (EQUAL(argv[i + 1], "rgba")) nRGBExpand = 4; else { printf("Value %s unsupported. Only gray, rgb or rgba are supported.\n\n", argv[i]); Usage(); GDALDestroyDriverManager(); exit(2); } i++; } else if (EQUAL(argv[i], "-stats")) { bStats = TRUE; bApproxStats = FALSE; } else if (EQUAL(argv[i], "-approx_stats")) { bStats = TRUE; bApproxStats = TRUE; } else if (argv[i][0] == '-') { printf("Option %s incomplete, or not recognised.\n\n", argv[i]); Usage(); GDALDestroyDriverManager(); exit(2); } else if (pszSource == NULL) { iSrcFileArg = i; pszSource = argv[i]; } else if (pszDest == NULL) { pszDest = argv[i]; iDstFileArg = i; } else { printf("Too many command options.\n\n"); Usage(); GDALDestroyDriverManager(); exit(2); } } if (pszDest == NULL) { Usage(); GDALDestroyDriverManager(); exit(10); } if (strcmp(pszSource, pszDest) == 0) { fprintf(stderr, "Source and destination datasets must be different.\n"); GDALDestroyDriverManager(); exit(1); } if (strcmp(pszDest, "/vsistdout/") == 0) { bQuiet = TRUE; pfnProgress = GDALDummyProgress; } /* -------------------------------------------------------------------- */ /* Attempt to open source file. */ /* -------------------------------------------------------------------- */ hDataset = GDALOpenShared(pszSource, GA_ReadOnly); if (hDataset == NULL) { fprintf(stderr, "GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(), CPLGetLastErrorMsg()); GDALDestroyDriverManager(); exit(1); } /* -------------------------------------------------------------------- */ /* Handle subdatasets. */ /* -------------------------------------------------------------------- */ if (!bCopySubDatasets && CSLCount(GDALGetMetadata(hDataset, "SUBDATASETS")) > 0 && GDALGetRasterCount(hDataset) == 0) { fprintf(stderr, "Input file contains subdatasets. Please, select one of them for reading.\n"); GDALClose(hDataset); GDALDestroyDriverManager(); exit(1); } if (CSLCount(GDALGetMetadata(hDataset, "SUBDATASETS")) > 0 && bCopySubDatasets) { char **papszSubdatasets = GDALGetMetadata(hDataset, "SUBDATASETS"); char *pszSubDest = (char*) CPLMalloc(strlen(pszDest) + 32); int i; int bOldSubCall = bSubCall; char **papszDupArgv = CSLDuplicate(argv); int nRet = 0; CPLFree(papszDupArgv[iDstFileArg]); papszDupArgv[iDstFileArg] = pszSubDest; bSubCall = TRUE; for (i = 0; papszSubdatasets[i] != NULL; i += 2) { CPLFree(papszDupArgv[iSrcFileArg]); papszDupArgv[iSrcFileArg] = CPLStrdup(strstr(papszSubdatasets[i], "=") + 1); sprintf(pszSubDest, "%s%d", pszDest, i / 2 + 1); nRet = ProxyMain(argc, papszDupArgv); if (nRet != 0) break; } CSLDestroy(papszDupArgv); bSubCall = bOldSubCall; CSLDestroy(argv); GDALClose(hDataset); if (!bSubCall) { GDALDumpOpenDatasets(stderr); GDALDestroyDriverManager(); } return nRet; } /* -------------------------------------------------------------------- */ /* Collect some information from the source file. */ /* -------------------------------------------------------------------- */ nRasterXSize = GDALGetRasterXSize(hDataset); nRasterYSize = GDALGetRasterYSize(hDataset); if (!bQuiet) printf("Input file size is %d, %d\n", nRasterXSize, nRasterYSize); if (anSrcWin[2] == 0 && anSrcWin[3] == 0) { anSrcWin[2] = nRasterXSize; anSrcWin[3] = nRasterYSize; } /* -------------------------------------------------------------------- */ /* Build band list to translate */ /* -------------------------------------------------------------------- */ if (nBandCount == 0) { nBandCount = GDALGetRasterCount(hDataset); if (nBandCount == 0) { fprintf(stderr, "Input file has no bands, and so cannot be translated.\n"); GDALDestroyDriverManager(); exit(1); } panBandList = (int*) CPLMalloc(sizeof(int) * nBandCount); for (i = 0; i < nBandCount; i++) panBandList[i] = i + 1; } else { for (i = 0; i < nBandCount; i++) { if (ABS(panBandList[i]) > GDALGetRasterCount(hDataset)) { fprintf(stderr, "Band %d requested, but only bands 1 to %d available.\n", ABS(panBandList[i]), GDALGetRasterCount(hDataset)); GDALDestroyDriverManager(); exit(2); } } if (nBandCount != GDALGetRasterCount(hDataset)) bDefBands = FALSE; } /* -------------------------------------------------------------------- */ /* Compute the source window from the projected source window */ /* if the projected coordinates were provided. Note that the */ /* projected coordinates are in ulx, uly, lrx, lry format, */ /* while the anSrcWin is xoff, yoff, xsize, ysize with the */ /* xoff,yoff being the ulx, uly in pixel/line. */ /* -------------------------------------------------------------------- */ if (dfULX != 0.0 || dfULY != 0.0 || dfLRX != 0.0 || dfLRY != 0.0) { double adfGeoTransform[6]; GDALGetGeoTransform(hDataset, adfGeoTransform); if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0) { fprintf(stderr, "The -projwin option was used, but the geotransform is\n" "rotated. This configuration is not supported.\n"); GDALClose(hDataset); CPLFree(panBandList); GDALDestroyDriverManager(); exit(1); } anSrcWin[0] = (int) ((dfULX - adfGeoTransform[0]) / adfGeoTransform[1] + 0.001); anSrcWin[1] = (int) ((dfULY - adfGeoTransform[3]) / adfGeoTransform[5] + 0.001); anSrcWin[2] = (int) ((dfLRX - dfULX) / adfGeoTransform[1] + 0.5); anSrcWin[3] = (int) ((dfLRY - dfULY) / adfGeoTransform[5] + 0.5); if (!bQuiet) fprintf(stdout, "Computed -srcwin %d %d %d %d from projected window.\n", anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3]); if (anSrcWin[0] < 0 || anSrcWin[1] < 0 || anSrcWin[0] + anSrcWin[2] > GDALGetRasterXSize(hDataset) || anSrcWin[1] + anSrcWin[3] > GDALGetRasterYSize(hDataset)) { fprintf(stderr, "Computed -srcwin falls outside raster size of %dx%d.\n", GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset)); exit(1); } } /* -------------------------------------------------------------------- */ /* Verify source window. */ /* -------------------------------------------------------------------- */ if (anSrcWin[0] < 0 || anSrcWin[1] < 0 || anSrcWin[2] <= 0 || anSrcWin[3] <= 0 || anSrcWin[0] + anSrcWin[2] > GDALGetRasterXSize(hDataset) || anSrcWin[1] + anSrcWin[3] > GDALGetRasterYSize(hDataset)) { fprintf(stderr, "-srcwin %d %d %d %d falls outside raster size of %dx%d\n" "or is otherwise illegal.\n", anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset)); exit(1); } /* -------------------------------------------------------------------- */ /* Find the output driver. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDriverByName(pszFormat); if (hDriver == NULL) { int iDr; printf("Output driver `%s' not recognised.\n", pszFormat); printf("The following format drivers are configured and support output:\n"); for (iDr = 0; iDr < GDALGetDriverCount(); iDr++) { GDALDriverH hDriver = GDALGetDriver(iDr); if (GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATE, NULL) != NULL || GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATECOPY, NULL) != NULL) { printf(" %s: %s\n", GDALGetDriverShortName(hDriver), GDALGetDriverLongName(hDriver)); } } printf("\n"); Usage(); GDALClose(hDataset); CPLFree(panBandList); GDALDestroyDriverManager(); CSLDestroy(argv); CSLDestroy(papszCreateOptions); exit(1); } /* -------------------------------------------------------------------- */ /* The short form is to CreateCopy(). We use this if the input */ /* matches the whole dataset. Eventually we should rewrite */ /* this entire program to use virtual datasets to construct a */ /* virtual input source to copy from. */ /* -------------------------------------------------------------------- */ int bSpatialArrangementPreserved = ( anSrcWin[0] == 0 && anSrcWin[1] == 0 && anSrcWin[2] == GDALGetRasterXSize(hDataset) && anSrcWin[3] == GDALGetRasterYSize(hDataset) && pszOXSize == NULL && pszOYSize == NULL); if (eOutputType == GDT_Unknown && !bScale && !bUnscale && CSLCount(papszMetadataOptions) == 0 && bDefBands && eMaskMode == MASK_AUTO && bSpatialArrangementPreserved && nGCPCount == 0 && !bGotBounds && pszOutputSRS == NULL && !bSetNoData && !bUnsetNoData && nRGBExpand == 0 && !bStats) { hOutDS = GDALCreateCopy(hDriver, pszDest, hDataset, bStrict, papszCreateOptions, pfnProgress, NULL); if (hOutDS != NULL) GDALClose(hOutDS); GDALClose(hDataset); CPLFree(panBandList); if (!bSubCall) { GDALDumpOpenDatasets(stderr); GDALDestroyDriverManager(); } CSLDestroy(argv); CSLDestroy(papszCreateOptions); return hOutDS == NULL; } /* -------------------------------------------------------------------- */ /* Establish some parameters. */ /* -------------------------------------------------------------------- */ if (pszOXSize == NULL) { nOXSize = anSrcWin[2]; nOYSize = anSrcWin[3]; } else { nOXSize = (int) ((pszOXSize[strlen(pszOXSize) - 1] == '%' ? CPLAtofM(pszOXSize) / 100 * anSrcWin[2] : atoi(pszOXSize))); nOYSize = (int) ((pszOYSize[strlen(pszOYSize) - 1] == '%' ? CPLAtofM(pszOYSize) / 100 * anSrcWin[3] : atoi(pszOYSize))); } /* ==================================================================== */ /* Create a virtual dataset. */ /* ==================================================================== */ VRTDataset *poVDS; /* -------------------------------------------------------------------- */ /* Make a virtual clone. */ /* -------------------------------------------------------------------- */ poVDS = (VRTDataset*) VRTCreate(nOXSize, nOYSize); if (nGCPCount == 0) { if (pszOutputSRS != NULL) { poVDS->SetProjection(pszOutputSRS); } else { pszProjection = GDALGetProjectionRef(hDataset); if (pszProjection != NULL && strlen(pszProjection) > 0) poVDS->SetProjection(pszProjection); } } if (bGotBounds) { adfGeoTransform[0] = adfULLR[0]; adfGeoTransform[1] = (adfULLR[2] - adfULLR[0]) / nOXSize; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = adfULLR[1]; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = (adfULLR[3] - adfULLR[1]) / nOYSize; poVDS->SetGeoTransform(adfGeoTransform); } else if (GDALGetGeoTransform(hDataset, adfGeoTransform) == CE_None && nGCPCount == 0) { adfGeoTransform[0] += anSrcWin[0] * adfGeoTransform[1] + anSrcWin[1] * adfGeoTransform[2]; adfGeoTransform[3] += anSrcWin[0] * adfGeoTransform[4] + anSrcWin[1] * adfGeoTransform[5]; adfGeoTransform[1] *= anSrcWin[2] / (double) nOXSize; adfGeoTransform[2] *= anSrcWin[3] / (double) nOYSize; adfGeoTransform[4] *= anSrcWin[2] / (double) nOXSize; adfGeoTransform[5] *= anSrcWin[3] / (double) nOYSize; poVDS->SetGeoTransform(adfGeoTransform); } if (nGCPCount != 0) { const char *pszGCPProjection = pszOutputSRS; if (pszGCPProjection == NULL) pszGCPProjection = GDALGetGCPProjection(hDataset); if (pszGCPProjection == NULL) pszGCPProjection = ""; poVDS->SetGCPs(nGCPCount, pasGCPs, pszGCPProjection); GDALDeinitGCPs(nGCPCount, pasGCPs); CPLFree(pasGCPs); } else if (GDALGetGCPCount(hDataset) > 0) { GDAL_GCP *pasGCPs; int nGCPs = GDALGetGCPCount(hDataset); pasGCPs = GDALDuplicateGCPs(nGCPs, GDALGetGCPs(hDataset)); for (i = 0; i < nGCPs; i++) { pasGCPs[i].dfGCPPixel -= anSrcWin[0]; pasGCPs[i].dfGCPLine -= anSrcWin[1]; pasGCPs[i].dfGCPPixel *= (nOXSize / (double) anSrcWin[2]); pasGCPs[i].dfGCPLine *= (nOYSize / (double) anSrcWin[3]); } poVDS->SetGCPs(nGCPs, pasGCPs, GDALGetGCPProjection(hDataset)); GDALDeinitGCPs(nGCPs, pasGCPs); CPLFree(pasGCPs); } /* -------------------------------------------------------------------- */ /* Transfer generally applicable metadata. */ /* -------------------------------------------------------------------- */ poVDS->SetMetadata(((GDALDataset*)hDataset)->GetMetadata()); AttachMetadata((GDALDatasetH) poVDS, papszMetadataOptions); const char *pszInterleave = GDALGetMetadataItem(hDataset, "INTERLEAVE", "IMAGE_STRUCTURE"); if (pszInterleave) poVDS->SetMetadataItem("INTERLEAVE", pszInterleave, "IMAGE_STRUCTURE"); /* -------------------------------------------------------------------- */ /* Transfer metadata that remains valid if the spatial */ /* arrangement of the data is unaltered. */ /* -------------------------------------------------------------------- */ if (bSpatialArrangementPreserved) { char **papszMD; papszMD = ((GDALDataset*)hDataset)->GetMetadata("RPC"); if (papszMD != NULL) poVDS->SetMetadata(papszMD, "RPC"); papszMD = ((GDALDataset*)hDataset)->GetMetadata("GEOLOCATION"); if (papszMD != NULL) poVDS->SetMetadata(papszMD, "GEOLOCATION"); } int nSrcBandCount = nBandCount; if (nRGBExpand != 0) { GDALRasterBand *poSrcBand; poSrcBand = ((GDALDataset*) hDataset)->GetRasterBand(ABS(panBandList[0])); if (panBandList[0] < 0) poSrcBand = poSrcBand->GetMaskBand(); GDALColorTable *poColorTable = poSrcBand->GetColorTable(); if (poColorTable == NULL) { fprintf(stderr, "Error : band %d has no color table\n", ABS(panBandList[0])); GDALClose(hDataset); CPLFree(panBandList); GDALDestroyDriverManager(); CSLDestroy(argv); CSLDestroy(papszCreateOptions); exit(1); } /* Check that the color table only contains gray levels */ /* when using -expand gray */ if (nRGBExpand == 1) { int nColorCount = poColorTable->GetColorEntryCount(); int nColor; for (nColor = 0; nColor < nColorCount; nColor++) { const GDALColorEntry *poEntry = poColorTable->GetColorEntry(nColor); if (poEntry->c1 != poEntry->c2 || poEntry->c1 != poEntry->c2) { fprintf(stderr, "Warning : color table contains non gray levels colors\n"); break; } } } if (nBandCount == 1) nBandCount = nRGBExpand; else if (nBandCount == 2 && (nRGBExpand == 3 || nRGBExpand == 4)) nBandCount = nRGBExpand; else { fprintf(stderr, "Error : invalid use of -expand option.\n"); exit(1); } } int bFilterOutStatsMetadata = (bScale || bUnscale || !bSpatialArrangementPreserved || nRGBExpand != 0); /* ==================================================================== */ /* Process all bands. */ /* ==================================================================== */ for (i = 0; i < nBandCount; i++) { VRTSourcedRasterBand *poVRTBand; GDALRasterBand *poSrcBand; GDALDataType eBandType; int nComponent = 0; int nSrcBand; if (nRGBExpand != 0) { if (nSrcBandCount == 2 && nRGBExpand == 4 && i == 3) nSrcBand = panBandList[1]; else { nSrcBand = panBandList[0]; nComponent = i + 1; } } else nSrcBand = panBandList[i]; poSrcBand = ((GDALDataset*) hDataset)->GetRasterBand(ABS(nSrcBand)); /* -------------------------------------------------------------------- */ /* Select output data type to match source. */ /* -------------------------------------------------------------------- */ if (eOutputType == GDT_Unknown) eBandType = poSrcBand->GetRasterDataType(); else eBandType = eOutputType; /* -------------------------------------------------------------------- */ /* Create this band. */ /* -------------------------------------------------------------------- */ poVDS->AddBand(eBandType, NULL); poVRTBand = (VRTSourcedRasterBand*) poVDS->GetRasterBand(i + 1); if (nSrcBand < 0) { poVRTBand->AddMaskBandSource(poSrcBand); continue; } /* -------------------------------------------------------------------- */ /* Do we need to collect scaling information? */ /* -------------------------------------------------------------------- */ double dfScale = 1.0, dfOffset = 0.0; if (bScale && !bHaveScaleSrc) { double adfCMinMax[2]; GDALComputeRasterMinMax(poSrcBand, TRUE, adfCMinMax); dfScaleSrcMin = adfCMinMax[0]; dfScaleSrcMax = adfCMinMax[1]; } if (bScale) { if (dfScaleSrcMax == dfScaleSrcMin) dfScaleSrcMax += 0.1; if (dfScaleDstMax == dfScaleDstMin) dfScaleDstMax += 0.1; dfScale = (dfScaleDstMax - dfScaleDstMin) / (dfScaleSrcMax - dfScaleSrcMin); dfOffset = -1 * dfScaleSrcMin * dfScale + dfScaleDstMin; } if (bUnscale) { dfScale = poSrcBand->GetScale(); dfOffset = poSrcBand->GetOffset(); } /* -------------------------------------------------------------------- */ /* Create a simple or complex data source depending on the */ /* translation type required. */ /* -------------------------------------------------------------------- */ if (bUnscale || bScale || (nRGBExpand != 0 && i < nRGBExpand)) { poVRTBand->AddComplexSource(poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize, dfOffset, dfScale, VRT_NODATA_UNSET, nComponent); } else poVRTBand->AddSimpleSource(poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize); /* -------------------------------------------------------------------- */ /* In case of color table translate, we only set the color */ /* interpretation other info copied by CopyBandInfo are */ /* not relevant in RGB expansion. */ /* -------------------------------------------------------------------- */ if (nRGBExpand == 1) { poVRTBand->SetColorInterpretation(GCI_GrayIndex); } else if (nRGBExpand != 0 && i < nRGBExpand) { poVRTBand->SetColorInterpretation((GDALColorInterp) (GCI_RedBand + i)); } /* -------------------------------------------------------------------- */ /* copy over some other information of interest. */ /* -------------------------------------------------------------------- */ else { CopyBandInfo(poSrcBand, poVRTBand, !bStats && !bFilterOutStatsMetadata, !bUnscale, !bSetNoData && !bUnsetNoData); } /* -------------------------------------------------------------------- */ /* Set a forcable nodata value? */ /* -------------------------------------------------------------------- */ if (bSetNoData) { double dfVal = dfNoDataReal; int bClamped = FALSE, bRounded = FALSE; #define CLAMP(val, type, minval, maxval) \ do { if (val < minval) { bClamped = TRUE; val = minval; \ } \ else if (val > maxval) { bClamped = TRUE; val = maxval; } \ else if (val != (type)val) { bRounded = TRUE; val = (type)(val + 0.5); } \ } \ while (0) switch (eBandType) { case GDT_Byte: CLAMP(dfVal, GByte, 0.0, 255.0); break; case GDT_Int16: CLAMP(dfVal, GInt16, -32768.0, 32767.0); break; case GDT_UInt16: CLAMP(dfVal, GUInt16, 0.0, 65535.0); break; case GDT_Int32: CLAMP(dfVal, GInt32, -2147483648.0, 2147483647.0); break; case GDT_UInt32: CLAMP(dfVal, GUInt32, 0.0, 4294967295.0); break; default: break; } if (bClamped) { printf("for band %d, nodata value has been clamped " "to %.0f, the original value being out of range.\n", i + 1, dfVal); } else if (bRounded) { printf("for band %d, nodata value has been rounded " "to %.0f, %s being an integer datatype.\n", i + 1, dfVal, GDALGetDataTypeName(eBandType)); } poVRTBand->SetNoDataValue(dfVal); } if (eMaskMode == MASK_AUTO && (GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) & GMF_PER_DATASET) == 0 && (poSrcBand->GetMaskFlags() & (GMF_ALL_VALID | GMF_NODATA)) == 0) { if (poVRTBand->CreateMaskBand(poSrcBand->GetMaskFlags()) == CE_None) { VRTSourcedRasterBand *hMaskVRTBand = (VRTSourcedRasterBand*)poVRTBand->GetMaskBand(); hMaskVRTBand->AddMaskBandSource(poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize); } } } if (eMaskMode == MASK_USER) { GDALRasterBand *poSrcBand = (GDALRasterBand*)GDALGetRasterBand(hDataset, ABS(nMaskBand)); if (poSrcBand && poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None) { VRTSourcedRasterBand *hMaskVRTBand = (VRTSourcedRasterBand*) GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1)); if (nMaskBand > 0) hMaskVRTBand->AddSimpleSource(poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize); else hMaskVRTBand->AddMaskBandSource(poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize); } } else if (eMaskMode == MASK_AUTO && nSrcBandCount > 0 && GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) == GMF_PER_DATASET) { if (poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None) { VRTSourcedRasterBand *hMaskVRTBand = (VRTSourcedRasterBand*) GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1)); hMaskVRTBand->AddMaskBandSource((GDALRasterBand*)GDALGetRasterBand(hDataset, 1), anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize); } } /* -------------------------------------------------------------------- */ /* Compute stats if required. */ /* -------------------------------------------------------------------- */ if (bStats) { for (i = 0; i < poVDS->GetRasterCount(); i++) { double dfMin, dfMax, dfMean, dfStdDev; poVDS->GetRasterBand(i + 1)->ComputeStatistics(bApproxStats, &dfMin, &dfMax, &dfMean, &dfStdDev, GDALDummyProgress, NULL); } } /* -------------------------------------------------------------------- */ /* Write to the output file using CopyCreate(). */ /* -------------------------------------------------------------------- */ hOutDS = GDALCreateCopy(hDriver, pszDest, (GDALDatasetH) poVDS, bStrict, papszCreateOptions, pfnProgress, NULL); if (hOutDS != NULL) { int bHasGotErr = FALSE; CPLErrorReset(); GDALFlushCache(hOutDS); if (CPLGetLastErrorType() != CE_None) bHasGotErr = TRUE; GDALClose(hOutDS); if (bHasGotErr) hOutDS = NULL; } GDALClose((GDALDatasetH) poVDS); GDALClose(hDataset); CPLFree(panBandList); CPLFree(pszOutputSRS); if (!bSubCall) { GDALDumpOpenDatasets(stderr); GDALDestroyDriverManager(); } CSLDestroy(argv); CSLDestroy(papszCreateOptions); return hOutDS == NULL; }
int main( int argc, char ** argv ) { int i; int bGotSRS = FALSE; int bPretty = FALSE; int bValidate = FALSE; int bFindEPSG = FALSE; int nEPSGCode = -1; const char *pszInput = NULL; const char *pszOutputType = "default"; OGRSpatialReference oSRS; /* Check strict compilation and runtime library version as we use C++ API */ if (! GDAL_CHECK_VERSION(argv[0])) exit(1); EarlySetConfigOptions(argc, argv); /* -------------------------------------------------------------------- */ /* Register standard GDAL and OGR drivers. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); #ifdef OGR_ENABLED OGRRegisterAll(); #endif /* -------------------------------------------------------------------- */ /* Register standard GDAL drivers, and process generic GDAL */ /* command options. */ /* -------------------------------------------------------------------- */ argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ for( i = 1; i < argc; i++ ) { CPLDebug( "gdalsrsinfo", "got arg #%d : [%s]", i, argv[i] ); if( EQUAL(argv[i], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(argv[i], "-h") || EQUAL(argv[i], "--help") ) Usage(); else if( EQUAL(argv[i], "-e") ) bFindEPSG = TRUE; else if( EQUAL(argv[i], "-o") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszOutputType = argv[++i]; } else if( EQUAL(argv[i], "-p") ) bPretty = TRUE; else if( EQUAL(argv[i], "-V") ) bValidate = TRUE; else if( argv[i][0] == '-' ) { Usage(CPLSPrintf("Unknown option name '%s'", argv[i])); } else pszInput = argv[i]; } if ( pszInput == NULL ) { CSLDestroy( argv ); Usage("No input specified."); } /* Search for SRS */ bGotSRS = FindSRS( pszInput, oSRS ); CPLDebug( "gdalsrsinfo", "bGotSRS: %d bValidate: %d pszOutputType: %s bPretty: %d", bGotSRS, bValidate, pszOutputType, bPretty ); /* Make sure we got a SRS */ if ( ! bGotSRS ) { CPLError( CE_Failure, CPLE_AppDefined, "ERROR - failed to load SRS definition from %s", pszInput ); } else { /* Find EPSG code - experimental */ if ( EQUAL(pszOutputType,"epsg") ) bFindEPSG = TRUE; if ( bFindEPSG ) { CPLError( CE_Warning, CPLE_AppDefined, "EPSG detection is experimental and requires new data files (see bug #4345)" ); nEPSGCode = FindEPSG( oSRS ); /* If found, replace oSRS based on EPSG code */ if(nEPSGCode != -1) { CPLDebug( "gdalsrsinfo", "Found EPSG code %d", nEPSGCode ); OGRSpatialReference oSRS2; if ( oSRS2.importFromEPSG( nEPSGCode ) == OGRERR_NONE ) oSRS = oSRS2; } } /* Validate - not well tested!*/ if ( bValidate ) { OGRErr eErr = oSRS.Validate( ); if ( eErr != OGRERR_NONE ) { printf( "\nValidate Fails" ); if ( eErr == OGRERR_CORRUPT_DATA ) printf( " - SRS is not well formed"); else if ( eErr == OGRERR_UNSUPPORTED_SRS ) printf(" - contains non-standard PROJECTION[] values"); printf("\n"); } else printf( "\nValidate Succeeds\n" ); } /* Output */ if ( EQUAL("default", pszOutputType ) ) { /* does this work in MSVC? */ const char* papszOutputTypes[] = { "proj4", "wkt", NULL }; if ( bFindEPSG ) printf("\nEPSG:%d\n",nEPSGCode); PrintSRSOutputTypes( oSRS, papszOutputTypes ); } else if ( EQUAL("all", pszOutputType ) ) { if ( bFindEPSG ) printf("\nEPSG:%d\n\n",nEPSGCode); const char* papszOutputTypes[] = {"proj4","wkt","wkt_simple","wkt_noct","wkt_esri","mapinfo","xml",NULL}; PrintSRSOutputTypes( oSRS, papszOutputTypes ); } else if ( EQUAL("wkt_all", pszOutputType ) ) { const char* papszOutputTypes[] = { "wkt", "wkt_simple", "wkt_noct", "wkt_esri", NULL }; PrintSRSOutputTypes( oSRS, papszOutputTypes ); } else { if ( bPretty ) printf( "\n" ); if ( EQUAL(pszOutputType,"epsg") ) printf("EPSG:%d\n",nEPSGCode); else PrintSRS( oSRS, pszOutputType, bPretty, FALSE ); if ( bPretty ) printf( "\n" ); } } /* cleanup anything left */ GDALDestroyDriverManager(); #ifdef OGR_ENABLED OGRCleanupAll(); #endif CSLDestroy( argv ); return 0; }
CPLErr GDALWMSDataset::Initialize(CPLXMLNode *config) { CPLErr ret = CE_None; char* pszXML = CPLSerializeXMLTree( config ); if (pszXML) { m_osXML = pszXML; CPLFree(pszXML); } // Initialize the minidriver, which can set parameters for the dataset using member functions CPLXMLNode *service_node = CPLGetXMLNode(config, "Service"); if (service_node != NULL) { const CPLString service_name = CPLGetXMLValue(service_node, "name", ""); if (!service_name.empty()) { GDALWMSMiniDriverManager *const mdm = GetGDALWMSMiniDriverManager(); GDALWMSMiniDriverFactory *const mdf = mdm->Find(service_name); if (mdf != NULL) { m_mini_driver = mdf->New(); m_mini_driver->m_parent_dataset = this; if (m_mini_driver->Initialize(service_node) == CE_None) { m_mini_driver_caps.m_capabilities_version = -1; m_mini_driver->GetCapabilities(&m_mini_driver_caps); if (m_mini_driver_caps.m_capabilities_version == -1) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Internal error, mini-driver capabilities version not set."); ret = CE_Failure; } } else { delete m_mini_driver; m_mini_driver = NULL; CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Failed to initialize minidriver."); ret = CE_Failure; } } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: No mini-driver registered for '%s'.", service_name.c_str()); ret = CE_Failure; } } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: No Service specified."); ret = CE_Failure; } } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: No Service specified."); ret = CE_Failure; } /* Parameters that could be set by minidriver already, based on server side information. If the size is set, minidriver has done this already A "server" side minidriver needs to set at least: - Blocksize (x and y) - Clamp flag (defaults to true) - DataWindow - Band Count - Data Type It should also initialize and register the bands and overviews. */ if (m_data_window.m_sx<1) { int nOverviews = 0; if (ret == CE_None) { m_block_size_x = atoi(CPLGetXMLValue(config, "BlockSizeX", CPLString().Printf("%d", m_default_block_size_x))); m_block_size_y = atoi(CPLGetXMLValue(config, "BlockSizeY", CPLString().Printf("%d", m_default_block_size_y))); if (m_block_size_x <= 0 || m_block_size_y <= 0) { CPLError( CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value in BlockSizeX or BlockSizeY" ); ret = CE_Failure; } } if (ret == CE_None) { m_clamp_requests = StrToBool(CPLGetXMLValue(config, "ClampRequests", "true")); if (m_clamp_requests<0) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of ClampRequests, true/false expected."); ret = CE_Failure; } } if (ret == CE_None) { CPLXMLNode *data_window_node = CPLGetXMLNode(config, "DataWindow"); if (data_window_node == NULL && m_bNeedsDataWindow) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: DataWindow missing."); ret = CE_Failure; } else { CPLString osDefaultX0, osDefaultX1, osDefaultY0, osDefaultY1; CPLString osDefaultTileCountX, osDefaultTileCountY, osDefaultTileLevel; CPLString osDefaultOverviewCount; osDefaultX0.Printf("%.8f", m_default_data_window.m_x0); osDefaultX1.Printf("%.8f", m_default_data_window.m_x1); osDefaultY0.Printf("%.8f", m_default_data_window.m_y0); osDefaultY1.Printf("%.8f", m_default_data_window.m_y1); osDefaultTileCountX.Printf("%d", m_default_tile_count_x); osDefaultTileCountY.Printf("%d", m_default_tile_count_y); if (m_default_data_window.m_tlevel >= 0) osDefaultTileLevel.Printf("%d", m_default_data_window.m_tlevel); if (m_default_overview_count >= 0) osDefaultOverviewCount.Printf("%d", m_default_overview_count); const char *overview_count = CPLGetXMLValue(config, "OverviewCount", osDefaultOverviewCount); const char *ulx = CPLGetXMLValue(data_window_node, "UpperLeftX", osDefaultX0); const char *uly = CPLGetXMLValue(data_window_node, "UpperLeftY", osDefaultY0); const char *lrx = CPLGetXMLValue(data_window_node, "LowerRightX", osDefaultX1); const char *lry = CPLGetXMLValue(data_window_node, "LowerRightY", osDefaultY1); const char *sx = CPLGetXMLValue(data_window_node, "SizeX", ""); const char *sy = CPLGetXMLValue(data_window_node, "SizeY", ""); const char *tx = CPLGetXMLValue(data_window_node, "TileX", "0"); const char *ty = CPLGetXMLValue(data_window_node, "TileY", "0"); const char *tlevel = CPLGetXMLValue(data_window_node, "TileLevel", osDefaultTileLevel); const char *str_tile_count_x = CPLGetXMLValue(data_window_node, "TileCountX", osDefaultTileCountX); const char *str_tile_count_y = CPLGetXMLValue(data_window_node, "TileCountY", osDefaultTileCountY); const char *y_origin = CPLGetXMLValue(data_window_node, "YOrigin", "default"); if (ret == CE_None) { if ((ulx[0] != '\0') && (uly[0] != '\0') && (lrx[0] != '\0') && (lry[0] != '\0')) { m_data_window.m_x0 = atof(ulx); m_data_window.m_y0 = atof(uly); m_data_window.m_x1 = atof(lrx); m_data_window.m_y1 = atof(lry); } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Mandatory elements of DataWindow missing: UpperLeftX, UpperLeftY, LowerRightX, LowerRightY."); ret = CE_Failure; } } m_data_window.m_tlevel = atoi(tlevel); if (ret == CE_None) { if ((sx[0] != '\0') && (sy[0] != '\0')) { m_data_window.m_sx = atoi(sx); m_data_window.m_sy = atoi(sy); } else if ((tlevel[0] != '\0') && (str_tile_count_x[0] != '\0') && (str_tile_count_y[0] != '\0')) { int tile_count_x = atoi(str_tile_count_x); int tile_count_y = atoi(str_tile_count_y); m_data_window.m_sx = tile_count_x * m_block_size_x * (1 << m_data_window.m_tlevel); m_data_window.m_sy = tile_count_y * m_block_size_y * (1 << m_data_window.m_tlevel); } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Mandatory elements of DataWindow missing: SizeX, SizeY."); ret = CE_Failure; } } if (ret == CE_None) { if ((tx[0] != '\0') && (ty[0] != '\0')) { m_data_window.m_tx = atoi(tx); m_data_window.m_ty = atoi(ty); } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Mandatory elements of DataWindow missing: TileX, TileY."); ret = CE_Failure; } } if (ret == CE_None) { if (overview_count[0] != '\0') { nOverviews = atoi(overview_count); } else if (tlevel[0] != '\0') { nOverviews = m_data_window.m_tlevel; } else { const int min_overview_size = MAX(32, MIN(m_block_size_x, m_block_size_y)); double a = log(static_cast<double>(MIN(m_data_window.m_sx, m_data_window.m_sy))) / log(2.0) - log(static_cast<double>(min_overview_size)) / log(2.0); nOverviews = MAX(0, MIN(static_cast<int>(ceil(a)), 32)); } } if (ret == CE_None) { CPLString y_origin_str = y_origin; if (y_origin_str == "top") { m_data_window.m_y_origin = GDALWMSDataWindow::TOP; } else if (y_origin_str == "bottom") { m_data_window.m_y_origin = GDALWMSDataWindow::BOTTOM; } else if (y_origin_str == "default") { m_data_window.m_y_origin = GDALWMSDataWindow::DEFAULT; } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: DataWindow YOrigin must be set to " "one of 'default', 'top', or 'bottom', not '%s'.", y_origin_str.c_str()); ret = CE_Failure; } } } } if (ret == CE_None) { if (nBands<1) nBands=atoi(CPLGetXMLValue(config,"BandsCount","3")); if (nBands<1) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Bad number of bands."); ret = CE_Failure; } } if (ret == CE_None) { const char *data_type = CPLGetXMLValue(config, "DataType", "Byte"); m_data_type = GDALGetDataTypeByName( data_type ); if ( m_data_type == GDT_Unknown || m_data_type >= GDT_TypeCount ) { CPLError( CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value in DataType. Data type \"%s\" is not supported.", data_type ); ret = CE_Failure; } } // Initialize the bands and the overviews. Assumes overviews are powers of two if (ret == CE_None) { nRasterXSize = m_data_window.m_sx; nRasterYSize = m_data_window.m_sy; if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize) || !GDALCheckBandCount(nBands, TRUE)) { return CE_Failure; } GDALColorInterp default_color_interp[4][4] = { { GCI_GrayIndex, GCI_Undefined, GCI_Undefined, GCI_Undefined }, { GCI_GrayIndex, GCI_AlphaBand, GCI_Undefined, GCI_Undefined }, { GCI_RedBand, GCI_GreenBand, GCI_BlueBand, GCI_Undefined }, { GCI_RedBand, GCI_GreenBand, GCI_BlueBand, GCI_AlphaBand } }; for (int i = 0; i < nBands; ++i) { GDALColorInterp color_interp = (nBands <= 4 && i <= 3 ? default_color_interp[nBands - 1][i] : GCI_Undefined); GDALWMSRasterBand *band = new GDALWMSRasterBand(this, i, 1.0); band->m_color_interp = color_interp; SetBand(i + 1, band); double scale = 0.5; for (int j = 0; j < nOverviews; ++j) { band->AddOverview(scale); band->m_color_interp = color_interp; scale *= 0.5; } } } } // UserPwd const char *pszUserPwd = CPLGetXMLValue(config, "UserPwd", ""); if (pszUserPwd[0] != '\0') m_osUserPwd = pszUserPwd; const char *pszUserAgent = CPLGetXMLValue(config, "UserAgent", ""); if (pszUserAgent[0] != '\0') m_osUserAgent = pszUserAgent; const char *pszReferer = CPLGetXMLValue(config, "Referer", ""); if (pszReferer[0] != '\0') m_osReferer = pszReferer; if (ret == CE_None) { const char *pszHttpZeroBlockCodes = CPLGetXMLValue(config, "ZeroBlockHttpCodes", ""); if(pszHttpZeroBlockCodes == '\0') { m_http_zeroblock_codes.push_back(204); } else { char **kv = CSLTokenizeString2(pszHttpZeroBlockCodes,",",CSLT_HONOURSTRINGS); int nCount = CSLCount(kv); for(int i=0; i<nCount; i++) { int code = atoi(kv[i]); if(code <= 0) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of ZeroBlockHttpCodes \"%s\", comma separated HTTP response codes expected.", kv[i]); ret = CE_Failure; break; } m_http_zeroblock_codes.push_back(code); } CSLDestroy(kv); } } if (ret == CE_None) { const char *pszZeroExceptions = CPLGetXMLValue(config, "ZeroBlockOnServerException", ""); if(pszZeroExceptions[0] != '\0') { m_zeroblock_on_serverexceptions = StrToBool(pszZeroExceptions); if (m_zeroblock_on_serverexceptions == -1) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of ZeroBlockOnServerException \"%s\", true/false expected.", pszZeroExceptions); ret = CE_Failure; } } } if (ret == CE_None) { const char *max_conn = CPLGetXMLValue(config, "MaxConnections", ""); if (max_conn[0] != '\0') { m_http_max_conn = atoi(max_conn); } else { m_http_max_conn = 2; } } if (ret == CE_None) { const char *timeout = CPLGetXMLValue(config, "Timeout", ""); if (timeout[0] != '\0') { m_http_timeout = atoi(timeout); } else { m_http_timeout = 300; } } if (ret == CE_None) { const char *offline_mode = CPLGetXMLValue(config, "OfflineMode", ""); if (offline_mode[0] != '\0') { const int offline_mode_bool = StrToBool(offline_mode); if (offline_mode_bool == -1) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of OfflineMode, true / false expected."); ret = CE_Failure; } else { m_offline_mode = offline_mode_bool; } } else { m_offline_mode = 0; } } if (ret == CE_None) { const char *advise_read = CPLGetXMLValue(config, "AdviseRead", ""); if (advise_read[0] != '\0') { const int advise_read_bool = StrToBool(advise_read); if (advise_read_bool == -1) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of AdviseRead, true / false expected."); ret = CE_Failure; } else { m_use_advise_read = advise_read_bool; } } else { m_use_advise_read = 0; } } if (ret == CE_None) { const char *verify_advise_read = CPLGetXMLValue(config, "VerifyAdviseRead", ""); if (m_use_advise_read) { if (verify_advise_read[0] != '\0') { const int verify_advise_read_bool = StrToBool(verify_advise_read); if (verify_advise_read_bool == -1) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of VerifyAdviseRead, true / false expected."); ret = CE_Failure; } else { m_verify_advise_read = verify_advise_read_bool; } } else { m_verify_advise_read = 1; } } } // Let the local configuration override the minidriver supplied projection if (ret == CE_None) { const char *proj = CPLGetXMLValue(config, "Projection", ""); if (proj[0] != '\0') { m_projection = ProjToWKT(proj); if (m_projection.size() == 0) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Bad projection specified."); ret = CE_Failure; } } } // Same for Min, Max and NoData, defined per band or per dataset // If they are set as null strings, they clear the server declared values if (ret == CE_None) { // Data values are attributes, they include NoData Min and Max // TODO: document those options if (0!=CPLGetXMLNode(config,"DataValues")) { const char *nodata=CPLGetXMLValue(config,"DataValues.NoData",NULL); if (nodata!=NULL) WMSSetNoDataValue(nodata); const char *min=CPLGetXMLValue(config,"DataValues.min",NULL); if (min!=NULL) WMSSetMinValue(min); const char *max=CPLGetXMLValue(config,"DataValues.max",NULL); if (max!=NULL) WMSSetMaxValue(max); } } if (ret == CE_None) { CPLXMLNode *cache_node = CPLGetXMLNode(config, "Cache"); if (cache_node != NULL) { m_cache = new GDALWMSCache(); if (m_cache->Initialize(cache_node) != CE_None) { delete m_cache; m_cache = NULL; CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Failed to initialize cache."); ret = CE_Failure; } } } if (ret == CE_None) { const int v = StrToBool(CPLGetXMLValue(config, "UnsafeSSL", "false")); if (v == -1) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Invalid value of UnsafeSSL: true or false expected."); ret = CE_Failure; } else { m_unsafeSsl = v; } } if (ret == CE_None) { /* If we dont have projection already set ask mini-driver. */ if (!m_projection.size()) { const char *proj = m_mini_driver->GetProjectionInWKT(); if (proj != NULL) { m_projection = proj; } } } return ret; }
int main(int argc, char* argv[]) { const char *pszFormat = "ESRI Shapefile"; char *pszLayerName = NULL; const char *pszSrcFilename = NULL, *pszDstFilename = NULL; int iBand = 1; GDALDatasetH hDS; GDALRasterBandH hBand; int nXSize, nYSize; int i, j; FILE *fOut = NULL; double *padfBuffer; double adfGeotransform[6]; OGRSFDriverH hOGRDriver; OGRDataSourceH hOGRDS; OGRLayerH hOGRLayer; OGRwkbGeometryType eType = wkbPoint25D; int xStep = 1, yStep = 1; OGRRegisterAll(); GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ for( i = 1; i < argc; i++ ) { if ( EQUAL(argv[i], "-b") && i < argc - 1) iBand = atoi(argv[++i]); else if ( EQUAL(argv[i], "-f") && i < argc - 1) pszFormat = argv[++i]; else if ( EQUAL(argv[i], "-l") && i < argc - 1) pszLayerName = CPLStrdup(argv[++i]); else if ( EQUAL(argv[i], "-t") && i < argc - 1) { i++; if (EQUAL(argv[i], "POLYGON")) eType = wkbPolygon; else if (EQUAL(argv[i], "POINT")) eType = wkbPoint; else if (EQUAL(argv[i], "POINT25D")) eType = wkbPoint25D; else { fprintf(stderr, "unhandled geometry type : %s\n", argv[i]); } } else if ( EQUAL(argv[i], "-step") && i < argc - 1) xStep = yStep = atoi(argv[++i]); else if ( argv[i][0] == '-') Usage(); else if( pszSrcFilename == NULL ) pszSrcFilename = argv[i]; else if( pszDstFilename == NULL ) pszDstFilename = argv[i]; else Usage(); } if( pszSrcFilename == NULL || pszDstFilename == NULL) Usage(); /* -------------------------------------------------------------------- */ /* Open GDAL source dataset */ /* -------------------------------------------------------------------- */ hDS = GDALOpen(pszSrcFilename, GA_ReadOnly); if (hDS == NULL) { fprintf(stderr, "Can't open %s\n", pszSrcFilename); exit(1); } hBand = GDALGetRasterBand(hDS, iBand); if (hBand == NULL) { fprintf(stderr, "Can't get band %d\n", iBand); exit(1); } if (GDALGetGeoTransform(hDS, adfGeotransform) != CE_None) { fprintf(stderr, "Can't get geotransform\n"); exit(1); } nXSize = GDALGetRasterXSize(hDS); nYSize = GDALGetRasterYSize(hDS); /* -------------------------------------------------------------------- */ /* Create OGR destination dataset */ /* -------------------------------------------------------------------- */ /* Special case for CSV : we generate the appropriate VRT file in the same time */ if (EQUAL(pszFormat, "CSV") && EQUAL(CPLGetExtension(pszDstFilename), "CSV")) { FILE* fOutCSVT; FILE* fOutVRT; char* pszDstFilenameCSVT; char* pszDstFilenameVRT; fOut = fopen(pszDstFilename, "wt"); if (fOut == NULL) { fprintf(stderr, "Can't open %s for writing\n", pszDstFilename); exit(1); } fprintf(fOut, "x,y,z\n"); pszDstFilenameCSVT = CPLMalloc(strlen(pszDstFilename) + 2); strcpy(pszDstFilenameCSVT, pszDstFilename); strcat(pszDstFilenameCSVT, "t"); fOutCSVT = fopen(pszDstFilenameCSVT, "wt"); if (fOutCSVT == NULL) { fprintf(stderr, "Can't open %s for writing\n", pszDstFilenameCSVT); exit(1); } CPLFree(pszDstFilenameCSVT); fprintf(fOutCSVT, "Real,Real,Real\n"); fclose(fOutCSVT); fOutCSVT = NULL; pszDstFilenameVRT = CPLStrdup(pszDstFilename); strcpy(pszDstFilenameVRT + strlen(pszDstFilename) - 3, "vrt"); fOutVRT = fopen(pszDstFilenameVRT, "wt"); if (fOutVRT == NULL) { fprintf(stderr, "Can't open %s for writing\n", pszDstFilenameVRT); exit(1); } CPLFree(pszDstFilenameVRT); fprintf(fOutVRT, "<OGRVRTDataSource>\n"); fprintf(fOutVRT, " <OGRVRTLayer name=\"%s\">\n", CPLGetBasename(pszDstFilename)); fprintf(fOutVRT, " <SrcDataSource>%s</SrcDataSource> \n", pszDstFilename); fprintf(fOutVRT, " <GeometryType>wkbPoint</GeometryType>\n"); fprintf(fOutVRT, " <GeometryField encoding=\"PointFromColumns\" x=\"x\" y=\"y\" z=\"z\"/>\n"); fprintf(fOutVRT, " </OGRVRTLayer>\n"); fprintf(fOutVRT, "</OGRVRTDataSource>\n"); fclose(fOutVRT); fOutVRT = NULL; } else { OGRSpatialReferenceH hSRS = NULL; const char* pszWkt; hOGRDriver = OGRGetDriverByName(pszFormat); if (hOGRDriver == NULL) { fprintf(stderr, "Can't find OGR driver %s\n", pszFormat); exit(1); } hOGRDS = OGR_Dr_CreateDataSource(hOGRDriver, pszDstFilename, NULL); if (hOGRDS == NULL) { fprintf(stderr, "Can't create OGR datasource %s\n", pszDstFilename); exit(1); } pszWkt = GDALGetProjectionRef(hDS); if (pszWkt && pszWkt[0]) { hSRS = OSRNewSpatialReference(pszWkt); } if (pszLayerName == NULL) pszLayerName = CPLStrdup(CPLGetBasename(pszDstFilename)); hOGRLayer = OGR_DS_CreateLayer( hOGRDS, pszLayerName, hSRS, eType, NULL); if (hSRS) OSRDestroySpatialReference(hSRS); if (hOGRLayer == NULL) { fprintf(stderr, "Can't create layer %s\n", pszLayerName); exit(1); } if (eType != wkbPoint25D) { OGRFieldDefnH hFieldDefn = OGR_Fld_Create( "z", OFTReal ); OGR_L_CreateField(hOGRLayer, hFieldDefn, 0); OGR_Fld_Destroy( hFieldDefn ); } } padfBuffer = (double*)CPLMalloc(nXSize * sizeof(double)); #define GET_X(j, i) adfGeotransform[0] + (j) * adfGeotransform[1] + (i) * adfGeotransform[2] #define GET_Y(j, i) adfGeotransform[3] + (j) * adfGeotransform[4] + (i) * adfGeotransform[5] #define GET_XY(j, i) GET_X(j, i), GET_Y(j, i) /* -------------------------------------------------------------------- */ /* "Translate" the source dataset */ /* -------------------------------------------------------------------- */ for(i=0;i<nYSize;i+=yStep) { GDALRasterIO( hBand, GF_Read, 0, i, nXSize, 1, padfBuffer, nXSize, 1, GDT_Float64, 0, 0); for(j=0;j<nXSize;j+=xStep) { if (fOut) { fprintf(fOut, "%f,%f,%f\n", GET_XY(j + .5, i + .5), padfBuffer[j]); } else { OGRFeatureH hFeature = OGR_F_Create(OGR_L_GetLayerDefn(hOGRLayer)); OGRGeometryH hGeometry = OGR_G_CreateGeometry(eType); if (eType == wkbPoint25D) { OGR_G_SetPoint(hGeometry, 0, GET_XY(j + .5, i + .5), padfBuffer[j]); } else if (eType == wkbPoint) { OGR_G_SetPoint_2D(hGeometry, 0, GET_XY(j + .5, i + .5)); OGR_F_SetFieldDouble(hFeature, 0, padfBuffer[j]); } else { OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing); OGR_G_SetPoint_2D(hLinearRing, 0, GET_XY(j + 0, i + 0)); OGR_G_SetPoint_2D(hLinearRing, 1, GET_XY(j + 1, i + 0)); OGR_G_SetPoint_2D(hLinearRing, 2, GET_XY(j + 1, i + 1)); OGR_G_SetPoint_2D(hLinearRing, 3, GET_XY(j + 0, i + 1)); OGR_G_SetPoint_2D(hLinearRing, 4, GET_XY(j + 0, i + 0)); OGR_G_AddGeometryDirectly(hGeometry, hLinearRing); OGR_F_SetFieldDouble(hFeature, 0, padfBuffer[j]); } OGR_F_SetGeometryDirectly(hFeature, hGeometry); OGR_L_CreateFeature(hOGRLayer, hFeature); OGR_F_Destroy(hFeature); } } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ if (fOut) fclose(fOut); else OGR_DS_Destroy(hOGRDS); GDALClose(hDS); CPLFree(padfBuffer); CPLFree(pszLayerName); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); OGRCleanupAll(); CSLDestroy( argv ); return 0; }
MAIN_START(argc, argv) { /* Check strict compilation and runtime library version as we use C++ API */ if (! GDAL_CHECK_VERSION(argv[0])) exit(1); EarlySetConfigOptions(argc, argv); /* -------------------------------------------------------------------- */ /* Register standard GDAL drivers, and process generic GDAL */ /* command options. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); for( int i = 0; argv != nullptr && argv[i] != nullptr; i++ ) { if( EQUAL(argv[i], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); CSLDestroy( argv ); return 0; } else if( EQUAL(argv[i],"--help") ) { Usage(nullptr); } else if ( EQUAL(argv[i], "--long-usage") ) { Usage(nullptr, FALSE); } } /* -------------------------------------------------------------------- */ /* Set optimal setting for best performance with huge input VRT. */ /* The rationale for 450 is that typical Linux process allow */ /* only 1024 file descriptors per process and we need to keep some */ /* spare for shared libraries, etc. so let's go down to 900. */ /* And some datasets may need 2 file descriptors, so divide by 2 */ /* for security. */ /* -------------------------------------------------------------------- */ if( CPLGetConfigOption("GDAL_MAX_DATASET_POOL_SIZE", nullptr) == nullptr ) { #if defined(__MACH__) && defined(__APPLE__) // On Mach, the default limit is 256 files per process // TODO We should eventually dynamically query the limit for all OS CPLSetConfigOption("GDAL_MAX_DATASET_POOL_SIZE", "100"); #else CPLSetConfigOption("GDAL_MAX_DATASET_POOL_SIZE", "450"); #endif } GDALTranslateOptionsForBinary* psOptionsForBinary = GDALTranslateOptionsForBinaryNew(); GDALTranslateOptions *psOptions = GDALTranslateOptionsNew(argv + 1, psOptionsForBinary); CSLDestroy( argv ); if( psOptions == nullptr ) { Usage(nullptr); } if( psOptionsForBinary->pszSource == nullptr ) { Usage("No source dataset specified."); } if( psOptionsForBinary->pszDest == nullptr ) { Usage("No target dataset specified."); } if( strcmp(psOptionsForBinary->pszDest, "/vsistdout/") == 0 ) { psOptionsForBinary->bQuiet = TRUE; } if( !(psOptionsForBinary->bQuiet) ) { GDALTranslateOptionsSetProgress(psOptions, GDALTermProgress, nullptr); } if( psOptionsForBinary->pszFormat ) { GDALDriverH hDriver = GDALGetDriverByName( psOptionsForBinary->pszFormat ); if( hDriver == nullptr ) { fprintf(stderr, "Output driver `%s' not recognised.\n", psOptionsForBinary->pszFormat); fprintf(stderr, "The following format drivers are configured and support output:\n" ); for( int iDr = 0; iDr < GDALGetDriverCount(); iDr++ ) { hDriver = GDALGetDriver(iDr); if( GDALGetMetadataItem( hDriver, GDAL_DCAP_RASTER, nullptr) != nullptr && (GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, nullptr ) != nullptr || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY, nullptr ) != nullptr) ) { fprintf(stderr, " %s: %s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); } } GDALTranslateOptionsFree(psOptions); GDALTranslateOptionsForBinaryFree(psOptionsForBinary); GDALDestroyDriverManager(); exit(1); } } /* -------------------------------------------------------------------- */ /* Attempt to open source file. */ /* -------------------------------------------------------------------- */ GDALDatasetH hDataset = GDALOpenEx(psOptionsForBinary->pszSource, GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR, nullptr, psOptionsForBinary->papszOpenOptions, nullptr); if( hDataset == nullptr ) { GDALDestroyDriverManager(); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Handle subdatasets. */ /* -------------------------------------------------------------------- */ if( !psOptionsForBinary->bCopySubDatasets && GDALGetRasterCount(hDataset) == 0 && CSLCount(GDALGetMetadata( hDataset, "SUBDATASETS" )) > 0 ) { fprintf( stderr, "Input file contains subdatasets. Please, select one of them for reading.\n" ); GDALClose( hDataset ); GDALDestroyDriverManager(); exit( 1 ); } int bUsageError = FALSE; GDALDatasetH hOutDS = nullptr; if( psOptionsForBinary->bCopySubDatasets && CSLCount(GDALGetMetadata( hDataset, "SUBDATASETS" )) > 0 ) { char **papszSubdatasets = GDALGetMetadata(hDataset,"SUBDATASETS"); char *pszSubDest = static_cast<char *>( CPLMalloc(strlen(psOptionsForBinary->pszDest) + 32)); CPLString osPath = CPLGetPath(psOptionsForBinary->pszDest); CPLString osBasename = CPLGetBasename(psOptionsForBinary->pszDest); CPLString osExtension = CPLGetExtension(psOptionsForBinary->pszDest); CPLString osTemp; const char* pszFormat = nullptr; if ( CSLCount(papszSubdatasets)/2 < 10 ) { pszFormat = "%s_%d"; } else if ( CSLCount(papszSubdatasets)/2 < 100 ) { pszFormat = "%s_%002d"; } else { pszFormat = "%s_%003d"; } const char* pszDest = pszSubDest; for( int i = 0; papszSubdatasets[i] != nullptr; i += 2 ) { char* pszSource = CPLStrdup(strstr(papszSubdatasets[i],"=")+1); osTemp = CPLSPrintf( pszFormat, osBasename.c_str(), i/2 + 1 ); osTemp = CPLFormFilename( osPath, osTemp, osExtension ); strcpy( pszSubDest, osTemp.c_str() ); hDataset = GDALOpenEx( pszSource, GDAL_OF_RASTER, nullptr, psOptionsForBinary->papszOpenOptions, nullptr ); CPLFree(pszSource); if( !psOptionsForBinary->bQuiet ) printf("Input file size is %d, %d\n", GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset)); hOutDS = GDALTranslate(pszDest, hDataset, psOptions, &bUsageError); if(bUsageError == TRUE) Usage(); if (hOutDS == nullptr) break; GDALClose(hOutDS); } GDALClose(hDataset); GDALTranslateOptionsFree(psOptions); GDALTranslateOptionsForBinaryFree(psOptionsForBinary); CPLFree(pszSubDest); GDALDestroyDriverManager(); return 0; } if( !psOptionsForBinary->bQuiet ) printf("Input file size is %d, %d\n", GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset)); hOutDS = GDALTranslate(psOptionsForBinary->pszDest, hDataset, psOptions, &bUsageError); if(bUsageError == TRUE) Usage(); int nRetCode = hOutDS ? 0 : 1; /* Close hOutDS before hDataset for the -f VRT case */ GDALClose(hOutDS); GDALClose(hDataset); GDALTranslateOptionsFree(psOptions); GDALTranslateOptionsForBinaryFree(psOptionsForBinary); GDALDestroyDriverManager(); return nRetCode; }
void IDADataset::ReadColorTable() { /* -------------------------------------------------------------------- */ /* Decide what .clr file to look for and try to open. */ /* -------------------------------------------------------------------- */ CPLString osCLRFilename; osCLRFilename = CPLGetConfigOption( "IDA_COLOR_FILE", "" ); if( strlen(osCLRFilename) == 0 ) osCLRFilename = CPLResetExtension(GetDescription(), "clr" ); FILE *fp = VSIFOpen( osCLRFilename, "r" ); if( fp == NULL ) { osCLRFilename = CPLResetExtension(osCLRFilename, "CLR" ); fp = VSIFOpen( osCLRFilename, "r" ); } if( fp == NULL ) return; /* -------------------------------------------------------------------- */ /* Skip first line, with the column titles. */ /* -------------------------------------------------------------------- */ CPLReadLine( fp ); /* -------------------------------------------------------------------- */ /* Create a RAT to populate. */ /* -------------------------------------------------------------------- */ GDALRasterAttributeTable *poRAT = new GDALDefaultRasterAttributeTable(); poRAT->CreateColumn( "FROM", GFT_Integer, GFU_Min ); poRAT->CreateColumn( "TO", GFT_Integer, GFU_Max ); poRAT->CreateColumn( "RED", GFT_Integer, GFU_Red ); poRAT->CreateColumn( "GREEN", GFT_Integer, GFU_Green ); poRAT->CreateColumn( "BLUE", GFT_Integer, GFU_Blue ); poRAT->CreateColumn( "LEGEND", GFT_String, GFU_Name ); /* -------------------------------------------------------------------- */ /* Apply lines. */ /* -------------------------------------------------------------------- */ const char *pszLine = CPLReadLine( fp ); int iRow = 0; while( pszLine != NULL ) { char **papszTokens = CSLTokenizeStringComplex( pszLine, " \t", FALSE, FALSE ); if( CSLCount( papszTokens ) >= 5 ) { poRAT->SetValue( iRow, 0, atoi(papszTokens[0]) ); poRAT->SetValue( iRow, 1, atoi(papszTokens[1]) ); poRAT->SetValue( iRow, 2, atoi(papszTokens[2]) ); poRAT->SetValue( iRow, 3, atoi(papszTokens[3]) ); poRAT->SetValue( iRow, 4, atoi(papszTokens[4]) ); // find name, first nonspace after 5th token. const char *pszName = pszLine; // skip from while( *pszName == ' ' || *pszName == '\t' ) pszName++; while( *pszName != ' ' && *pszName != '\t' && *pszName != '\0' ) pszName++; // skip to while( *pszName == ' ' || *pszName == '\t' ) pszName++; while( *pszName != ' ' && *pszName != '\t' && *pszName != '\0' ) pszName++; // skip red while( *pszName == ' ' || *pszName == '\t' ) pszName++; while( *pszName != ' ' && *pszName != '\t' && *pszName != '\0' ) pszName++; // skip green while( *pszName == ' ' || *pszName == '\t' ) pszName++; while( *pszName != ' ' && *pszName != '\t' && *pszName != '\0' ) pszName++; // skip blue while( *pszName == ' ' || *pszName == '\t' ) pszName++; while( *pszName != ' ' && *pszName != '\t' && *pszName != '\0' ) pszName++; // skip pre-name white space while( *pszName == ' ' || *pszName == '\t' ) pszName++; poRAT->SetValue( iRow, 5, pszName ); iRow++; } CSLDestroy( papszTokens ); pszLine = CPLReadLine( fp ); } VSIFClose( fp ); /* -------------------------------------------------------------------- */ /* Attach RAT to band. */ /* -------------------------------------------------------------------- */ ((IDARasterBand *) GetRasterBand( 1 ))->poRAT = poRAT; /* -------------------------------------------------------------------- */ /* Build a conventional color table from this. */ /* -------------------------------------------------------------------- */ ((IDARasterBand *) GetRasterBand( 1 ))->poColorTable = poRAT->TranslateToColorTable(); }
// Unix case. static bool TABAdjustCaseSensitiveFilename(char *pszFname) { VSIStatBufL sStatBuf; // First check if the filename is OK as is. if (VSIStatL(pszFname, &sStatBuf) == 0) { return true; } // File either does not exist or has the wrong cases. // Go backwards until we find a portion of the path that is valid. char *pszTmpPath = CPLStrdup(pszFname); const int nTotalLen = static_cast<int>(strlen(pszTmpPath)); int iTmpPtr = nTotalLen; GBool bValidPath = false; while(iTmpPtr > 0 && !bValidPath) { // Move back to the previous '/' separator. pszTmpPath[--iTmpPtr] = '\0'; while( iTmpPtr > 0 && pszTmpPath[iTmpPtr-1] != '/' ) { pszTmpPath[--iTmpPtr] = '\0'; } if (iTmpPtr > 0 && VSIStatL(pszTmpPath, &sStatBuf) == 0) bValidPath = true; } CPLAssert(iTmpPtr >= 0); // Assume that CWD is valid. Therefor an empty path is a valid. if (iTmpPtr == 0) bValidPath = true; // Now that we have a valid base, reconstruct the whole path // by scanning all the sub-directories. // If we get to a point where a path component does not exist then // we simply return the rest of the path as is. while(bValidPath && (int)strlen(pszTmpPath) < nTotalLen) { int iLastPartStart = iTmpPtr; char **papszDir = VSIReadDir(pszTmpPath); // Add one component to the current path. pszTmpPath[iTmpPtr] = pszFname[iTmpPtr]; iTmpPtr++; for( ; pszFname[iTmpPtr] != '\0' && pszFname[iTmpPtr]!='/'; iTmpPtr++) { pszTmpPath[iTmpPtr] = pszFname[iTmpPtr]; } while(iLastPartStart < iTmpPtr && pszTmpPath[iLastPartStart] == '/') iLastPartStart++; // And do a case insensitive search in the current dir. for(int iEntry = 0; papszDir && papszDir[iEntry]; iEntry++) { if (EQUAL(pszTmpPath + iLastPartStart, papszDir[iEntry])) { // Fount it. strcpy(pszTmpPath+iLastPartStart, papszDir[iEntry]); break; } } if (iTmpPtr > 0 && VSIStatL(pszTmpPath, &sStatBuf) != 0) bValidPath = false; CSLDestroy(papszDir); } // We reached the last valid path component... just copy the rest // of the path as is. if (iTmpPtr < nTotalLen-1) { strncpy(pszTmpPath+iTmpPtr, pszFname+iTmpPtr, nTotalLen-iTmpPtr); } // Update the source buffer and return. strcpy(pszFname, pszTmpPath); CPLFree(pszTmpPath); return bValidPath; }
int VSICurlStreamingHandle::Exists() { if (eExists == EXIST_UNKNOWN) { /* Consider that only the files whose extension ends up with one that is */ /* listed in CPL_VSIL_CURL_ALLOWED_EXTENSIONS exist on the server */ /* This can speeds up dramatically open experience, in case the server */ /* cannot return a file list */ /* For example : */ /* gdalinfo --config CPL_VSIL_CURL_ALLOWED_EXTENSIONS ".tif" /vsicurl_streaming/http://igskmncngs506.cr.usgs.gov/gmted/Global_tiles_GMTED/075darcsec/bln/W030/30N030W_20101117_gmted_bln075.tif */ const char* pszAllowedExtensions = CPLGetConfigOption("CPL_VSIL_CURL_ALLOWED_EXTENSIONS", NULL); if (pszAllowedExtensions) { char** papszExtensions = CSLTokenizeString2( pszAllowedExtensions, ", ", 0 ); int nURLLen = strlen(pszURL); int bFound = FALSE; for(int i=0;papszExtensions[i] != NULL;i++) { int nExtensionLen = strlen(papszExtensions[i]); if (nURLLen > nExtensionLen && EQUAL(pszURL + nURLLen - nExtensionLen, papszExtensions[i])) { bFound = TRUE; break; } } if (!bFound) { eExists = EXIST_NO; fileSize = 0; poFS->AcquireMutex(); CachedFileProp* cachedFileProp = poFS->GetCachedFileProp(pszURL); cachedFileProp->bHastComputedFileSize = TRUE; cachedFileProp->fileSize = fileSize; cachedFileProp->eExists = eExists; poFS->ReleaseMutex(); CSLDestroy(papszExtensions); return 0; } CSLDestroy(papszExtensions); } char chFirstByte; int bExists = (Read(&chFirstByte, 1, 1) == 1); AcquireMutex(); poFS->AcquireMutex(); CachedFileProp* cachedFileProp = poFS->GetCachedFileProp(pszURL); cachedFileProp->eExists = eExists = bExists ? EXIST_YES : EXIST_NO; poFS->ReleaseMutex(); ReleaseMutex(); Seek(0, SEEK_SET); } return eExists == EXIST_YES; }
CPLKeywordParser::~CPLKeywordParser() { CSLDestroy( papszKeywordList ); papszKeywordList = NULL; }
int OGRGFTDataSource::Open( const char * pszFilename, int bUpdateIn) { bReadWrite = bUpdateIn; pszName = CPLStrdup( pszFilename ); osAuth = OGRGFTGetOptionValue(pszFilename, "auth"); if (osAuth.empty()) osAuth = CPLGetConfigOption("GFT_AUTH", ""); osRefreshToken = OGRGFTGetOptionValue(pszFilename, "refresh"); if (osRefreshToken.empty()) osRefreshToken = CPLGetConfigOption("GFT_REFRESH_TOKEN", ""); osAPIKey = CPLGetConfigOption("GFT_APIKEY", GDAL_API_KEY); CPLString osTables = OGRGFTGetOptionValue(pszFilename, "tables"); bUseHTTPS = TRUE; osAccessToken = OGRGFTGetOptionValue(pszFilename, "access"); if (osAccessToken.empty()) osAccessToken = CPLGetConfigOption("GFT_ACCESS_TOKEN",""); if (osAccessToken.empty() && !osRefreshToken.empty()) { osAccessToken.Seize(GOA2GetAccessToken(osRefreshToken, FUSION_TABLE_SCOPE)); if (osAccessToken.empty()) return FALSE; } /* coverity[copy_paste_error] */ if (osAccessToken.empty() && !osAuth.empty()) { osRefreshToken.Seize(GOA2GetRefreshToken(osAuth, FUSION_TABLE_SCOPE)); if (osRefreshToken.empty()) return FALSE; } if (osAccessToken.empty()) { if (osTables.empty()) { CPLError(CE_Failure, CPLE_AppDefined, "Unauthenticated access requires explicit tables= parameter"); return FALSE; } } if (!osTables.empty()) { char** papszTables = CSLTokenizeString2(osTables, ",", 0); for(int i=0;papszTables && papszTables[i];i++) { papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*)); papoLayers[nLayers ++] = new OGRGFTTableLayer(this, papszTables[i], papszTables[i]); } CSLDestroy(papszTables); return TRUE; } /* Get list of tables */ CPLHTTPResult * psResult = RunSQL("SHOW TABLES"); if (psResult == nullptr) return FALSE; char* pszLine = (char*) psResult->pabyData; if (pszLine == nullptr || psResult->pszErrBuf != nullptr || !STARTS_WITH(pszLine, "table id,name")) { CPLHTTPDestroyResult(psResult); return FALSE; } pszLine = OGRGFTGotoNextLine(pszLine); while(pszLine != nullptr && *pszLine != 0) { char* pszNextLine = OGRGFTGotoNextLine(pszLine); if (pszNextLine) pszNextLine[-1] = 0; char** papszTokens = CSLTokenizeString2(pszLine, ",", 0); if (CSLCount(papszTokens) == 2) { CPLString osTableId(papszTokens[0]); CPLString osLayerName(papszTokens[1]); for(int i=0;i<nLayers;i++) { if (strcmp(papoLayers[i]->GetName(), osLayerName) == 0) { osLayerName += " ("; osLayerName += osTableId; osLayerName += ")"; break; } } papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*)); papoLayers[nLayers ++] = new OGRGFTTableLayer(this, osLayerName, osTableId); } CSLDestroy(papszTokens); pszLine = pszNextLine; } CPLHTTPDestroyResult(psResult); return TRUE; }
GDALDataset *HDF5ImageDataset::Open( GDALOpenInfo * poOpenInfo ) { int i; HDF5ImageDataset *poDS; char szFilename[2048]; if(!EQUALN( poOpenInfo->pszFilename, "HDF5:", 5 ) || strlen(poOpenInfo->pszFilename) > sizeof(szFilename) - 3 ) return NULL; /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The HDF5ImageDataset driver does not support update access to existing" " datasets.\n" ); return NULL; } poDS = new HDF5ImageDataset(); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ /* printf("poOpenInfo->pszFilename %s\n",poOpenInfo->pszFilename); */ char **papszName = CSLTokenizeString2( poOpenInfo->pszFilename, ":", CSLT_HONOURSTRINGS|CSLT_PRESERVEESCAPES ); if( !((CSLCount(papszName) == 3) || (CSLCount(papszName) == 4)) ) { CSLDestroy(papszName); delete poDS; return NULL; } poDS->SetDescription( poOpenInfo->pszFilename ); /* -------------------------------------------------------------------- */ /* Check for drive name in windows HDF5:"D:\... */ /* -------------------------------------------------------------------- */ strcpy(szFilename, papszName[1]); if( strlen(papszName[1]) == 1 && papszName[3] != NULL ) { strcat(szFilename, ":"); strcat(szFilename, papszName[2]); poDS->SetSubdatasetName( papszName[3] ); } else poDS->SetSubdatasetName( papszName[2] ); CSLDestroy(papszName); papszName = NULL; if( !H5Fis_hdf5(szFilename) ) { delete poDS; return NULL; } poDS->SetPhysicalFilename( szFilename ); /* -------------------------------------------------------------------- */ /* Try opening the dataset. */ /* -------------------------------------------------------------------- */ poDS->hHDF5 = H5Fopen(szFilename, H5F_ACC_RDONLY, H5P_DEFAULT ); if( poDS->hHDF5 < 0 ) { delete poDS; return NULL; } poDS->hGroupID = H5Gopen( poDS->hHDF5, "/" ); if( poDS->hGroupID < 0 ) { poDS->bIsHDFEOS=false; delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* THIS IS AN HDF5 FILE */ /* -------------------------------------------------------------------- */ poDS->bIsHDFEOS=TRUE; poDS->ReadGlobalAttributes( FALSE ); /* -------------------------------------------------------------------- */ /* Create HDF5 Data Hierarchy in a link list */ /* -------------------------------------------------------------------- */ poDS->poH5Objects = poDS->HDF5FindDatasetObjectsbyPath( poDS->poH5RootGroup, (char *)poDS->GetSubdatasetName() ); if( poDS->poH5Objects == NULL ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Retrieve HDF5 data information */ /* -------------------------------------------------------------------- */ poDS->dataset_id = H5Dopen( poDS->hHDF5,poDS->poH5Objects->pszPath ); poDS->dataspace_id = H5Dget_space( poDS->dataset_id ); poDS->ndims = H5Sget_simple_extent_ndims( poDS->dataspace_id ); poDS->dims = (hsize_t*)CPLCalloc( poDS->ndims, sizeof(hsize_t) ); poDS->maxdims = (hsize_t*)CPLCalloc( poDS->ndims, sizeof(hsize_t) ); poDS->dimensions = H5Sget_simple_extent_dims( poDS->dataspace_id, poDS->dims, poDS->maxdims ); poDS->datatype = H5Dget_type( poDS->dataset_id ); poDS->clas = H5Tget_class( poDS->datatype ); poDS->size = H5Tget_size( poDS->datatype ); poDS->address = H5Dget_offset( poDS->dataset_id ); poDS->native = H5Tget_native_type( poDS->datatype, H5T_DIR_ASCEND ); poDS->nRasterYSize=(int)poDS->dims[poDS->ndims-2]; // Y poDS->nRasterXSize=(int)poDS->dims[poDS->ndims-1]; // X alway last poDS->nBands=1; if( poDS->ndims == 3 ) poDS->nBands=(int) poDS->dims[0]; for( i = 1; i <= poDS->nBands; i++ ) { HDF5ImageRasterBand *poBand = new HDF5ImageRasterBand( poDS, i, poDS->GetDataType( poDS->native ) ); poDS->SetBand( i, poBand ); if( poBand->bNoDataSet ) poBand->SetNoDataValue( 255 ); } // CSK code in IdentifyProductType() and CreateProjections() // uses dataset metadata. poDS->SetMetadata( poDS->papszMetadata ); // Check if the hdf5 is a well known product type poDS->IdentifyProductType(); poDS->CreateProjections( ); /* -------------------------------------------------------------------- */ /* Setup/check for pam .aux.xml. */ /* -------------------------------------------------------------------- */ poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Setup overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, ":::VIRTUAL:::" ); return( poDS ); }
CPLXMLNode *GDALSerializeRPCTransformer( void *pTransformArg ) { VALIDATE_POINTER1( pTransformArg, "GDALSerializeRPCTransformer", NULL ); CPLXMLNode *psTree; GDALRPCTransformInfo *psInfo = (GDALRPCTransformInfo *)(pTransformArg); psTree = CPLCreateXMLNode( NULL, CXT_Element, "RPCTransformer" ); /* -------------------------------------------------------------------- */ /* Serialize bReversed. */ /* -------------------------------------------------------------------- */ CPLCreateXMLElementAndValue( psTree, "Reversed", CPLString().Printf( "%d", psInfo->bReversed ) ); /* -------------------------------------------------------------------- */ /* Serialize Height Offset. */ /* -------------------------------------------------------------------- */ CPLCreateXMLElementAndValue( psTree, "HeightOffset", CPLString().Printf( "%.15g", psInfo->dfHeightOffset ) ); /* -------------------------------------------------------------------- */ /* Serialize Height Scale. */ /* -------------------------------------------------------------------- */ if (psInfo->dfHeightScale != 1.0) CPLCreateXMLElementAndValue( psTree, "HeightScale", CPLString().Printf( "%.15g", psInfo->dfHeightScale ) ); /* -------------------------------------------------------------------- */ /* Serialize DEM path. */ /* -------------------------------------------------------------------- */ if (psInfo->pszDEMPath != NULL) CPLCreateXMLElementAndValue( psTree, "DEMPath", CPLString().Printf( "%s", psInfo->pszDEMPath ) ); /* -------------------------------------------------------------------- */ /* Serialize DEM interpolation */ /* -------------------------------------------------------------------- */ CPLString soDEMInterpolation; switch(psInfo->eResampleAlg) { case DRA_NearestNeighbour: soDEMInterpolation = "near"; break; case DRA_Cubic: soDEMInterpolation = "cubic"; break; default: case DRA_Bilinear: soDEMInterpolation = "bilinear"; } CPLCreateXMLElementAndValue( psTree, "DEMInterpolation", soDEMInterpolation ); /* -------------------------------------------------------------------- */ /* Serialize pixel error threshold. */ /* -------------------------------------------------------------------- */ CPLCreateXMLElementAndValue( psTree, "PixErrThreshold", CPLString().Printf( "%.15g", psInfo->dfPixErrThreshold ) ); /* -------------------------------------------------------------------- */ /* RPC metadata. */ /* -------------------------------------------------------------------- */ char **papszMD = RPCInfoToMD( &(psInfo->sRPC) ); CPLXMLNode *psMD= CPLCreateXMLNode( psTree, CXT_Element, "Metadata" ); for( int i = 0; papszMD != NULL && papszMD[i] != NULL; i++ ) { const char *pszRawValue; char *pszKey; CPLXMLNode *psMDI; pszRawValue = CPLParseNameValue( papszMD[i], &pszKey ); psMDI = CPLCreateXMLNode( psMD, CXT_Element, "MDI" ); CPLSetXMLValue( psMDI, "#key", pszKey ); CPLCreateXMLNode( psMDI, CXT_Text, pszRawValue ); CPLFree( pszKey ); } CSLDestroy( papszMD ); return psTree; }
CPLErr CPL_STDCALL GDALComputeProximity( GDALRasterBandH hSrcBand, GDALRasterBandH hProximityBand, char **papszOptions, GDALProgressFunc pfnProgress, void * pProgressArg ) { int nXSize, nYSize, i, bFixedBufVal = FALSE; const char *pszOpt; double dfMaxDist; double dfFixedBufVal = 0.0; VALIDATE_POINTER1( hSrcBand, "GDALComputeProximity", CE_Failure ); VALIDATE_POINTER1( hProximityBand, "GDALComputeProximity", CE_Failure ); if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* Are we using pixels or georeferenced coordinates for distances? */ /* -------------------------------------------------------------------- */ double dfDistMult = 1.0; pszOpt = CSLFetchNameValue( papszOptions, "DISTUNITS" ); if( pszOpt ) { if( EQUAL(pszOpt,"GEO") ) { GDALDatasetH hSrcDS = GDALGetBandDataset( hSrcBand ); if( hSrcDS ) { double adfGeoTransform[6]; GDALGetGeoTransform( hSrcDS, adfGeoTransform ); if( ABS(adfGeoTransform[1]) != ABS(adfGeoTransform[5]) ) CPLError( CE_Warning, CPLE_AppDefined, "Pixels not square, distances will be inaccurate." ); dfDistMult = ABS(adfGeoTransform[1]); } } else if( !EQUAL(pszOpt,"PIXEL") ) { CPLError( CE_Failure, CPLE_AppDefined, "Unrecognised DISTUNITS value '%s', should be GEO or PIXEL.", pszOpt ); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* What is our maxdist value? */ /* -------------------------------------------------------------------- */ pszOpt = CSLFetchNameValue( papszOptions, "MAXDIST" ); if( pszOpt ) dfMaxDist = CPLAtof(pszOpt) / dfDistMult; else dfMaxDist = GDALGetRasterBandXSize(hSrcBand) + GDALGetRasterBandYSize(hSrcBand); CPLDebug( "GDAL", "MAXDIST=%g, DISTMULT=%g", dfMaxDist, dfDistMult ); /* -------------------------------------------------------------------- */ /* Verify the source and destination are compatible. */ /* -------------------------------------------------------------------- */ nXSize = GDALGetRasterBandXSize( hSrcBand ); nYSize = GDALGetRasterBandYSize( hSrcBand ); if( nXSize != GDALGetRasterBandXSize( hProximityBand ) || nYSize != GDALGetRasterBandYSize( hProximityBand )) { CPLError( CE_Failure, CPLE_AppDefined, "Source and proximity bands are not the same size." ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Get input NODATA value. */ /* -------------------------------------------------------------------- */ double dfSrcNoDataValue = 0.0; double *pdfSrcNoData = NULL; if( CSLFetchBoolean( papszOptions, "USE_INPUT_NODATA", FALSE ) ) { int bSrcHasNoData = 0; dfSrcNoDataValue = GDALGetRasterNoDataValue( hSrcBand, &bSrcHasNoData ); if( bSrcHasNoData ) pdfSrcNoData = &dfSrcNoDataValue; } /* -------------------------------------------------------------------- */ /* Get output NODATA value. */ /* -------------------------------------------------------------------- */ float fNoDataValue; pszOpt = CSLFetchNameValue( papszOptions, "NODATA" ); if( pszOpt != NULL ) fNoDataValue = (float) CPLAtof(pszOpt); else { int bSuccess; fNoDataValue = (float) GDALGetRasterNoDataValue( hProximityBand, &bSuccess ); if( !bSuccess ) fNoDataValue = 65535.0; } /* -------------------------------------------------------------------- */ /* Is there a fixed value we wish to force the buffer area to? */ /* -------------------------------------------------------------------- */ pszOpt = CSLFetchNameValue( papszOptions, "FIXED_BUF_VAL" ); if( pszOpt ) { dfFixedBufVal = CPLAtof(pszOpt); bFixedBufVal = TRUE; } /* -------------------------------------------------------------------- */ /* Get the target value(s). */ /* -------------------------------------------------------------------- */ int *panTargetValues = NULL; int nTargetValues = 0; pszOpt = CSLFetchNameValue( papszOptions, "VALUES" ); if( pszOpt != NULL ) { char **papszValuesTokens; papszValuesTokens = CSLTokenizeStringComplex( pszOpt, ",", FALSE,FALSE); nTargetValues = CSLCount(papszValuesTokens); panTargetValues = (int *) CPLCalloc(sizeof(int),nTargetValues); for( i = 0; i < nTargetValues; i++ ) panTargetValues[i] = atoi(papszValuesTokens[i]); CSLDestroy( papszValuesTokens ); } /* -------------------------------------------------------------------- */ /* Initialize progress counter. */ /* -------------------------------------------------------------------- */ if( !pfnProgress( 0.0, "", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); CPLFree(panTargetValues); return CE_Failure; } /* -------------------------------------------------------------------- */ /* We need a signed type for the working proximity values kept */ /* on disk. If our proximity band is not signed, then create a */ /* temporary file for this purpose. */ /* -------------------------------------------------------------------- */ GDALRasterBandH hWorkProximityBand = hProximityBand; GDALDatasetH hWorkProximityDS = NULL; GDALDataType eProxType = GDALGetRasterDataType( hProximityBand ); int *panNearX = NULL, *panNearY = NULL; float *pafProximity = NULL; GInt32 *panSrcScanline = NULL; int iLine; CPLErr eErr = CE_None; if( eProxType == GDT_Byte || eProxType == GDT_UInt16 || eProxType == GDT_UInt32 ) { GDALDriverH hDriver = GDALGetDriverByName("GTiff"); if (hDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "GDALComputeProximity needs GTiff driver"); eErr = CE_Failure; goto end; } CPLString osTmpFile = CPLGenerateTempFilename( "proximity" ); hWorkProximityDS = GDALCreate( hDriver, osTmpFile, nXSize, nYSize, 1, GDT_Float32, NULL ); if (hWorkProximityDS == NULL) { eErr = CE_Failure; goto end; } hWorkProximityBand = GDALGetRasterBand( hWorkProximityDS, 1 ); } /* -------------------------------------------------------------------- */ /* Allocate buffer for two scanlines of distances as floats */ /* (the current and last line). */ /* -------------------------------------------------------------------- */ pafProximity = (float *) VSIMalloc2(sizeof(float), nXSize); panNearX = (int *) VSIMalloc2(sizeof(int), nXSize); panNearY = (int *) VSIMalloc2(sizeof(int), nXSize); panSrcScanline = (GInt32 *) VSIMalloc2(sizeof(GInt32), nXSize); if( pafProximity== NULL || panNearX == NULL || panNearY == NULL || panSrcScanline == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory allocating working buffers."); eErr = CE_Failure; goto end; } /* -------------------------------------------------------------------- */ /* Loop from top to bottom of the image. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nXSize; i++ ) panNearX[i] = panNearY[i] = -1; for( iLine = 0; eErr == CE_None && iLine < nYSize; iLine++ ) { // Read for target values. eErr = GDALRasterIO( hSrcBand, GF_Read, 0, iLine, nXSize, 1, panSrcScanline, nXSize, 1, GDT_Int32, 0, 0 ); if( eErr != CE_None ) break; for( i = 0; i < nXSize; i++ ) pafProximity[i] = -1.0; // Left to right ProcessProximityLine( panSrcScanline, panNearX, panNearY, TRUE, iLine, nXSize, dfMaxDist, pafProximity, pdfSrcNoData, nTargetValues, panTargetValues ); // Right to Left ProcessProximityLine( panSrcScanline, panNearX, panNearY, FALSE, iLine, nXSize, dfMaxDist, pafProximity, pdfSrcNoData, nTargetValues, panTargetValues ); // Write out results. eErr = GDALRasterIO( hWorkProximityBand, GF_Write, 0, iLine, nXSize, 1, pafProximity, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; if( !pfnProgress( 0.5 * (iLine+1) / (double) nYSize, "", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Loop from bottom to top of the image. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nXSize; i++ ) panNearX[i] = panNearY[i] = -1; for( iLine = nYSize-1; eErr == CE_None && iLine >= 0; iLine-- ) { // Read first pass proximity eErr = GDALRasterIO( hWorkProximityBand, GF_Read, 0, iLine, nXSize, 1, pafProximity, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; // Read pixel values. eErr = GDALRasterIO( hSrcBand, GF_Read, 0, iLine, nXSize, 1, panSrcScanline, nXSize, 1, GDT_Int32, 0, 0 ); if( eErr != CE_None ) break; // Right to left ProcessProximityLine( panSrcScanline, panNearX, panNearY, FALSE, iLine, nXSize, dfMaxDist, pafProximity, pdfSrcNoData, nTargetValues, panTargetValues ); // Left to right ProcessProximityLine( panSrcScanline, panNearX, panNearY, TRUE, iLine, nXSize, dfMaxDist, pafProximity, pdfSrcNoData, nTargetValues, panTargetValues ); // Final post processing of distances. for( i = 0; i < nXSize; i++ ) { if( pafProximity[i] < 0.0 ) pafProximity[i] = fNoDataValue; else if( pafProximity[i] > 0.0 ) { if( bFixedBufVal ) pafProximity[i] = (float) dfFixedBufVal; else pafProximity[i] = (float)(pafProximity[i] * dfDistMult); } } // Write out results. eErr = GDALRasterIO( hProximityBand, GF_Write, 0, iLine, nXSize, 1, pafProximity, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; if( !pfnProgress( 0.5 + 0.5 * (nYSize-iLine) / (double) nYSize, "", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ end: CPLFree( panNearX ); CPLFree( panNearY ); CPLFree( panSrcScanline ); CPLFree( pafProximity ); CPLFree(panTargetValues); if( hWorkProximityDS != NULL ) { CPLString osProxFile = GDALGetDescription( hWorkProximityDS ); GDALClose( hWorkProximityDS ); GDALDeleteDataset( GDALGetDriverByName( "GTiff" ), osProxFile ); } return eErr; }