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; }
int main( int argc, char ** argv ) { GDALDatasetH hDataset = NULL; GDALRasterBandH hBand = NULL; int i, iBand; double adfGeoTransform[6]; GDALDriverH hDriver; char **papszMetadata; int bComputeMinMax = FALSE, bSample = FALSE; int bShowGCPs = TRUE, bShowMetadata = TRUE, bShowRAT=TRUE; int bStats = FALSE, bApproxStats = TRUE, iMDD; int bShowColorTable = TRUE, bComputeChecksum = FALSE; int bReportHistograms = FALSE; int bReportProj4 = FALSE; int nSubdataset = -1; const char *pszFilename = NULL; char **papszExtraMDDomains = NULL, **papszFileList; const char *pszProjection = NULL; OGRCoordinateTransformationH hTransform = NULL; int bShowFileList = TRUE; /* Check that we are running against at least GDAL 1.5 */ /* Note to developers : if we use newer API, please change the requirement */ if (atoi(GDALVersionInfo("VERSION_NUM")) < 1500) { fprintf(stderr, "At least, GDAL >= 1.5.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } EarlySetConfigOptions(argc, argv); GDALAllRegister(); 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],"--help") ) Usage(NULL); else if( EQUAL(argv[i], "-mm") ) bComputeMinMax = TRUE; else if( EQUAL(argv[i], "-hist") ) bReportHistograms = TRUE; else if( EQUAL(argv[i], "-proj4") ) bReportProj4 = TRUE; else if( EQUAL(argv[i], "-stats") ) { bStats = TRUE; bApproxStats = FALSE; } else if( EQUAL(argv[i], "-approx_stats") ) { bStats = TRUE; bApproxStats = TRUE; } else if( EQUAL(argv[i], "-sample") ) bSample = TRUE; else if( EQUAL(argv[i], "-checksum") ) bComputeChecksum = TRUE; else if( EQUAL(argv[i], "-nogcp") ) bShowGCPs = FALSE; else if( EQUAL(argv[i], "-nomd") ) bShowMetadata = FALSE; else if( EQUAL(argv[i], "-norat") ) bShowRAT = FALSE; else if( EQUAL(argv[i], "-noct") ) bShowColorTable = FALSE; else if( EQUAL(argv[i], "-mdd") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); papszExtraMDDomains = CSLAddString( papszExtraMDDomains, argv[++i] ); } else if( EQUAL(argv[i], "-nofl") ) bShowFileList = FALSE; else if( EQUAL(argv[i], "-sd") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); nSubdataset = atoi(argv[++i]); } else if( argv[i][0] == '-' ) Usage(CPLSPrintf("Unkown option name '%s'", argv[i])); else if( pszFilename == NULL ) pszFilename = argv[i]; else Usage("Too many command options."); } if( pszFilename == NULL ) Usage("No datasource specified."); /* -------------------------------------------------------------------- */ /* Open dataset. */ /* -------------------------------------------------------------------- */ hDataset = GDALOpen( pszFilename, GA_ReadOnly ); if( hDataset == NULL ) { fprintf( stderr, "gdalinfo failed - unable to open '%s'.\n", pszFilename ); /* -------------------------------------------------------------------- */ /* If argument is a VSIFILE, then print its contents */ /* -------------------------------------------------------------------- */ if ( strncmp( pszFilename, "/vsizip/", 8 ) == 0 || strncmp( pszFilename, "/vsitar/", 8 ) == 0 ) { papszFileList = VSIReadDirRecursive( pszFilename ); if ( papszFileList ) { int nCount = CSLCount( papszFileList ); fprintf( stdout, "Unable to open source `%s' directly.\n" "The archive contains %d files:\n", pszFilename, nCount ); for ( i = 0; i < nCount; i++ ) { fprintf( stdout, " %s/%s\n", pszFilename, papszFileList[i] ); } CSLDestroy( papszFileList ); papszFileList = NULL; } } CSLDestroy( argv ); CSLDestroy( papszExtraMDDomains ); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); CPLDumpSharedList( NULL ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Read specified subdataset if requested. */ /* -------------------------------------------------------------------- */ if ( nSubdataset > 0 ) { char **papszSubdatasets = GDALGetMetadata( hDataset, "SUBDATASETS" ); int nSubdatasets = CSLCount( papszSubdatasets ); if ( nSubdatasets > 0 && nSubdataset <= nSubdatasets ) { char szKeyName[1024]; char *pszSubdatasetName; snprintf( szKeyName, sizeof(szKeyName), "SUBDATASET_%d_NAME", nSubdataset ); szKeyName[sizeof(szKeyName) - 1] = '\0'; pszSubdatasetName = CPLStrdup( CSLFetchNameValue( papszSubdatasets, szKeyName ) ); GDALClose( hDataset ); hDataset = GDALOpen( pszSubdatasetName, GA_ReadOnly ); CPLFree( pszSubdatasetName ); } else { fprintf( stderr, "gdalinfo warning: subdataset %d of %d requested. " "Reading the main dataset.\n", nSubdataset, nSubdatasets ); } } /* -------------------------------------------------------------------- */ /* Report general info. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDatasetDriver( hDataset ); printf( "Driver: %s/%s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); papszFileList = GDALGetFileList( hDataset ); if( CSLCount(papszFileList) == 0 ) { printf( "Files: none associated\n" ); } else { printf( "Files: %s\n", papszFileList[0] ); if( bShowFileList ) { for( i = 1; papszFileList[i] != NULL; i++ ) printf( " %s\n", papszFileList[i] ); } } CSLDestroy( papszFileList ); printf( "Size is %d, %d\n", GDALGetRasterXSize( hDataset ), GDALGetRasterYSize( hDataset ) ); /* -------------------------------------------------------------------- */ /* Report projection. */ /* -------------------------------------------------------------------- */ if( GDALGetProjectionRef( hDataset ) != NULL ) { OGRSpatialReferenceH hSRS; char *pszProjection; pszProjection = (char *) GDALGetProjectionRef( hDataset ); hSRS = OSRNewSpatialReference(NULL); if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None ) { char *pszPrettyWkt = NULL; OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE ); printf( "Coordinate System is:\n%s\n", pszPrettyWkt ); CPLFree( pszPrettyWkt ); } else printf( "Coordinate System is `%s'\n", GDALGetProjectionRef( hDataset ) ); if ( bReportProj4 ) { char *pszProj4 = NULL; OSRExportToProj4( hSRS, &pszProj4 ); printf("PROJ.4 string is:\n\'%s\'\n",pszProj4); CPLFree( pszProj4 ); } OSRDestroySpatialReference( hSRS ); } /* -------------------------------------------------------------------- */ /* Report Geotransform. */ /* -------------------------------------------------------------------- */ if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) { if( adfGeoTransform[2] == 0.0 && adfGeoTransform[4] == 0.0 ) { printf( "Origin = (%.15f,%.15f)\n", adfGeoTransform[0], adfGeoTransform[3] ); printf( "Pixel Size = (%.15f,%.15f)\n", adfGeoTransform[1], adfGeoTransform[5] ); } else printf( "GeoTransform =\n" " %.16g, %.16g, %.16g\n" " %.16g, %.16g, %.16g\n", adfGeoTransform[0], adfGeoTransform[1], adfGeoTransform[2], adfGeoTransform[3], adfGeoTransform[4], adfGeoTransform[5] ); } /* -------------------------------------------------------------------- */ /* Report GCPs. */ /* -------------------------------------------------------------------- */ if( bShowGCPs && GDALGetGCPCount( hDataset ) > 0 ) { if (GDALGetGCPProjection(hDataset) != NULL) { OGRSpatialReferenceH hSRS; char *pszProjection; pszProjection = (char *) GDALGetGCPProjection( hDataset ); hSRS = OSRNewSpatialReference(NULL); if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None ) { char *pszPrettyWkt = NULL; OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE ); printf( "GCP Projection = \n%s\n", pszPrettyWkt ); CPLFree( pszPrettyWkt ); } else printf( "GCP Projection = %s\n", GDALGetGCPProjection( hDataset ) ); OSRDestroySpatialReference( hSRS ); } for( i = 0; i < GDALGetGCPCount(hDataset); i++ ) { const GDAL_GCP *psGCP; psGCP = GDALGetGCPs( hDataset ) + i; printf( "GCP[%3d]: Id=%s, Info=%s\n" " (%.15g,%.15g) -> (%.15g,%.15g,%.15g)\n", i, psGCP->pszId, psGCP->pszInfo, psGCP->dfGCPPixel, psGCP->dfGCPLine, psGCP->dfGCPX, psGCP->dfGCPY, psGCP->dfGCPZ ); } } /* -------------------------------------------------------------------- */ /* Report metadata. */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, NULL ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } for( iMDD = 0; bShowMetadata && iMDD < CSLCount(papszExtraMDDomains); iMDD++ ) { papszMetadata = GDALGetMetadata( hDataset, papszExtraMDDomains[iMDD] ); if( CSLCount(papszMetadata) > 0 ) { printf( "Metadata (%s):\n", papszExtraMDDomains[iMDD]); for( i = 0; papszMetadata[i] != NULL; i++ ) { if (EQUALN(papszExtraMDDomains[iMDD], "xml:", 4)) printf( "%s\n", papszMetadata[i] ); else printf( " %s\n", papszMetadata[i] ); } } } /* -------------------------------------------------------------------- */ /* Report "IMAGE_STRUCTURE" metadata. */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, "IMAGE_STRUCTURE" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "Image Structure Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report subdatasets. */ /* -------------------------------------------------------------------- */ papszMetadata = GDALGetMetadata( hDataset, "SUBDATASETS" ); if( CSLCount(papszMetadata) > 0 ) { printf( "Subdatasets:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report geolocation. */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, "GEOLOCATION" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "Geolocation:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Report RPCs */ /* -------------------------------------------------------------------- */ papszMetadata = (bShowMetadata) ? GDALGetMetadata( hDataset, "RPC" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( "RPC Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } /* -------------------------------------------------------------------- */ /* Setup projected to lat/long transform if appropriate. */ /* -------------------------------------------------------------------- */ if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ) pszProjection = GDALGetProjectionRef(hDataset); if( pszProjection != NULL && strlen(pszProjection) > 0 ) { OGRSpatialReferenceH hProj, hLatLong = NULL; hProj = OSRNewSpatialReference( pszProjection ); if( hProj != NULL ) hLatLong = OSRCloneGeogCS( hProj ); if( hLatLong != NULL ) { CPLPushErrorHandler( CPLQuietErrorHandler ); hTransform = OCTNewCoordinateTransformation( hProj, hLatLong ); CPLPopErrorHandler(); OSRDestroySpatialReference( hLatLong ); } if( hProj != NULL ) OSRDestroySpatialReference( hProj ); } /* -------------------------------------------------------------------- */ /* Report corners. */ /* -------------------------------------------------------------------- */ printf( "Corner Coordinates:\n" ); GDALInfoReportCorner( hDataset, hTransform, "Upper Left", 0.0, 0.0 ); GDALInfoReportCorner( hDataset, hTransform, "Lower Left", 0.0, GDALGetRasterYSize(hDataset)); GDALInfoReportCorner( hDataset, hTransform, "Upper Right", GDALGetRasterXSize(hDataset), 0.0 ); GDALInfoReportCorner( hDataset, hTransform, "Lower Right", GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset) ); GDALInfoReportCorner( hDataset, hTransform, "Center", GDALGetRasterXSize(hDataset)/2.0, GDALGetRasterYSize(hDataset)/2.0 ); if( hTransform != NULL ) { OCTDestroyCoordinateTransformation( hTransform ); hTransform = NULL; } /* ==================================================================== */ /* Loop over bands. */ /* ==================================================================== */ for( iBand = 0; iBand < GDALGetRasterCount( hDataset ); iBand++ ) { double dfMin, dfMax, adfCMinMax[2], dfNoData; int bGotMin, bGotMax, bGotNodata, bSuccess; int nBlockXSize, nBlockYSize, nMaskFlags; double dfMean, dfStdDev; GDALColorTableH hTable; CPLErr eErr; hBand = GDALGetRasterBand( hDataset, iBand+1 ); if( bSample ) { float afSample[10000]; int nCount; nCount = GDALGetRandomRasterSample( hBand, 10000, afSample ); printf( "Got %d samples.\n", nCount ); } GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize ); printf( "Band %d Block=%dx%d Type=%s, ColorInterp=%s\n", iBand+1, nBlockXSize, nBlockYSize, GDALGetDataTypeName( GDALGetRasterDataType(hBand)), GDALGetColorInterpretationName( GDALGetRasterColorInterpretation(hBand)) ); if( GDALGetDescription( hBand ) != NULL && strlen(GDALGetDescription( hBand )) > 0 ) printf( " Description = %s\n", GDALGetDescription(hBand) ); dfMin = GDALGetRasterMinimum( hBand, &bGotMin ); dfMax = GDALGetRasterMaximum( hBand, &bGotMax ); if( bGotMin || bGotMax || bComputeMinMax ) { printf( " " ); if( bGotMin ) printf( "Min=%.3f ", dfMin ); if( bGotMax ) printf( "Max=%.3f ", dfMax ); if( bComputeMinMax ) { CPLErrorReset(); GDALComputeRasterMinMax( hBand, FALSE, adfCMinMax ); if (CPLGetLastErrorType() == CE_None) { printf( " Computed Min/Max=%.3f,%.3f", adfCMinMax[0], adfCMinMax[1] ); } } printf( "\n" ); } eErr = GDALGetRasterStatistics( hBand, bApproxStats, bStats, &dfMin, &dfMax, &dfMean, &dfStdDev ); if( eErr == CE_None ) { printf( " Minimum=%.3f, Maximum=%.3f, Mean=%.3f, StdDev=%.3f\n", dfMin, dfMax, dfMean, dfStdDev ); } if( bReportHistograms ) { int nBucketCount, *panHistogram = NULL; eErr = GDALGetDefaultHistogram( hBand, &dfMin, &dfMax, &nBucketCount, &panHistogram, TRUE, GDALTermProgress, NULL ); if( eErr == CE_None ) { int iBucket; printf( " %d buckets from %g to %g:\n ", nBucketCount, dfMin, dfMax ); for( iBucket = 0; iBucket < nBucketCount; iBucket++ ) printf( "%d ", panHistogram[iBucket] ); printf( "\n" ); CPLFree( panHistogram ); } } if ( bComputeChecksum) { printf( " Checksum=%d\n", GDALChecksumImage(hBand, 0, 0, GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset))); } dfNoData = GDALGetRasterNoDataValue( hBand, &bGotNodata ); if( bGotNodata ) { if (CPLIsNan(dfNoData)) printf( " NoData Value=nan\n" ); else printf( " NoData Value=%.18g\n", dfNoData ); } if( GDALGetOverviewCount(hBand) > 0 ) { int iOverview; printf( " Overviews: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hBand); iOverview++ ) { GDALRasterBandH hOverview; const char *pszResampling = NULL; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hBand, iOverview ); if (hOverview != NULL) { printf( "%dx%d", GDALGetRasterBandXSize( hOverview ), GDALGetRasterBandYSize( hOverview ) ); pszResampling = GDALGetMetadataItem( hOverview, "RESAMPLING", "" ); if( pszResampling != NULL && EQUALN(pszResampling,"AVERAGE_BIT2",12) ) printf( "*" ); } else printf( "(null)" ); } printf( "\n" ); if ( bComputeChecksum) { printf( " Overviews checksum: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hBand); iOverview++ ) { GDALRasterBandH hOverview; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hBand, iOverview ); if (hOverview) printf( "%d", GDALChecksumImage(hOverview, 0, 0, GDALGetRasterBandXSize(hOverview), GDALGetRasterBandYSize(hOverview))); else printf( "(null)" ); } printf( "\n" ); } } if( GDALHasArbitraryOverviews( hBand ) ) { printf( " Overviews: arbitrary\n" ); } nMaskFlags = GDALGetMaskFlags( hBand ); if( (nMaskFlags & (GMF_NODATA|GMF_ALL_VALID)) == 0 ) { GDALRasterBandH hMaskBand = GDALGetMaskBand(hBand) ; printf( " Mask Flags: " ); if( nMaskFlags & GMF_PER_DATASET ) printf( "PER_DATASET " ); if( nMaskFlags & GMF_ALPHA ) printf( "ALPHA " ); if( nMaskFlags & GMF_NODATA ) printf( "NODATA " ); if( nMaskFlags & GMF_ALL_VALID ) printf( "ALL_VALID " ); printf( "\n" ); if( hMaskBand != NULL && GDALGetOverviewCount(hMaskBand) > 0 ) { int iOverview; printf( " Overviews of mask band: " ); for( iOverview = 0; iOverview < GDALGetOverviewCount(hMaskBand); iOverview++ ) { GDALRasterBandH hOverview; if( iOverview != 0 ) printf( ", " ); hOverview = GDALGetOverview( hMaskBand, iOverview ); printf( "%dx%d", GDALGetRasterBandXSize( hOverview ), GDALGetRasterBandYSize( hOverview ) ); } printf( "\n" ); } } if( strlen(GDALGetRasterUnitType(hBand)) > 0 ) { printf( " Unit Type: %s\n", GDALGetRasterUnitType(hBand) ); } if( GDALGetRasterCategoryNames(hBand) != NULL ) { char **papszCategories = GDALGetRasterCategoryNames(hBand); int i; printf( " Categories:\n" ); for( i = 0; papszCategories[i] != NULL; i++ ) printf( " %3d: %s\n", i, papszCategories[i] ); } if( GDALGetRasterScale( hBand, &bSuccess ) != 1.0 || GDALGetRasterOffset( hBand, &bSuccess ) != 0.0 ) printf( " Offset: %.15g, Scale:%.15g\n", GDALGetRasterOffset( hBand, &bSuccess ), GDALGetRasterScale( hBand, &bSuccess ) ); papszMetadata = (bShowMetadata) ? GDALGetMetadata( hBand, NULL ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( " Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } papszMetadata = (bShowMetadata) ? GDALGetMetadata( hBand, "IMAGE_STRUCTURE" ) : NULL; if( bShowMetadata && CSLCount(papszMetadata) > 0 ) { printf( " Image Structure Metadata:\n" ); for( i = 0; papszMetadata[i] != NULL; i++ ) { printf( " %s\n", papszMetadata[i] ); } } if( GDALGetRasterColorInterpretation(hBand) == GCI_PaletteIndex && (hTable = GDALGetRasterColorTable( hBand )) != NULL ) { int i; printf( " Color Table (%s with %d entries)\n", GDALGetPaletteInterpretationName( GDALGetPaletteInterpretation( hTable )), GDALGetColorEntryCount( hTable ) ); if (bShowColorTable) { for( i = 0; i < GDALGetColorEntryCount( hTable ); i++ ) { GDALColorEntry sEntry; GDALGetColorEntryAsRGB( hTable, i, &sEntry ); printf( " %3d: %d,%d,%d,%d\n", i, sEntry.c1, sEntry.c2, sEntry.c3, sEntry.c4 ); } } } if( bShowRAT && GDALGetDefaultRAT( hBand ) != NULL ) { GDALRasterAttributeTableH hRAT = GDALGetDefaultRAT( hBand ); GDALRATDumpReadable( hRAT, NULL ); } } GDALClose( hDataset ); CSLDestroy( papszExtraMDDomains ); CSLDestroy( argv ); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); CPLDumpSharedList( NULL ); CPLCleanupTLS(); exit( 0 ); }
static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, cairo_renderer *r) { /* We need a GDAL 1.10 PDF driver at runtime, but as far as the C API is concerned, GDAL 1.9 is */ /* largely sufficient. */ #if defined(USE_GDAL) && defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1900 GDALDatasetH hDS = NULL; const char* pszGEO_ENCODING = NULL; GDALDriverH hPDFDriver = NULL; const char* pszVirtualIO = NULL; int bVirtualIO = FALSE; char* pszTmpFilename = NULL; VSILFILE* fp = NULL; if (map == NULL) return; pszGEO_ENCODING = msGetOutputFormatOption(img->format, "GEO_ENCODING", NULL); if (pszGEO_ENCODING == NULL) return; msGDALInitialize(); hPDFDriver = GDALGetDriverByName("PDF"); if (hPDFDriver == NULL) return; /* When compiled against libpoppler, the PDF driver is VirtualIO capable */ /* but not, when it is compiled against libpodofo. */ pszVirtualIO = GDALGetMetadataItem( hPDFDriver, GDAL_DCAP_VIRTUALIO, NULL ); if (pszVirtualIO) bVirtualIO = CSLTestBoolean(pszVirtualIO); if (bVirtualIO) pszTmpFilename = msTmpFile(map, NULL, "/vsimem/mscairopdf/", "pdf"); else pszTmpFilename = msTmpFile(map, map->mappath, NULL, "pdf"); /* Copy content of outputStream buffer into file */ fp = VSIFOpenL(pszTmpFilename, "wb"); if (fp == NULL) { msFree(pszTmpFilename); return; } VSIFWriteL(r->outputStream->data, 1, r->outputStream->size, fp); VSIFCloseL(fp); fp = NULL; hDS = GDALOpen(pszTmpFilename, GA_Update); if ( hDS != NULL ) { char* pszWKT = msProjectionObj2OGCWKT( &(map->projection) ); if( pszWKT != NULL ) { double adfGeoTransform[6]; int i; /* Add user-specified options */ for( i = 0; i < img->format->numformatoptions; i++ ) { const char* pszOption = img->format->formatoptions[i]; if( strncasecmp(pszOption,"METADATA_ITEM:",14) == 0 ) { char* pszKey = NULL; const char* pszValue = CPLParseNameValue(pszOption + 14, &pszKey); if( pszKey != NULL ) { GDALSetMetadataItem(hDS, pszKey, pszValue, NULL); CPLFree(pszKey); } } } /* We need to rescale the geotransform because GDAL will not necessary */ /* open the PDF with the DPI that was used to generate it */ memcpy(adfGeoTransform, map->gt.geotransform, 6 * sizeof(double)); adfGeoTransform[1] = adfGeoTransform[1] * map->width / GDALGetRasterXSize(hDS); adfGeoTransform[5] = adfGeoTransform[5] * map->height / GDALGetRasterYSize(hDS); GDALSetGeoTransform(hDS, adfGeoTransform); GDALSetProjection(hDS, pszWKT); msFree( pszWKT ); pszWKT = NULL; CPLSetThreadLocalConfigOption("GDAL_PDF_GEO_ENCODING", pszGEO_ENCODING); GDALClose(hDS); hDS = NULL; CPLSetThreadLocalConfigOption("GDAL_PDF_GEO_ENCODING", NULL); /* We need to replace the buffer with the content of the GDAL file */ fp = VSIFOpenL(pszTmpFilename, "rb"); if( fp != NULL ) { int nFileSize; VSIFSeekL(fp, 0, SEEK_END); nFileSize = (int)VSIFTellL(fp); msBufferResize(r->outputStream, nFileSize); VSIFSeekL(fp, 0, SEEK_SET); r->outputStream->size = VSIFReadL(r->outputStream->data, 1, nFileSize, fp); VSIFCloseL(fp); fp = NULL; } } } if ( hDS != NULL ) GDALClose(hDS); VSIUnlink(pszTmpFilename); msFree(pszTmpFilename); #endif }
MAIN_START(nArgc, papszArgv) { // Check strict compilation and runtime library version as we use C++ API. if( !GDAL_CHECK_VERSION(papszArgv[0]) ) exit(1); EarlySetConfigOptions(nArgc, papszArgv); OGRRegisterAll(); /* -------------------------------------------------------------------- */ /* Processing command line arguments. */ /* -------------------------------------------------------------------- */ nArgc = OGRGeneralCmdLineProcessor(nArgc, &papszArgv, 0); if( nArgc < 1 ) exit(-nArgc); char *pszWHERE = nullptr; const char *pszDataSource = nullptr; char **papszLayers = nullptr; OGRGeometry *poSpatialFilter = nullptr; int nRepeatCount = 1; bool bAllLayers = false; char *pszSQLStatement = nullptr; const char *pszDialect = nullptr; int nRet = 0; const char* pszGeomField = nullptr; char **papszOpenOptions = nullptr; char **papszExtraMDDomains = nullptr; bool bListMDD = false; bool bShowMetadata = true; bool bFeatureCount = true; bool bExtent = true; bool bDatasetGetNextFeature = false; bool bReadOnly = false; bool bUpdate = false; const char* pszWKTFormat = "WKT2"; for( int iArg = 1; iArg < nArgc; iArg++ ) { if( EQUAL(papszArgv[iArg], "--utility_version") ) { printf("%s was compiled against GDAL %s and " "is running against GDAL %s\n", papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); CSLDestroy(papszArgv); return 0; } else if( EQUAL(papszArgv[iArg], "--help") ) { Usage(); } else if( EQUAL(papszArgv[iArg], "-ro") ) { bReadOnly = true; } else if( EQUAL(papszArgv[iArg], "-update") ) { bUpdate = true; } else if( EQUAL(papszArgv[iArg], "-q") || EQUAL(papszArgv[iArg], "-quiet")) { bVerbose = false; } else if( EQUAL(papszArgv[iArg], "-qq") ) { /* Undocumented: mainly only useful for AFL testing */ bVerbose = false; bSuperQuiet = true; } else if( EQUAL(papszArgv[iArg], "-fid") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); nFetchFID = CPLAtoGIntBig(papszArgv[++iArg]); } else if( EQUAL(papszArgv[iArg], "-spat") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(4); OGRLinearRing oRing; oRing.addPoint(CPLAtof(papszArgv[iArg+1]), CPLAtof(papszArgv[iArg+2])); oRing.addPoint(CPLAtof(papszArgv[iArg+1]), CPLAtof(papszArgv[iArg+4])); oRing.addPoint(CPLAtof(papszArgv[iArg+3]), CPLAtof(papszArgv[iArg+4])); oRing.addPoint(CPLAtof(papszArgv[iArg+3]), CPLAtof(papszArgv[iArg+2])); oRing.addPoint(CPLAtof(papszArgv[iArg+1]), CPLAtof(papszArgv[iArg+2])); poSpatialFilter = new OGRPolygon(); static_cast<OGRPolygon *>(poSpatialFilter)->addRing(&oRing); iArg += 4; } else if( EQUAL(papszArgv[iArg], "-geomfield") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszGeomField = papszArgv[++iArg]; } else if( EQUAL(papszArgv[iArg], "-where") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); iArg++; CPLFree(pszWHERE); GByte* pabyRet = nullptr; if( papszArgv[iArg][0] == '@' && VSIIngestFile(nullptr, papszArgv[iArg] + 1, &pabyRet, nullptr, 1024*1024) ) { RemoveBOM(pabyRet); pszWHERE = reinterpret_cast<char *>(pabyRet); } else { pszWHERE = CPLStrdup(papszArgv[iArg]); } } else if( EQUAL(papszArgv[iArg], "-sql") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); iArg++; CPLFree(pszSQLStatement); GByte* pabyRet = nullptr; if( papszArgv[iArg][0] == '@' && VSIIngestFile(nullptr, papszArgv[iArg] + 1, &pabyRet, nullptr, 1024*1024) ) { RemoveBOM(pabyRet); pszSQLStatement = reinterpret_cast<char *>(pabyRet); RemoveSQLComments(pszSQLStatement); } else { pszSQLStatement = CPLStrdup(papszArgv[iArg]); } } else if( EQUAL(papszArgv[iArg], "-dialect") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszDialect = papszArgv[++iArg]; } else if( EQUAL(papszArgv[iArg], "-rc") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); nRepeatCount = atoi(papszArgv[++iArg]); } else if( EQUAL(papszArgv[iArg], "-al") ) { bAllLayers = true; } else if( EQUAL(papszArgv[iArg], "-so") || EQUAL(papszArgv[iArg], "-summary") ) { bSummaryOnly = true; } else if( STARTS_WITH_CI(papszArgv[iArg], "-fields=") ) { char* pszTemp = static_cast<char *>(CPLMalloc(32 + strlen(papszArgv[iArg]))); snprintf(pszTemp, 32 + strlen(papszArgv[iArg]), "DISPLAY_FIELDS=%s", papszArgv[iArg] + strlen("-fields=")); papszOptions = CSLAddString(papszOptions, pszTemp); CPLFree(pszTemp); } else if( STARTS_WITH_CI(papszArgv[iArg], "-geom=") ) { char* pszTemp = static_cast<char *>(CPLMalloc(32 + strlen(papszArgv[iArg]))); snprintf(pszTemp, 32 + strlen(papszArgv[iArg]), "DISPLAY_GEOMETRY=%s", papszArgv[iArg] + strlen("-geom=")); papszOptions = CSLAddString(papszOptions, pszTemp); CPLFree(pszTemp); } else if( EQUAL(papszArgv[iArg], "-oo") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); papszOpenOptions = CSLAddString(papszOpenOptions, papszArgv[++iArg]); } else if( EQUAL(papszArgv[iArg], "-nomd") ) { bShowMetadata = false; } else if( EQUAL(papszArgv[iArg], "-listmdd") ) { bListMDD = true; } else if( EQUAL(papszArgv[iArg], "-mdd") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); papszExtraMDDomains = CSLAddString(papszExtraMDDomains, papszArgv[++iArg]); } else if( EQUAL(papszArgv[iArg], "-nocount") ) { bFeatureCount = false; } else if( EQUAL(papszArgv[iArg], "-noextent") ) { bExtent = false; } else if( EQUAL(papszArgv[iArg], "-rl")) { bDatasetGetNextFeature = true; } else if( EQUAL(papszArgv[iArg], "-wkt_format") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszWKTFormat = papszArgv[++iArg]; } else if( papszArgv[iArg][0] == '-' ) { Usage(CPLSPrintf("Unknown option name '%s'", papszArgv[iArg])); } else if( pszDataSource == nullptr ) { pszDataSource = papszArgv[iArg]; } else { papszLayers = CSLAddString(papszLayers, papszArgv[iArg]); bAllLayers = false; } } if( pszDataSource == nullptr ) Usage("No datasource specified."); if( pszDialect != nullptr && pszWHERE != nullptr && pszSQLStatement == nullptr ) printf("Warning: -dialect is ignored with -where. Use -sql instead"); if( bDatasetGetNextFeature && pszSQLStatement ) { Usage("-rl is incompatible with -sql"); } #ifdef __AFL_HAVE_MANUAL_CONTROL while (__AFL_LOOP(1000)) { #endif /* -------------------------------------------------------------------- */ /* Open data source. */ /* -------------------------------------------------------------------- */ GDALDataset *poDS = static_cast<GDALDataset *>(GDALOpenEx( pszDataSource, ((bReadOnly || pszSQLStatement == nullptr) && !bUpdate ? GDAL_OF_READONLY : GDAL_OF_UPDATE) | GDAL_OF_VECTOR, nullptr, papszOpenOptions, nullptr)); if( poDS == nullptr && !bReadOnly && !bUpdate && pszSQLStatement == nullptr ) { // In some cases (empty geopackage for example), opening in read-only // mode fails, so retry in update mode if( GDALIdentifyDriverEx(pszDataSource, GDAL_OF_VECTOR, nullptr, nullptr) ) { poDS = static_cast<GDALDataset *>(GDALOpenEx( pszDataSource, GDAL_OF_UPDATE | GDAL_OF_VECTOR, nullptr, papszOpenOptions, nullptr)); } } if( poDS == nullptr && !bReadOnly && !bUpdate && pszSQLStatement != nullptr ) { poDS = static_cast<GDALDataset *>(GDALOpenEx( pszDataSource, GDAL_OF_READONLY | GDAL_OF_VECTOR, nullptr, papszOpenOptions, nullptr)); if( poDS != nullptr && bVerbose ) { printf("Had to open data source read-only.\n"); #ifdef __AFL_HAVE_MANUAL_CONTROL bReadOnly = true; #endif } } GDALDriver *poDriver = nullptr; if( poDS != nullptr ) poDriver = poDS->GetDriver(); /* -------------------------------------------------------------------- */ /* Report failure */ /* -------------------------------------------------------------------- */ if( poDS == nullptr ) { printf("FAILURE:\n" "Unable to open datasource `%s' with the following drivers.\n", pszDataSource); #ifdef __AFL_HAVE_MANUAL_CONTROL continue; #else OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar(); for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ ) { printf(" -> %s\n", poR->GetDriver(iDriver)->GetDescription()); } nRet = 1; goto end; #endif } CPLAssert(poDriver != nullptr); /* -------------------------------------------------------------------- */ /* Some information messages. */ /* -------------------------------------------------------------------- */ if( bVerbose ) printf("INFO: Open of `%s'\n" " using driver `%s' successful.\n", pszDataSource, poDriver->GetDescription()); if( bVerbose && !EQUAL(pszDataSource,poDS->GetDescription()) ) { printf("INFO: Internal data source name `%s'\n" " different from user name `%s'.\n", poDS->GetDescription(), pszDataSource); } GDALInfoReportMetadata(static_cast<GDALMajorObjectH>(poDS), bListMDD, bShowMetadata, papszExtraMDDomains); if( bDatasetGetNextFeature ) { nRepeatCount = 0; // skip layer reporting. /* -------------------------------------------------------------------- */ /* Set filters if provided. */ /* -------------------------------------------------------------------- */ if( pszWHERE != nullptr || poSpatialFilter != nullptr ) { for( int iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ ) { OGRLayer *poLayer = poDS->GetLayer(iLayer); if( poLayer == nullptr ) { printf("FAILURE: Couldn't fetch advertised layer %d!\n", iLayer); exit(1); } if( pszWHERE != nullptr ) { if( poLayer->SetAttributeFilter(pszWHERE) != OGRERR_NONE ) { printf("WARNING: SetAttributeFilter(%s) " "failed on layer %s.\n", pszWHERE, poLayer->GetName()); } } if( poSpatialFilter != nullptr ) { if( pszGeomField != nullptr ) { OGRFeatureDefn *poDefn = poLayer->GetLayerDefn(); const int iGeomField = poDefn->GetGeomFieldIndex(pszGeomField); if( iGeomField >= 0 ) poLayer->SetSpatialFilter(iGeomField, poSpatialFilter); else printf("WARNING: Cannot find geometry field %s.\n", pszGeomField); } else { poLayer->SetSpatialFilter(poSpatialFilter); } } } } std::set<OGRLayer*> oSetLayers; while( true ) { OGRLayer* poLayer = nullptr; OGRFeature* poFeature = poDS->GetNextFeature(&poLayer, nullptr, nullptr, nullptr); if( poFeature == nullptr ) break; if( papszLayers == nullptr || poLayer == nullptr || CSLFindString(papszLayers, poLayer->GetName()) >= 0 ) { if( bVerbose && poLayer != nullptr && oSetLayers.find(poLayer) == oSetLayers.end() ) { oSetLayers.insert(poLayer); const bool bSummaryOnlyBackup = bSummaryOnly; bSummaryOnly = true; ReportOnLayer(poLayer, nullptr, nullptr, nullptr, bListMDD, bShowMetadata, papszExtraMDDomains, bFeatureCount, bExtent, pszWKTFormat); bSummaryOnly = bSummaryOnlyBackup; } if( !bSuperQuiet && !bSummaryOnly ) poFeature->DumpReadable(nullptr, papszOptions); } OGRFeature::DestroyFeature(poFeature); } } /* -------------------------------------------------------------------- */ /* Special case for -sql clause. No source layers required. */ /* -------------------------------------------------------------------- */ else if( pszSQLStatement != nullptr ) { nRepeatCount = 0; // skip layer reporting. if( CSLCount(papszLayers) > 0 ) printf("layer names ignored in combination with -sql.\n"); OGRLayer *poResultSet = poDS->ExecuteSQL( pszSQLStatement, pszGeomField == nullptr ? poSpatialFilter : nullptr, pszDialect); if( poResultSet != nullptr ) { if( pszWHERE != nullptr ) { if( poResultSet->SetAttributeFilter(pszWHERE) != OGRERR_NONE ) { printf("FAILURE: SetAttributeFilter(%s) failed.\n", pszWHERE); exit(1); } } if( pszGeomField != nullptr ) ReportOnLayer(poResultSet, nullptr, pszGeomField, poSpatialFilter, bListMDD, bShowMetadata, papszExtraMDDomains, bFeatureCount, bExtent, pszWKTFormat); else ReportOnLayer(poResultSet, nullptr, nullptr, nullptr, bListMDD, bShowMetadata, papszExtraMDDomains, bFeatureCount, bExtent, pszWKTFormat); poDS->ReleaseResultSet(poResultSet); } } // coverity[tainted_data] for( int iRepeat = 0; iRepeat < nRepeatCount; iRepeat++ ) { if( papszLayers == nullptr || *papszLayers == nullptr ) { if( iRepeat == 0 ) CPLDebug("OGR", "GetLayerCount() = %d\n", poDS->GetLayerCount()); /* -------------------------------------------------------------------- */ /* Process each data source layer. */ /* -------------------------------------------------------------------- */ for( int iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ ) { OGRLayer *poLayer = poDS->GetLayer(iLayer); if( poLayer == nullptr ) { printf("FAILURE: Couldn't fetch advertised layer %d!\n", iLayer); exit(1); } if( !bAllLayers ) { printf("%d: %s", iLayer + 1, poLayer->GetName()); const int nGeomFieldCount = poLayer->GetLayerDefn()->GetGeomFieldCount(); if( nGeomFieldCount > 1 ) { printf(" ("); for( int iGeom = 0; iGeom < nGeomFieldCount; iGeom++ ) { if( iGeom > 0 ) printf(", "); OGRGeomFieldDefn* poGFldDefn = poLayer->GetLayerDefn()-> GetGeomFieldDefn(iGeom); printf( "%s", OGRGeometryTypeToName( poGFldDefn->GetType())); } printf(")"); } else if( poLayer->GetGeomType() != wkbUnknown ) printf(" (%s)", OGRGeometryTypeToName( poLayer->GetGeomType())); printf("\n"); } else { if( iRepeat != 0 ) poLayer->ResetReading(); ReportOnLayer(poLayer, pszWHERE, pszGeomField, poSpatialFilter, bListMDD, bShowMetadata, papszExtraMDDomains, bFeatureCount, bExtent, pszWKTFormat); } } } else { /* -------------------------------------------------------------------- */ /* Process specified data source layers. */ /* -------------------------------------------------------------------- */ for( char** papszIter = papszLayers; *papszIter != nullptr; ++papszIter ) { OGRLayer *poLayer = poDS->GetLayerByName(*papszIter); if( poLayer == nullptr ) { printf("FAILURE: Couldn't fetch requested layer %s!\n", *papszIter); exit(1); } if( iRepeat != 0 ) poLayer->ResetReading(); ReportOnLayer(poLayer, pszWHERE, pszGeomField, poSpatialFilter, bListMDD, bShowMetadata, papszExtraMDDomains, bFeatureCount, bExtent, pszWKTFormat); } } } /* -------------------------------------------------------------------- */ /* Close down. */ /* -------------------------------------------------------------------- */ GDALClose(poDS); #ifdef __AFL_HAVE_MANUAL_CONTROL } #else end: #endif CSLDestroy(papszArgv); CSLDestroy(papszLayers); CSLDestroy(papszOptions); CSLDestroy(papszOpenOptions); CSLDestroy(papszExtraMDDomains); if( poSpatialFilter ) OGRGeometryFactory::destroyGeometry(poSpatialFilter); CPLFree(pszSQLStatement); CPLFree(pszWHERE); OGRCleanupAll(); return nRet; }
int QgsRasterCalculator::processCalculation( QProgressDialog* p ) { //prepare search string / tree QString errorString; QgsRasterCalcNode* calcNode = QgsRasterCalcNode::parseRasterCalcString( mFormulaString, errorString ); if ( !calcNode ) { //error return static_cast<int>( ParserError ); } QMap< QString, QgsRasterBlock* > inputBlocks; QVector<QgsRasterCalculatorEntry>::const_iterator it = mRasterEntries.constBegin(); for ( ; it != mRasterEntries.constEnd(); ++it ) { if ( !it->raster ) // no raster layer in entry { delete calcNode; qDeleteAll( inputBlocks ); return static_cast< int >( InputLayerError ); } QgsRasterBlock* block = nullptr; // if crs transform needed if ( it->raster->crs() != mOutputCrs ) { QgsRasterProjector proj; proj.setCrs( it->raster->crs(), mOutputCrs ); proj.setInput( it->raster->dataProvider() ); proj.setPrecision( QgsRasterProjector::Exact ); block = proj.block( it->bandNumber, mOutputRectangle, mNumOutputColumns, mNumOutputRows ); } else { block = it->raster->dataProvider()->block( it->bandNumber, mOutputRectangle, mNumOutputColumns, mNumOutputRows ); } if ( block->isEmpty() ) { delete block; delete calcNode; qDeleteAll( inputBlocks ); return static_cast<int>( MemoryError ); } inputBlocks.insert( it->ref, block ); } //open output dataset for writing GDALDriverH outputDriver = openOutputDriver(); if ( !outputDriver ) { return static_cast< int >( CreateOutputError ); } GDALDatasetH outputDataset = openOutputFile( outputDriver ); GDALSetProjection( outputDataset, mOutputCrs.toWkt().toLocal8Bit().data() ); GDALRasterBandH outputRasterBand = GDALGetRasterBand( outputDataset, 1 ); float outputNodataValue = -FLT_MAX; GDALSetRasterNoDataValue( outputRasterBand, outputNodataValue ); if ( p ) { p->setMaximum( mNumOutputRows ); } QgsRasterMatrix resultMatrix; resultMatrix.setNodataValue( outputNodataValue ); //read / write line by line for ( int i = 0; i < mNumOutputRows; ++i ) { if ( p ) { p->setValue( i ); } if ( p && p->wasCanceled() ) { break; } if ( calcNode->calculate( inputBlocks, resultMatrix, i ) ) { bool resultIsNumber = resultMatrix.isNumber(); float* calcData = new float[mNumOutputColumns]; for ( int j = 0; j < mNumOutputColumns; ++j ) { calcData[j] = ( float )( resultIsNumber ? resultMatrix.number() : resultMatrix.data()[j] ); } //write scanline to the dataset if ( GDALRasterIO( outputRasterBand, GF_Write, 0, i, mNumOutputColumns, 1, calcData, mNumOutputColumns, 1, GDT_Float32, 0, 0 ) != CE_None ) { QgsDebugMsg( "RasterIO error!" ); } delete[] calcData; } } if ( p ) { p->setValue( mNumOutputRows ); } //close datasets and release memory delete calcNode; qDeleteAll( inputBlocks ); inputBlocks.clear(); if ( p && p->wasCanceled() ) { //delete the dataset without closing (because it is faster) GDALDeleteDataset( outputDriver, TO8F( mOutputFile ) ); return static_cast< int >( Cancelled ); } GDALClose( outputDataset ); return static_cast< int >( Success ); }
// Slot called when the menu item is triggered // If you created more menu items / toolbar buttons in initiGui, you should // create a separate handler for each action - this single run() method will // not be enough void Heatmap::run() { HeatmapGui d( mQGisIface->mainWindow(), QgisGui::ModalDialogFlags, &mSessionSettings ); if ( d.exec() == QDialog::Accepted ) { // everything runs here // Get the required data from the dialog QgsRectangle myBBox = d.bbox(); int columns = d.columns(); int rows = d.rows(); double cellsize = d.cellSizeX(); // or d.cellSizeY(); both have the same value mDecay = d.decayRatio(); int kernelShape = d.kernelShape(); // Start working on the input vector QgsVectorLayer* inputLayer = d.inputVectorLayer(); // Getting the rasterdataset in place GDALAllRegister(); GDALDataset *emptyDataset; GDALDriver *myDriver; myDriver = GetGDALDriverManager()->GetDriverByName( d.outputFormat().toUtf8() ); if ( myDriver == NULL ) { QMessageBox::information( 0, tr( "GDAL driver error" ), tr( "Cannot open the driver for the specified format" ) ); return; } double geoTransform[6] = { myBBox.xMinimum(), cellsize, 0, myBBox.yMinimum(), 0, cellsize }; emptyDataset = myDriver->Create( d.outputFilename().toUtf8(), columns, rows, 1, GDT_Float32, NULL ); emptyDataset->SetGeoTransform( geoTransform ); // Set the projection on the raster destination to match the input layer emptyDataset->SetProjection( inputLayer->crs().toWkt().toLocal8Bit().data() ); GDALRasterBand *poBand; poBand = emptyDataset->GetRasterBand( 1 ); poBand->SetNoDataValue( NO_DATA ); float* line = ( float * ) CPLMalloc( sizeof( float ) * columns ); for ( int i = 0; i < columns ; i++ ) { line[i] = NO_DATA; } // Write the empty raster for ( int i = 0; i < rows ; i++ ) { poBand->RasterIO( GF_Write, 0, i, columns, 1, line, columns, 1, GDT_Float32, 0, 0 ); } CPLFree( line ); //close the dataset GDALClose(( GDALDatasetH ) emptyDataset ); // open the raster in GA_Update mode GDALDataset *heatmapDS; heatmapDS = ( GDALDataset * ) GDALOpen( TO8F( d.outputFilename() ), GA_Update ); if ( !heatmapDS ) { QMessageBox::information( 0, tr( "Raster update error" ), tr( "Could not open the created raster for updating. The heatmap was not generated." ) ); return; } poBand = heatmapDS->GetRasterBand( 1 ); QgsAttributeList myAttrList; int rField = 0; int wField = 0; // Handle different radius options double radius; double radiusToMapUnits = 1; int myBuffer = 0; if ( d.variableRadius() ) { rField = d.radiusField(); myAttrList.append( rField ); QgsDebugMsg( QString( "Radius Field index received: %1" ).arg( rField ) ); // If not using map units, then calculate a conversion factor to convert the radii to map units if ( d.radiusUnit() == HeatmapGui::Meters ) { radiusToMapUnits = mapUnitsOf( 1, inputLayer->crs() ); } } else { radius = d.radius(); // radius returned by d.radius() is already in map units myBuffer = bufferSize( radius, cellsize ); } if ( d.weighted() ) { wField = d.weightField(); myAttrList.append( wField ); } // This might have attributes or mightnot have attibutes at all // based on the variableRadius() and weighted() QgsFeatureIterator fit = inputLayer->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( myAttrList ) ); int totalFeatures = inputLayer->featureCount(); int counter = 0; QProgressDialog p( tr( "Creating heatmap" ), tr( "Abort" ), 0, totalFeatures, mQGisIface->mainWindow() ); p.setWindowModality( Qt::ApplicationModal ); p.show(); QgsFeature myFeature; while ( fit.nextFeature( myFeature ) ) { counter++; p.setValue( counter ); QApplication::processEvents(); if ( p.wasCanceled() ) { QMessageBox::information( 0, tr( "Heatmap generation aborted" ), tr( "QGIS will now load the partially-computed raster." ) ); break; } QgsGeometry* myPointGeometry; myPointGeometry = myFeature.geometry(); // convert the geometry to point QgsPoint myPoint; myPoint = myPointGeometry->asPoint(); // avoiding any empty points or out of extent points if (( myPoint.x() < myBBox.xMinimum() ) || ( myPoint.y() < myBBox.yMinimum() ) || ( myPoint.x() > myBBox.xMaximum() ) || ( myPoint.y() > myBBox.yMaximum() ) ) { continue; } // If radius is variable then fetch it and calculate new pixel buffer size if ( d.variableRadius() ) { radius = myFeature.attribute( rField ).toDouble() * radiusToMapUnits; myBuffer = bufferSize( radius, cellsize ); } int blockSize = 2 * myBuffer + 1; //Block SIDE would be more appropriate // calculate the pixel position unsigned int xPosition, yPosition; xPosition = (( myPoint.x() - myBBox.xMinimum() ) / cellsize ) - myBuffer; yPosition = (( myPoint.y() - myBBox.yMinimum() ) / cellsize ) - myBuffer; // get the data float *dataBuffer = ( float * ) CPLMalloc( sizeof( float ) * blockSize * blockSize ); poBand->RasterIO( GF_Read, xPosition, yPosition, blockSize, blockSize, dataBuffer, blockSize, blockSize, GDT_Float32, 0, 0 ); double weight = 1.0; if ( d.weighted() ) { weight = myFeature.attribute( wField ).toDouble(); } for ( int xp = 0; xp <= myBuffer; xp++ ) { for ( int yp = 0; yp <= myBuffer; yp++ ) { double distance = sqrt( pow( xp, 2.0 ) + pow( yp, 2.0 ) ); // is pixel outside search bandwidth of feature? if ( distance > myBuffer ) { continue; } double pixelValue = weight * calculateKernelValue( distance, myBuffer, kernelShape ); // clearing anamolies along the axes if ( xp == 0 && yp == 0 ) { pixelValue /= 4; } else if ( xp == 0 || yp == 0 ) { pixelValue /= 2; } int pos[4]; pos[0] = ( myBuffer + xp ) * blockSize + ( myBuffer + yp ); pos[1] = ( myBuffer + xp ) * blockSize + ( myBuffer - yp ); pos[2] = ( myBuffer - xp ) * blockSize + ( myBuffer + yp ); pos[3] = ( myBuffer - xp ) * blockSize + ( myBuffer - yp ); for ( int p = 0; p < 4; p++ ) { if ( dataBuffer[ pos[p] ] == NO_DATA ) { dataBuffer[ pos[p] ] = 0; } dataBuffer[ pos[p] ] += pixelValue; } } } poBand->RasterIO( GF_Write, xPosition, yPosition, blockSize, blockSize, dataBuffer, blockSize, blockSize, GDT_Float32, 0, 0 ); CPLFree( dataBuffer ); } // Finally close the dataset GDALClose(( GDALDatasetH ) heatmapDS ); // Open the file in QGIS window mQGisIface->addRasterLayer( d.outputFilename(), QFileInfo( d.outputFilename() ).baseName() ); } }
// ------------------------------------------------------------------- int main(int argc, char **argv) { char *ERROR_PRM = "Ungueltiger numerischer Wert fuer %s: %s\n!"; // Alle GDAL Treiber registrieren GDALAllRegister(); // Dateiname der Geotiff-Datei const char *format = "GTiff"; GDALDriverH h_drv = GDALGetDriverByName( format ); if( h_drv == NULL ) { error_exit(10,"Treiber %s nicht vorhanden!" ,format); } // Test ob Geotiffdateien erzeugt werden koennen char **test_meta; test_meta = GDALGetMetadata( h_drv, NULL ); if( ! CSLFetchBoolean( test_meta, GDAL_DCAP_CREATE, FALSE ) ) { error_exit(10,"Das Format %s kann nicht erzeugt werden" ,format); } // 3 Kommandozeilenparameter if (argc<6) { error_exit(10, "Fehlende Parameter\nUsage %s IN OUT EXT SZ ID X Y ID X Y ID X Y....!\n", argv[0]); } // Eingabemuster einlesen char *ifile = argv[1]; // Ausgabemuster einlesen char *ofile = argv[2]; // zusammengesetzte Ausgabedatei char cfile[512]; // Dateierweiterung setzen char *ext = argv[3]; // Fenstergroesse int size = 64; if (! sscanf(argv[4],"%d",&size) ) { error_exit(1000+3,ERROR_PRM,"SZ",argv[4]); } double trfm[] ={0,0,0,0,0,0}; // Vektoren fuer die Positionen und ID int_vector_t id; int_vector_init(&id, 10); dbl_vector_t pos_x; dbl_vector_init(&pos_x, 10); dbl_vector_t pos_y; dbl_vector_init(&pos_y, 10); // Positionen einlesen int a = 5; double dbl; int pk; while( a < argc-2 ) { // X Koordinate parsen if (! sscanf(argv[a],"%d",&pk) ) { error_exit(1000+a,ERROR_PRM,"ID", argv[a]); } int_vector_add(&id,pk); // X Koordinate parsen if (! sscanf(argv[a+1],"%lf",&dbl) ) { error_exit(1000+a+1,ERROR_PRM,"X", argv[a+1]); } dbl_vector_add(&pos_x,dbl); // Y Koordinate parsen if (! sscanf(argv[a+2],"%lf",&dbl) ) { error_exit(1000+a+2,ERROR_PRM,"Y", argv[a+2]); } dbl_vector_add(&pos_y,dbl); a+=3; } // Alle GDAL Treiber registrieren GDALAllRegister(); // Geotiff oeffnen printf("# IN FILE: %s\n", ifile); GDALDatasetH h_dset = GDALOpen( ifile, GA_ReadOnly); printf("# OUT FILE: %s\n", ofile); printf("# EXTENTION: %s\n", ext); // Transformation holen if( GDALGetGeoTransform( h_dset, trfm ) == CE_None ) { printf("# TRANSFORM: \n"); printf("# X = %.6f + %.6f * COL + %.6f * ROW\n", trfm[0], trfm[1], trfm[2] ); printf("# Y = %.6f + %.6f * COL + %.6f * ROW\n# EOF:\n", trfm[3], trfm[4], trfm[5] ); } else { error_exit(10, "Keine Transformation im TIFF vorhanden!\n"); } // Geotiff Fehler abfangen if( h_dset == NULL ) { error_exit(10, "Datensatz %s kann nicht geoeffnet werden!\n", ifile); } // Bilddimensionen ermitteln int img_width = GDALGetRasterXSize( h_dset ); int img_height = GDALGetRasterYSize( h_dset ); int num_bands = GDALGetRasterCount (h_dset ); // Bilddimensionen ermitteln GDALRasterBandH h_band[num_bands]; GDALDataType h_type[num_bands]; int h_tsize[num_bands]; for(int b=0 ; b<num_bands; b++) { h_band[b] = GDALGetRasterBand( h_dset, b+1 ); h_type[b] = GDALGetRasterDataType(h_band[b]); h_tsize[b] = GDALGetDataTypeSize(h_type[b]); } // Erzeuge Bildschnitte for (int c=0; c< pos_x.length; c++ ) { // Welt zu Pixeltransformation long icol = -1; long irow = -1; trfm_geo_pix(trfm, pos_x.data[c], pos_y.data[c], &icol , &irow); // Dateinamen erzeugen sprintf(cfile,"%s.%d%s",ofile, id.data[c],ext); // Test ob das Schnittfenstrer passt if (icol-size/2<=0 || irow-size/2<=0 || icol+size/2>=img_width || irow+size/2>=img_height){ printf ("IGN %d %s\n",id.data[c],ofile); continue; } // Schneiden printf ("ADD %d %s\n",id.data[c],ofile); int ioffs_col = icol-size/2; int ioffs_row = irow-size/2; // Tiff-Datei anlegen // char **options = NULL; GDALDatasetH h_dset_out = GDALCreate( h_drv, cfile, size, size, num_bands, h_type[0], NULL); // Iteration ueber alle Baender for (int b=0; b< num_bands; b++) { // IO Buffer allozieren @todo static void *io_buffer = CPLMalloc(h_tsize[0] * size * size); // Pixel lesen GDALRasterIO( h_band[b], GF_Read, ioffs_col, ioffs_row, size, size, io_buffer, size, size, h_type[b], 0, 0 ); // Pixel schreiben GDALRasterBandH h_band_out = GDALGetRasterBand(h_dset_out, b+1); GDALRasterIO( h_band_out, GF_Write, 0, 0, size, size, io_buffer, size, size, h_type[b], 0, 0 ); // IO Buffer freigeben CPLFree(io_buffer); } // resultierendes Tiff flushen und schliessen GDALClose( h_dset_out ); } // EOF Positions // Eingangsbild GDALClose( h_dset); return 0; }
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; }
int main( int argc, char ** argv ) { GDALDatasetH hSrcDS; int iY, iX, nOutLevel=0, nXSize, nYSize, iArg, nFillDist=0; void *pStream; GInt16 *panData; const char *pszFilename = NULL; GDALRasterBandH hSrcBand; double adfGeoTransform[6]; int bEnableTrim = FALSE; GInt16 noDataValue = 0; int bHasNoData; /* -------------------------------------------------------------------- */ /* Identify arguments. */ /* -------------------------------------------------------------------- */ for( iArg = 1; iArg < argc; iArg++ ) { if( EQUAL(argv[iArg],"-trim") ) bEnableTrim = TRUE; else if( EQUAL(argv[iArg],"-fill") ) nFillDist = atoi(argv[++iArg]); else if( EQUAL(argv[iArg],"-level") ) nOutLevel = atoi(argv[++iArg]); else { if( pszFilename != NULL ) Usage(); pszFilename = argv[iArg]; } } if( pszFilename == NULL ) Usage(); /* -------------------------------------------------------------------- */ /* Open input file. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); hSrcDS = GDALOpen( pszFilename, GA_ReadOnly ); if( hSrcDS == NULL ) exit(1); hSrcBand = GDALGetRasterBand( hSrcDS, 1 ); noDataValue = (GInt16)GDALGetRasterNoDataValue(hSrcBand, &bHasNoData); nXSize = GDALGetRasterXSize( hSrcDS ); nYSize = GDALGetRasterYSize( hSrcDS ); GDALGetGeoTransform( hSrcDS, adfGeoTransform ); /* -------------------------------------------------------------------- */ /* Create output stream. */ /* -------------------------------------------------------------------- */ pStream = DTEDCreatePtStream( ".", nOutLevel ); if( pStream == NULL ) exit( 1 ); /* -------------------------------------------------------------------- */ /* Process all the profiles. */ /* -------------------------------------------------------------------- */ panData = (GInt16 *) malloc(sizeof(GInt16) * nXSize); for( iY = 0; iY < nYSize; iY++ ) { GDALRasterIO( hSrcBand, GF_Read, 0, iY, nXSize, 1, panData, nXSize, 1, GDT_Int16, 0, 0 ); if (bHasNoData) { for( iX = 0; iX < nXSize; iX++ ) { if (panData[iX] == noDataValue) panData[iX] = DTED_NODATA_VALUE; } } for( iX = 0; iX < nXSize; iX++ ) { DTEDWritePt( pStream, adfGeoTransform[0] + adfGeoTransform[1] * (iX + 0.5) + adfGeoTransform[2] * (iY + 0.5), adfGeoTransform[3] + adfGeoTransform[4] * (iX + 0.5) + adfGeoTransform[5] * (iY + 0.5), panData[iX] ); } } free( panData ); /* -------------------------------------------------------------------- */ /* Cleanup. */ /* -------------------------------------------------------------------- */ if( bEnableTrim ) DTEDPtStreamTrimEdgeOnlyTiles( pStream ); if( nFillDist > 0 ) DTEDFillPtStream( pStream, nFillDist ); DTEDClosePtStream( pStream ); GDALClose( hSrcDS ); exit( 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; }
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; }
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, 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 tindex(maps*& conf, maps*& inputs,maps*& outputs) { char *index_filename = NULL; const char *tile_index = "location"; int i_arg, ti_field; OGRDataSourceH hTileIndexDS; OGRLayerH hLayer = NULL; OGRFeatureDefnH hFDefn; int write_absolute_path = FALSE; char* current_path = NULL; int i; int nExistingFiles; int skip_different_projection = FALSE; char** existingFilesTab = NULL; int alreadyExistingProjectionRefValid = FALSE; char* alreadyExistingProjectionRef = NULL; char* index_filename_mod; int bExists; VSIStatBuf sStatBuf; /* 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) { char tmp[1024]; sprintf(tmp, "At least, GDAL >= 1.4.0 is required for this version of" "tindex, which was compiled against GDAL %s\n", GDAL_RELEASE_NAME); return SERVICE_FAILED; } GDALAllRegister(); OGRRegisterAll(); /* -------------------------------------------------------------------- */ /* Get the directory name to search for raster file to index. */ /* -------------------------------------------------------------------- */ char *tmpDataDir; char *pszDataDir; map* tmpMap=getMapFromMaps(conf,"main","isTrial"); map* tmpMap1=getMapFromMaps(conf,"main","dataPath"); map* tmpInputMap=getMapFromMaps(inputs,"dir","value"); if(tmpMap!=NULL && strcasecmp(tmpMap->value,"true")==0){ pszDataDir=(char*) malloc((strlen(tmpInputMap->value)+strlen(tmpMap1->value)+5+1)*sizeof(char)); sprintf(pszDataDir,"%s/ftp/%s",tmpMap1->value,tmpInputMap->value); }else{ pszDataDir=(char*) malloc(((strlen(tmpInputMap->value)+1)*sizeof(char))); sprintf(pszDataDir,"%s",tmpInputMap->value); } tmpMap=getMapFromMaps(inputs,"iname","value"); tmpMap1=getMapFromMaps(inputs,"idir","value"); map* tmpMap2=getMapFromMaps(conf,"main","dataPath"); if(tmpMap!=NULL && tmpMap1!=NULL && tmpMap2!=NULL){ index_filename = (char*) malloc((strlen(tmpMap->value)+strlen(tmpMap1->value)+strlen(tmpMap2->value)+12)*sizeof(char)); sprintf(index_filename,"%s/dirs/%s/%s.shp",tmpMap2->value,tmpMap1->value,tmpMap->value); } fprintf(stderr,"Filename %s\n",index_filename); /* -------------------------------------------------------------------- */ /* Open or create the target shapefile and DBF file. */ /* -------------------------------------------------------------------- */ index_filename_mod = CPLStrdup(CPLResetExtension(index_filename, "shp")); bExists = (VSIStat(index_filename_mod, &sStatBuf) == 0); if (!bExists) { CPLFree(index_filename_mod); index_filename_mod = CPLStrdup(CPLResetExtension(index_filename, "SHP")); bExists = (VSIStat(index_filename_mod, &sStatBuf) == 0); } CPLFree(index_filename_mod); if (bExists) { hTileIndexDS = OGROpen( index_filename, TRUE, NULL ); if (hTileIndexDS != NULL) { hLayer = OGR_DS_GetLayer(hTileIndexDS, 0); } } else { OGRSFDriverH hDriver; const char* pszDriverName = "ESRI Shapefile"; fprintf( stderr,"Creating new index file...\n" ); hDriver = OGRGetDriverByName( pszDriverName ); if( hDriver == NULL ) { char msg[1024]; sprintf( msg, "%s driver not available.", pszDriverName ); setMapInMaps(conf,"lenv","message",msg); return SERVICE_FAILED; } hTileIndexDS = OGR_Dr_CreateDataSource( hDriver, index_filename, NULL ); if (hTileIndexDS) { char* pszLayerName = CPLStrdup(CPLGetBasename(index_filename)); OGRSpatialReferenceH hSpatialRef = NULL; GDALDatasetH hDS = GDALOpen( index_filename, GA_ReadOnly ); if (hDS) { const char* pszWKT = GDALGetProjectionRef(hDS); if (pszWKT != NULL && pszWKT[0] != '\0') { hSpatialRef = OSRNewSpatialReference(pszWKT); } GDALClose(hDS); } DIR *dirp = opendir(pszDataDir); if(dirp==NULL){ char tmp1[1024]; sprintf(tmp1,_ss("The specified path %s doesn't exist."),pszDataDir); setMapInMaps(conf,"lenv","message",tmp1); return SERVICE_FAILED; } char *res=NULL; struct dirent *dp; tmpMap=getMapFromMaps(inputs,"ext","value"); char *ext; if(tmpMap!=NULL) ext=tmpMap->value; while ((dp = readdir(dirp)) != NULL){ if(strncmp(dp->d_name,".",1)!=0&&strncmp(dp->d_name,"..",2)!=0){ char* argv=(char*) malloc((strlen(dp->d_name)+strlen(pszDataDir)+2)*sizeof(char)); sprintf(argv,"%s/%s",pszDataDir,dp->d_name); GDALDatasetH hDS0 = GDALOpen( argv, GA_ReadOnly ); if (hDS0) { const char* pszWKT = GDALGetProjectionRef(hDS0); fprintf(stderr,"SRS %s \n",pszWKT); if (pszWKT != NULL && pszWKT[0] != '\0') { if (hSpatialRef) OSRRelease(hSpatialRef); hSpatialRef = OSRNewSpatialReference(pszWKT); } GDALClose(hDS); } break; } } closedir(dirp); hLayer = OGR_DS_CreateLayer( hTileIndexDS, pszLayerName, hSpatialRef, wkbPolygon, NULL ); CPLFree(pszLayerName); if (hSpatialRef) OSRRelease(hSpatialRef); if (hLayer) { OGRFieldDefnH hFieldDefn = OGR_Fld_Create( tile_index, OFTString ); OGR_Fld_SetWidth( hFieldDefn, 255); OGR_L_CreateField( hLayer, hFieldDefn, TRUE ); OGR_Fld_Destroy(hFieldDefn); } } } if( hTileIndexDS == NULL || hLayer == NULL ) { char msg[1024]; sprintf( msg, "Unable to open/create shapefile `%s'.", index_filename ); setMapInMaps(conf,"lenv","message",msg); } hFDefn = OGR_L_GetLayerDefn(hLayer); for( ti_field = 0; ti_field < OGR_FD_GetFieldCount(hFDefn); ti_field++ ) { OGRFieldDefnH hFieldDefn = OGR_FD_GetFieldDefn( hFDefn, ti_field ); if( strcmp(OGR_Fld_GetNameRef(hFieldDefn), tile_index) == 0 ) break; } if( ti_field == OGR_FD_GetFieldCount(hFDefn) ) { char msg[1024]; sprintf( msg, "Unable to find field `%s' in DBF file `%s'.\n", tile_index, index_filename ); setMapInMaps(conf,"lenv","message",msg); return SERVICE_FAILED; } /* Load in memory existing file names in SHP */ nExistingFiles = OGR_L_GetFeatureCount(hLayer, FALSE); if (nExistingFiles) { OGRFeatureH hFeature; existingFilesTab = (char**)CPLMalloc(nExistingFiles * sizeof(char*)); for(i=0;i<nExistingFiles;i++) { hFeature = OGR_L_GetNextFeature(hLayer); existingFilesTab[i] = CPLStrdup(OGR_F_GetFieldAsString( hFeature, ti_field )); if (i == 0) { GDALDatasetH hDS = GDALOpen(existingFilesTab[i], GA_ReadOnly ); if (hDS) { alreadyExistingProjectionRefValid = TRUE; alreadyExistingProjectionRef = CPLStrdup(GDALGetProjectionRef(hDS)); GDALClose(hDS); } } OGR_F_Destroy( hFeature ); } } if (write_absolute_path) { current_path = CPLGetCurrentDir(); if (current_path == NULL) { fprintf( stderr, "This system does not support the CPLGetCurrentDir call. " "The option -write_absolute_path will have no effect\n"); write_absolute_path = FALSE; } } /* -------------------------------------------------------------------- */ /* loop over GDAL files, processing. */ /* -------------------------------------------------------------------- */ DIR *dirp = opendir(pszDataDir); if(dirp==NULL){ char tmp1[1024]; sprintf(tmp1,_ss("The specified path %s doesn't exist."),pszDataDir); setMapInMaps(conf,"lenv","message",tmp1); return SERVICE_FAILED; } char *res=NULL; struct dirent *dp; tmpMap=getMapFromMaps(inputs,"ext","value"); char *ext; if(tmpMap!=NULL) ext=tmpMap->value; while ((dp = readdir(dirp)) != NULL){ if(strlen(dp->d_name)>2 && strstr(dp->d_name,".")!=0 && strstr(dp->d_name,ext)>0){ char* argv=(char*) malloc((strlen(dp->d_name)+strlen(pszDataDir)+2)*sizeof(char)); sprintf(argv,"%s/%s",pszDataDir,dp->d_name); GDALDatasetH hDS; double adfGeoTransform[6]; double adfX[5], adfY[5]; int nXSize, nYSize; char* fileNameToWrite; const char* projectionRef; VSIStatBuf sStatBuf; int k; OGRFeatureH hFeature; OGRGeometryH hPoly, hRing; /* Make sure it is a file before building absolute path name */ if (write_absolute_path && CPLIsFilenameRelative( argv ) && VSIStat( argv, &sStatBuf ) == 0) { fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path, argv)); } else { fileNameToWrite = CPLStrdup(argv); } /* Checks that file is not already in tileindex */ for(i=0;i<nExistingFiles;i++) { if (EQUAL(fileNameToWrite, existingFilesTab[i])) { fprintf(stderr, "File %s is already in tileindex. Skipping it.\n", fileNameToWrite); break; } } if (i != nExistingFiles) { CPLFree(fileNameToWrite); continue; } hDS = GDALOpen( argv, GA_ReadOnly ); if( hDS == NULL ) { fprintf( stderr, "Unable to open %s, skipping.\n", argv ); CPLFree(fileNameToWrite); continue; } GDALGetGeoTransform( hDS, adfGeoTransform ); if( adfGeoTransform[0] == 0.0 && adfGeoTransform[1] == 1.0 && adfGeoTransform[3] == 0.0 && ABS(adfGeoTransform[5]) == 1.0 ) { fprintf( stderr, "It appears no georeferencing is available for\n" "`%s', skipping.\n", argv ); GDALClose( hDS ); CPLFree(fileNameToWrite); continue; } projectionRef = GDALGetProjectionRef(hDS); if (alreadyExistingProjectionRefValid) { int projectionRefNotNull, alreadyExistingProjectionRefNotNull; projectionRefNotNull = projectionRef && projectionRef[0]; alreadyExistingProjectionRefNotNull = alreadyExistingProjectionRef && alreadyExistingProjectionRef[0]; if ((projectionRefNotNull && alreadyExistingProjectionRefNotNull && EQUAL(projectionRef, alreadyExistingProjectionRef) == 0) || (projectionRefNotNull != alreadyExistingProjectionRefNotNull)) { fprintf(stderr, "Warning : %s is not using the same projection system as " "other files in the tileindex. This may cause problems when " "using it in MapServer for example.%s\n", argv, (skip_different_projection) ? " Skipping it" : ""); if (skip_different_projection) { CPLFree(fileNameToWrite); GDALClose( hDS ); continue; } } } else { alreadyExistingProjectionRefValid = TRUE; alreadyExistingProjectionRef = CPLStrdup(projectionRef); } nXSize = GDALGetRasterXSize( hDS ); nYSize = GDALGetRasterYSize( hDS ); adfX[0] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[0] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + 0 * adfGeoTransform[5]; adfX[1] = adfGeoTransform[0] + nXSize * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[1] = adfGeoTransform[3] + nXSize * adfGeoTransform[4] + 0 * adfGeoTransform[5]; adfX[2] = adfGeoTransform[0] + nXSize * adfGeoTransform[1] + nYSize * adfGeoTransform[2]; adfY[2] = adfGeoTransform[3] + nXSize * adfGeoTransform[4] + nYSize * adfGeoTransform[5]; adfX[3] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + nYSize * adfGeoTransform[2]; adfY[3] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + nYSize * adfGeoTransform[5]; adfX[4] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[4] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + 0 * adfGeoTransform[5]; hFeature = OGR_F_Create( OGR_L_GetLayerDefn( hLayer ) ); OGR_F_SetFieldString( hFeature, ti_field, fileNameToWrite ); hPoly = OGR_G_CreateGeometry(wkbPolygon); hRing = OGR_G_CreateGeometry(wkbLinearRing); for(k=0;k<5;k++) OGR_G_SetPoint_2D(hRing, k, adfX[k], adfY[k]); OGR_G_AddGeometryDirectly( hPoly, hRing ); OGR_F_SetGeometryDirectly( hFeature, hPoly ); if( OGR_L_CreateFeature( hLayer, hFeature ) != OGRERR_NONE ) { fprintf( stderr, "Failed to create feature in shapefile.\n" ); break; } OGR_F_Destroy( hFeature ); CPLFree(fileNameToWrite); GDALClose( hDS ); } } CPLFree(current_path); if (nExistingFiles) { for(i=0;i<nExistingFiles;i++) { CPLFree(existingFilesTab[i]); } CPLFree(existingFilesTab); } CPLFree(alreadyExistingProjectionRef); OGR_DS_Destroy( hTileIndexDS ); GDALDestroyDriverManager(); OGRCleanupAll(); setMapInMaps(outputs,"Result","value","Tile index successfully created."); //CSLDestroy(argv); return SERVICE_SUCCEEDED; }
SEXP ogrCheckExists (SEXP ogrSource, SEXP Layer) { OGRLayer *poLayer; #ifdef GDALV2 GDALDataset *poDS; GDALDriver *poDriver; #else OGRDataSource *poDS; OGRSFDriver *poDriver; #endif SEXP ans, drv; int pc=0; PROTECT(ans=NEW_LOGICAL(1)); pc++; installErrorHandler(); #ifdef GDALV2 poDS=(GDALDataset*) GDALOpenEx(CHAR(STRING_ELT(ogrSource, 0)), GDAL_OF_VECTOR, NULL, NULL, NULL); if (poDS != NULL) poDriver = poDS->GetDriver(); #else poDS=OGRSFDriverRegistrar::Open(CHAR(STRING_ELT(ogrSource, 0)), FALSE, &poDriver); #endif uninstallErrorHandlerAndTriggerError(); if (poDS==NULL) { // installErrorHandler(); // OGRDataSource::DestroyDataSource( poDS ); // uninstallErrorHandlerAndTriggerError(); // delete poDS; LOGICAL_POINTER(ans)[0] = FALSE; UNPROTECT(pc); return(ans); } installErrorHandler(); poLayer = poDS->GetLayerByName(CHAR(STRING_ELT(Layer, 0))); uninstallErrorHandlerAndTriggerError(); if (poLayer == NULL) { installErrorHandler(); #ifdef GDALV2 GDALClose( poDS ); #else OGRDataSource::DestroyDataSource( poDS ); #endif uninstallErrorHandlerAndTriggerError(); // delete poDS; LOGICAL_POINTER(ans)[0] = FALSE; UNPROTECT(pc); return(ans); } LOGICAL_POINTER(ans)[0] = TRUE; PROTECT(drv=allocVector(STRSXP,1)); pc++; installErrorHandler(); #ifdef GDALV2 SET_STRING_ELT(drv, 0, mkChar(poDriver->GetDescription())); #else SET_STRING_ELT(drv, 0, mkChar(poDriver->GetName())); #endif uninstallErrorHandlerAndTriggerError(); setAttrib(ans, install("driver"), drv); installErrorHandler(); #ifdef GDALV2 GDALClose( poDS ); #else OGRDataSource::DestroyDataSource( poDS ); #endif uninstallErrorHandlerAndTriggerError(); // delete poDS; UNPROTECT(pc); return(ans); }
int InCoreInterp::outputFile(char *outputName, int outputFormat, unsigned int outputType, double *adfGeoTransform, const char* wkt) { int i,j,k; FILE **arcFiles; char arcFileName[1024]; FILE **gridFiles; char gridFileName[1024]; const char *ext[6] = {".min", ".max", ".mean", ".idw", ".den", ".std"}; unsigned int type[6] = {OUTPUT_TYPE_MIN, OUTPUT_TYPE_MAX, OUTPUT_TYPE_MEAN, OUTPUT_TYPE_IDW, OUTPUT_TYPE_DEN, OUTPUT_TYPE_STD}; int numTypes = 6; // open ArcGIS files if(outputFormat == OUTPUT_FORMAT_ARC_ASCII || outputFormat == OUTPUT_FORMAT_ALL) { if((arcFiles = (FILE **)malloc(sizeof(FILE *) * numTypes)) == NULL) { cerr << "Arc File open error: " << endl; return -1; } for(i = 0; i < numTypes; i++) { if(outputType & type[i]) { strncpy(arcFileName, outputName, sizeof(arcFileName)); strncat(arcFileName, ext[i], strlen(ext[i])); strncat(arcFileName, ".asc", strlen(".asc")); if((arcFiles[i] = fopen(arcFileName, "w+")) == NULL) { cerr << "File open error: " << arcFileName << endl; return -1; } } else { arcFiles[i] = NULL; } } } else { arcFiles = NULL; } // open Grid ASCII files if(outputFormat == OUTPUT_FORMAT_GRID_ASCII || outputFormat == OUTPUT_FORMAT_ALL) { if((gridFiles = (FILE **)malloc(sizeof(FILE *) * numTypes)) == NULL) { cerr << "File array allocation error" << endl; return -1; } for(i = 0; i < numTypes; i++) { if(outputType & type[i]) { strncpy(gridFileName, outputName, sizeof(arcFileName)); strncat(gridFileName, ext[i], strlen(ext[i])); strncat(gridFileName, ".grid", strlen(".grid")); if((gridFiles[i] = fopen(gridFileName, "w+")) == NULL) { cerr << "File open error: " << gridFileName << endl; return -1; } } else { gridFiles[i] = NULL; } } } else { gridFiles = NULL; } // print ArcGIS headers if(arcFiles != NULL) { for(i = 0; i < numTypes; i++) { if(arcFiles[i] != NULL) { fprintf(arcFiles[i], "ncols %d\n", GRID_SIZE_X); fprintf(arcFiles[i], "nrows %d\n", GRID_SIZE_Y); fprintf(arcFiles[i], "xllcorner %f\n", min_x); fprintf(arcFiles[i], "yllcorner %f\n", min_y); fprintf(arcFiles[i], "cellsize %f\n", GRID_DIST_X); fprintf(arcFiles[i], "NODATA_value -9999\n"); } } } // print Grid headers if(gridFiles != NULL) { for(i = 0; i < numTypes; i++) { if(gridFiles[i] != NULL) { fprintf(gridFiles[i], "north: %f\n", max_y); fprintf(gridFiles[i], "south: %f\n", min_y); fprintf(gridFiles[i], "east: %f\n", max_x); fprintf(gridFiles[i], "west: %f\n", min_x); fprintf(gridFiles[i], "rows: %d\n", GRID_SIZE_Y); fprintf(gridFiles[i], "cols: %d\n", GRID_SIZE_X); } } } // print data for(i = GRID_SIZE_Y - 1; i >= 0; i--) { for(j = 0; j < GRID_SIZE_X; j++) { if(arcFiles != NULL) { // Zmin if(arcFiles[0] != NULL) { if(interp[j][i].empty == 0 && interp[j][i].filled == 0) fprintf(arcFiles[0], "-9999 "); else fprintf(arcFiles[0], "%f ", interp[j][i].Zmin); } // Zmax if(arcFiles[1] != NULL) { if(interp[j][i].empty == 0 && interp[j][i].filled == 0) fprintf(arcFiles[1], "-9999 "); else fprintf(arcFiles[1], "%f ", interp[j][i].Zmax); } // Zmean if(arcFiles[2] != NULL) { if(interp[j][i].empty == 0 && interp[j][i].filled == 0) fprintf(arcFiles[2], "-9999 "); else fprintf(arcFiles[2], "%f ", interp[j][i].Zmean); } // Zidw if(arcFiles[3] != NULL) { if(interp[j][i].empty == 0 && interp[j][i].filled == 0) fprintf(arcFiles[3], "-9999 "); else fprintf(arcFiles[3], "%f ", interp[j][i].Zidw); } // count if(arcFiles[4] != NULL) { if(interp[j][i].empty == 0 && interp[j][i].filled == 0) fprintf(arcFiles[4], "-9999 "); else fprintf(arcFiles[4], "%d ", interp[j][i].count); } // count if(arcFiles[5] != NULL) { if(interp[j][i].empty == 0 && interp[j][i].filled == 0) fprintf(arcFiles[5], "-9999 "); else fprintf(arcFiles[5], "%f ", interp[j][i].Zstd); } } if(gridFiles != NULL) { // Zmin if(gridFiles[0] != NULL) { if(interp[j][i].empty == 0 && interp[j][i].filled == 0) fprintf(gridFiles[0], "-9999 "); else fprintf(gridFiles[0], "%f ", interp[j][i].Zmin); } // Zmax if(gridFiles[1] != NULL) { if(interp[j][i].empty == 0 && interp[j][i].filled == 0) fprintf(gridFiles[1], "-9999 "); else fprintf(gridFiles[1], "%f ", interp[j][i].Zmax); } // Zmean if(gridFiles[2] != NULL) { if(interp[j][i].empty == 0 && interp[j][i].filled == 0) fprintf(gridFiles[2], "-9999 "); else fprintf(gridFiles[2], "%f ", interp[j][i].Zmean); } // Zidw if(gridFiles[3] != NULL) { if(interp[j][i].empty == 0 && interp[j][i].filled == 0) fprintf(gridFiles[3], "-9999 "); else fprintf(gridFiles[3], "%f ", interp[j][i].Zidw); } // count if(gridFiles[4] != NULL) { if(interp[j][i].empty == 0 && interp[j][i].filled == 0) fprintf(gridFiles[4], "-9999 "); else fprintf(gridFiles[4], "%d ", interp[j][i].count); } // count if(gridFiles[5] != NULL) { if(interp[j][i].empty == 0 && interp[j][i].filled == 0) fprintf(gridFiles[5], "-9999 "); else fprintf(gridFiles[5], "%f ", interp[j][i].Zstd); } } } if(arcFiles != NULL) for(k = 0; k < numTypes; k++) { if(arcFiles[k] != NULL) fprintf(arcFiles[k], "\n"); } if(gridFiles != NULL) for(k = 0; k < numTypes; k++) { if(gridFiles[k] != NULL) fprintf(gridFiles[k], "\n"); } } #ifdef HAVE_GDAL GDALDataset **gdalFiles; char gdalFileName[1024]; // open GDAL GeoTIFF files if(outputFormat == OUTPUT_FORMAT_GDAL_GTIFF || outputFormat == OUTPUT_FORMAT_ALL) { GDALAllRegister(); if((gdalFiles = (GDALDataset **)malloc(sizeof(GDALDataset *) * numTypes)) == NULL) { cerr << "File array allocation error" << endl; return -1; } for(i = 0; i < numTypes; i++) { if(outputType & type[i]) { strncpy(gdalFileName, outputName, sizeof(gdalFileName)); strncat(gdalFileName, ext[i], strlen(ext[i])); strncat(gdalFileName, ".tif", strlen(".tif")); char **papszMetadata; const char *pszFormat = "GTIFF"; GDALDriver* tpDriver = GetGDALDriverManager()->GetDriverByName(pszFormat); if (tpDriver) { papszMetadata = tpDriver->GetMetadata(); if (CSLFetchBoolean(papszMetadata, GDAL_DCAP_CREATE, FALSE)) { char **papszOptions = NULL; gdalFiles[i] = tpDriver->Create(gdalFileName, GRID_SIZE_X, GRID_SIZE_Y, 1, GDT_Float32, papszOptions); if (gdalFiles[i] == NULL) { cerr << "File open error: " << gdalFileName << endl; return -1; } else { if (adfGeoTransform) gdalFiles[i]->SetGeoTransform(adfGeoTransform); if (wkt) gdalFiles[i]->SetProjection(wkt); } } } } else { gdalFiles[i] = NULL; } } } else { gdalFiles = NULL; } if (gdalFiles != NULL) { for (i = 0; i < numTypes; i++) { if (gdalFiles[i] != NULL) { float *poRasterData = new float[GRID_SIZE_X*GRID_SIZE_Y]; for (j = 0; j < GRID_SIZE_X*GRID_SIZE_Y; j++) { poRasterData[j] = 0; } for(j = GRID_SIZE_Y - 1; j >= 0; j--) { for(k = 0; k < GRID_SIZE_X; k++) { int index = j * GRID_SIZE_X + k; if(interp[k][j].empty == 0 && interp[k][j].filled == 0) { poRasterData[index] = -9999.f; } else { switch (i) { case 0: poRasterData[index] = interp[k][j].Zmin; break; case 1: poRasterData[index] = interp[k][j].Zmax; break; case 2: poRasterData[index] = interp[k][j].Zmean; break; case 3: poRasterData[index] = interp[k][j].Zidw; break; case 4: poRasterData[index] = interp[k][j].count; break; case 5: poRasterData[index] = interp[k][j].Zstd; break; } } } } GDALRasterBand *tBand = gdalFiles[i]->GetRasterBand(1); tBand->SetNoDataValue(-9999.f); if (GRID_SIZE_X > 0 && GRID_SIZE_Y > 0) tBand->RasterIO(GF_Write, 0, 0, GRID_SIZE_X, GRID_SIZE_Y, poRasterData, GRID_SIZE_X, GRID_SIZE_Y, GDT_Float32, 0, 0); GDALClose((GDALDatasetH) gdalFiles[i]); delete [] poRasterData; } } } #endif // HAVE_GDAL // close files if(gridFiles != NULL) { for(i = 0; i < numTypes; i++) { if(gridFiles[i] != NULL) fclose(gridFiles[i]); } } if(arcFiles != NULL) { for(i = 0; i < numTypes; i++) { if(arcFiles[i] != NULL) fclose(arcFiles[i]); } } return 0; }
SEXP ogrDeleteLayer (SEXP ogrSource, SEXP Layer, SEXP ogrDriver) { OGRLayer *poLayer; #ifdef GDALV2 GDALDataset *poDS; GDALDriver *poDriver; #else OGRDataSource *poDS; OGRSFDriver *poDriver; #endif int iLayer = -1; int flag = 0; installErrorHandler(); #ifdef GDALV2 poDriver = GetGDALDriverManager()->GetDriverByName(CHAR(STRING_ELT(ogrDriver, 0))); #else poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName( CHAR(STRING_ELT(ogrDriver, 0)) ); #endif uninstallErrorHandlerAndTriggerError(); if (poDriver == NULL) { error("Driver not available"); } installErrorHandler(); #ifdef GDALV2 poDS=(GDALDataset*) GDALOpenEx(CHAR(STRING_ELT(ogrSource, 0)), GDAL_OF_VECTOR, NULL, NULL, NULL); if(poDS==NULL) { error("Cannot open data source"); } if (!EQUAL(CHAR(STRING_ELT(ogrDriver, 0)), poDS->GetDriver()->GetDescription())) { GDALClose( poDS ); poDS = NULL; } #else poDS = poDriver->Open(CHAR(STRING_ELT(ogrSource, 0)), TRUE); #endif uninstallErrorHandlerAndTriggerError(); if (poDS==NULL) error("Cannot open data source for update"); installErrorHandler(); for(iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++) { poLayer = poDS->GetLayer(iLayer); #ifdef GDALV2 if (poLayer != NULL && EQUAL(poLayer->GetName(), CHAR(STRING_ELT(Layer, 0)))) { flag = 1; break; } #else if (poLayer != NULL && EQUAL(poLayer->GetLayerDefn()->GetName(), CHAR(STRING_ELT(Layer, 0)))) { flag = 1; break; } #endif } uninstallErrorHandlerAndTriggerError(); installErrorHandler(); if (flag != 0) { int res = poDS->DeleteLayer(iLayer); if (res != OGRERR_NONE) { #ifdef GDALV2 GDALClose( poDS ); #else OGRDataSource::DestroyDataSource( poDS ); #endif uninstallErrorHandlerAndTriggerError(); error("ogrDeleteLayer: failed to delete layer"); } } else { warning("ogrDeleteLayer: no such layer"); } #ifdef GDALV2 GDALClose( poDS ); #else OGRDataSource::DestroyDataSource( poDS ); #endif uninstallErrorHandlerAndTriggerError(); return(R_NilValue); }
int GDALRPCTransform( void *pTransformArg, int bDstToSrc, int nPointCount, double *padfX, double *padfY, double *padfZ, int *panSuccess ) { VALIDATE_POINTER1( pTransformArg, "GDALRPCTransform", 0 ); GDALRPCTransformInfo *psTransform = (GDALRPCTransformInfo *) pTransformArg; GDALRPCInfo *psRPC = &(psTransform->sRPC); int i; if( psTransform->bReversed ) bDstToSrc = !bDstToSrc; int bands[1] = {1}; int nRasterXSize = 0, nRasterYSize = 0; /* -------------------------------------------------------------------- */ /* Lazy opening of the optionnal DEM file. */ /* -------------------------------------------------------------------- */ if(psTransform->pszDEMPath != NULL && psTransform->bHasTriedOpeningDS == FALSE) { int bIsValid = FALSE; psTransform->bHasTriedOpeningDS = TRUE; psTransform->poDS = (GDALDataset *) GDALOpen( psTransform->pszDEMPath, GA_ReadOnly ); if(psTransform->poDS != NULL && psTransform->poDS->GetRasterCount() >= 1) { const char* pszSpatialRef = psTransform->poDS->GetProjectionRef(); if (pszSpatialRef != NULL && pszSpatialRef[0] != '\0') { OGRSpatialReference* poWGSSpaRef = new OGRSpatialReference(SRS_WKT_WGS84); OGRSpatialReference* poDSSpaRef = new OGRSpatialReference(pszSpatialRef); if(!poWGSSpaRef->IsSame(poDSSpaRef)) psTransform->poCT =OGRCreateCoordinateTransformation( poWGSSpaRef, poDSSpaRef ); delete poWGSSpaRef; delete poDSSpaRef; } if (psTransform->poDS->GetGeoTransform( psTransform->adfGeoTransform) == CE_None && GDALInvGeoTransform( psTransform->adfGeoTransform, psTransform->adfReverseGeoTransform )) { bIsValid = TRUE; } } if (!bIsValid && psTransform->poDS != NULL) { GDALClose(psTransform->poDS); psTransform->poDS = NULL; } } if (psTransform->poDS) { nRasterXSize = psTransform->poDS->GetRasterXSize(); nRasterYSize = psTransform->poDS->GetRasterYSize(); } /* -------------------------------------------------------------------- */ /* The simple case is transforming from lat/long to pixel/line. */ /* Just apply the equations directly. */ /* -------------------------------------------------------------------- */ if( bDstToSrc ) { for( i = 0; i < nPointCount; i++ ) { if(psTransform->poDS) { double dfX, dfY; //check if dem is not in WGS84 and transform points padfX[i], padfY[i] if(psTransform->poCT) { double dfXOrig = padfX[i]; double dfYOrig = padfY[i]; double dfZOrig = padfZ[i]; if (!psTransform->poCT->Transform( 1, &dfXOrig, &dfYOrig, &dfZOrig)) { panSuccess[i] = FALSE; continue; } GDALApplyGeoTransform( psTransform->adfReverseGeoTransform, dfXOrig, dfYOrig, &dfX, &dfY ); } else GDALApplyGeoTransform( psTransform->adfReverseGeoTransform, padfX[i], padfY[i], &dfX, &dfY ); int dX = int(dfX); int dY = int(dfY); if (!(dX >= 0 && dY >= 0 && dX+2 <= nRasterXSize && dY+2 <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } double dfDEMH(0); double dfDeltaX = dfX - dX; double dfDeltaY = dfY - dY; if(psTransform->eResampleAlg == DRA_Cubic) { int dXNew = dX - 1; int dYNew = dY - 1; if (!(dXNew >= 0 && dYNew >= 0 && dXNew + 4 <= nRasterXSize && dYNew + 4 <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } //cubic interpolation int adElevData[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dXNew, dYNew, 4, 4, &adElevData, 4, 4, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } double dfSumH(0); for ( int i = 0; i < 5; i++ ) { // Loop across the X axis for ( int j = 0; j < 5; j++ ) { // Calculate the weight for the specified pixel according // to the bicubic b-spline kernel we're using for // interpolation int dKernIndX = j - 1; int dKernIndY = i - 1; double dfPixelWeight = BiCubicKernel(dKernIndX - dfDeltaX) * BiCubicKernel(dKernIndY - dfDeltaY); // Create a sum of all values // adjusted for the pixel's calculated weight dfSumH += adElevData[j + i * 4] * dfPixelWeight; } } dfDEMH = dfSumH; } else if(psTransform->eResampleAlg == DRA_Bilinear) { if (!(dX >= 0 && dY >= 0 && dX + 2 <= nRasterXSize && dY + 2 <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } //bilinear interpolation int anElevData[4] = {0,0,0,0}; CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 2, 2, &anElevData, 2, 2, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } double dfDeltaX1 = 1.0 - dfDeltaX; double dfDeltaY1 = 1.0 - dfDeltaY; double dfXZ1 = anElevData[0] * dfDeltaX1 + anElevData[1] * dfDeltaX; double dfXZ2 = anElevData[2] * dfDeltaX1 + anElevData[3] * dfDeltaX; double dfYZ = dfXZ1 * dfDeltaY1 + dfXZ2 * dfDeltaY; dfDEMH = dfYZ; } else { if (!(dX >= 0 && dY >= 0 && dX <= nRasterXSize && dY <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 1, 1, &dfDEMH, 1, 1, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } } RPCTransformPoint( psRPC, padfX[i], padfY[i], padfZ[i] + (psTransform->dfHeightOffset + dfDEMH) * psTransform->dfHeightScale, padfX + i, padfY + i ); } else RPCTransformPoint( psRPC, padfX[i], padfY[i], padfZ[i] + psTransform->dfHeightOffset * psTransform->dfHeightScale, padfX + i, padfY + i ); panSuccess[i] = TRUE; } return TRUE; } /* -------------------------------------------------------------------- */ /* Compute the inverse (pixel/line/height to lat/long). This */ /* function uses an iterative method from an initial linear */ /* approximation. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nPointCount; i++ ) { double dfResultX, dfResultY; if(psTransform->poDS) { RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], padfZ[i] + psTransform->dfHeightOffset * psTransform->dfHeightScale, &dfResultX, &dfResultY ); double dfX, dfY; //check if dem is not in WGS84 and transform points padfX[i], padfY[i] if(psTransform->poCT) { double dfZ = 0; if (!psTransform->poCT->Transform(1, &dfResultX, &dfResultY, &dfZ)) { panSuccess[i] = FALSE; continue; } } GDALApplyGeoTransform( psTransform->adfReverseGeoTransform, dfResultX, dfResultY, &dfX, &dfY ); int dX = int(dfX); int dY = int(dfY); double dfDEMH(0); double dfDeltaX = dfX - dX; double dfDeltaY = dfY - dY; if(psTransform->eResampleAlg == DRA_Cubic) { int dXNew = dX - 1; int dYNew = dY - 1; if (!(dXNew >= 0 && dYNew >= 0 && dXNew + 4 <= nRasterXSize && dYNew + 4 <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } //cubic interpolation int adElevData[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dXNew, dYNew, 4, 4, &adElevData, 4, 4, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } double dfSumH(0); for ( int i = 0; i < 5; i++ ) { // Loop across the X axis for ( int j = 0; j < 5; j++ ) { // Calculate the weight for the specified pixel according // to the bicubic b-spline kernel we're using for // interpolation int dKernIndX = j - 1; int dKernIndY = i - 1; double dfPixelWeight = BiCubicKernel(dKernIndX - dfDeltaX) * BiCubicKernel(dKernIndY - dfDeltaY); // Create a sum of all values // adjusted for the pixel's calculated weight dfSumH += adElevData[j + i * 4] * dfPixelWeight; } } dfDEMH = dfSumH; } else if(psTransform->eResampleAlg == DRA_Bilinear) { if (!(dX >= 0 && dY >= 0 && dX + 2 <= nRasterXSize && dY + 2 <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } //bilinear interpolation int adElevData[4] = {0,0,0,0}; CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 2, 2, &adElevData, 2, 2, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } double dfDeltaX1 = 1.0 - dfDeltaX; double dfDeltaY1 = 1.0 - dfDeltaY; double dfXZ1 = adElevData[0] * dfDeltaX1 + adElevData[1] * dfDeltaX; double dfXZ2 = adElevData[2] * dfDeltaX1 + adElevData[3] * dfDeltaX; double dfYZ = dfXZ1 * dfDeltaY1 + dfXZ2 * dfDeltaY; dfDEMH = dfYZ; } else { if (!(dX >= 0 && dY >= 0 && dX <= nRasterXSize && dY <= nRasterYSize)) { panSuccess[i] = FALSE; continue; } CPLErr eErr = psTransform->poDS->RasterIO(GF_Read, dX, dY, 1, 1, &dfDEMH, 1, 1, GDT_Int32, 1, bands, 0, 0, 0); if(eErr != CE_None) { panSuccess[i] = FALSE; continue; } } RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], padfZ[i] + (psTransform->dfHeightOffset + dfDEMH) * psTransform->dfHeightScale, &dfResultX, &dfResultY ); } else { RPCInverseTransformPoint( psTransform, padfX[i], padfY[i], padfZ[i] + psTransform->dfHeightOffset * psTransform->dfHeightScale, &dfResultX, &dfResultY ); } padfX[i] = dfResultX; padfY[i] = dfResultY; panSuccess[i] = TRUE; } return TRUE; }
static int GeoLocGenerateBackMap( GDALGeoLocTransformInfo *psTransform ) { int nXSize = psTransform->nGeoLocXSize; int nYSize = psTransform->nGeoLocYSize; int nMaxIter = 3; /* -------------------------------------------------------------------- */ /* Scan forward map for lat/long extents. */ /* -------------------------------------------------------------------- */ double dfMinX=0, dfMaxX=0, dfMinY=0, dfMaxY=0; int i, bInit = FALSE; for( i = nXSize * nYSize - 1; i >= 0; i-- ) { if( !psTransform->bHasNoData || psTransform->padfGeoLocX[i] != psTransform->dfNoDataX ) { if( bInit ) { dfMinX = MIN(dfMinX,psTransform->padfGeoLocX[i]); dfMaxX = MAX(dfMaxX,psTransform->padfGeoLocX[i]); dfMinY = MIN(dfMinY,psTransform->padfGeoLocY[i]); dfMaxY = MAX(dfMaxY,psTransform->padfGeoLocY[i]); } else { bInit = TRUE; dfMinX = dfMaxX = psTransform->padfGeoLocX[i]; dfMinY = dfMaxY = psTransform->padfGeoLocY[i]; } } } /* -------------------------------------------------------------------- */ /* Decide on resolution for backmap. We aim for slightly */ /* higher resolution than the source but we can't easily */ /* establish how much dead space there is in the backmap, so it */ /* is approximate. */ /* -------------------------------------------------------------------- */ double dfTargetPixels = (nXSize * nYSize * 1.3); double dfPixelSize = sqrt((dfMaxX - dfMinX) * (dfMaxY - dfMinY) / dfTargetPixels); int nBMXSize, nBMYSize; nBMYSize = psTransform->nBackMapHeight = (int) ((dfMaxY - dfMinY) / dfPixelSize + 1); nBMXSize= psTransform->nBackMapWidth = (int) ((dfMaxX - dfMinX) / dfPixelSize + 1); if (nBMXSize > INT_MAX / nBMYSize) { CPLError(CE_Failure, CPLE_AppDefined, "Int overflow : %d x %d", nBMXSize, nBMYSize); return FALSE; } dfMinX -= dfPixelSize/2.0; dfMaxY += dfPixelSize/2.0; psTransform->adfBackMapGeoTransform[0] = dfMinX; psTransform->adfBackMapGeoTransform[1] = dfPixelSize; psTransform->adfBackMapGeoTransform[2] = 0.0; psTransform->adfBackMapGeoTransform[3] = dfMaxY; psTransform->adfBackMapGeoTransform[4] = 0.0; psTransform->adfBackMapGeoTransform[5] = -dfPixelSize; /* -------------------------------------------------------------------- */ /* Allocate backmap, and initialize to nodata value (-1.0). */ /* -------------------------------------------------------------------- */ GByte *pabyValidFlag; pabyValidFlag = (GByte *) VSI_CALLOC_VERBOSE(nBMXSize, nBMYSize); psTransform->pafBackMapX = (float *) VSI_MALLOC3_VERBOSE(nBMXSize, nBMYSize, sizeof(float)); psTransform->pafBackMapY = (float *) VSI_MALLOC3_VERBOSE(nBMXSize, nBMYSize, sizeof(float)); if( pabyValidFlag == NULL || psTransform->pafBackMapX == NULL || psTransform->pafBackMapY == NULL ) { CPLFree( pabyValidFlag ); return FALSE; } for( i = nBMXSize * nBMYSize - 1; i >= 0; i-- ) { psTransform->pafBackMapX[i] = -1.0; psTransform->pafBackMapY[i] = -1.0; } /* -------------------------------------------------------------------- */ /* Run through the whole geoloc array forward projecting and */ /* pushing into the backmap. */ /* Initialize to the nMaxIter+1 value so we can spot genuinely */ /* valid pixels in the hole-filling loop. */ /* -------------------------------------------------------------------- */ int iBMX, iBMY; int iX, iY; for( iY = 0; iY < nYSize; iY++ ) { for( iX = 0; iX < nXSize; iX++ ) { if( psTransform->bHasNoData && psTransform->padfGeoLocX[iX + iY * nXSize] == psTransform->dfNoDataX ) continue; i = iX + iY * nXSize; iBMX = (int) ((psTransform->padfGeoLocX[i] - dfMinX) / dfPixelSize); iBMY = (int) ((dfMaxY - psTransform->padfGeoLocY[i]) / dfPixelSize); if( iBMX < 0 || iBMY < 0 || iBMX >= nBMXSize || iBMY >= nBMYSize ) continue; psTransform->pafBackMapX[iBMX + iBMY * nBMXSize] = (float)(iX * psTransform->dfPIXEL_STEP + psTransform->dfPIXEL_OFFSET); psTransform->pafBackMapY[iBMX + iBMY * nBMXSize] = (float)(iY * psTransform->dfLINE_STEP + psTransform->dfLINE_OFFSET); pabyValidFlag[iBMX + iBMY * nBMXSize] = (GByte) (nMaxIter+1); } } /* -------------------------------------------------------------------- */ /* Now, loop over the backmap trying to fill in holes with */ /* nearby values. */ /* -------------------------------------------------------------------- */ int iIter; int nNumValid; for( iIter = 0; iIter < nMaxIter; iIter++ ) { nNumValid = 0; for( iBMY = 0; iBMY < nBMYSize; iBMY++ ) { for( iBMX = 0; iBMX < nBMXSize; iBMX++ ) { // if this point is already set, ignore it. if( pabyValidFlag[iBMX + iBMY*nBMXSize] ) { nNumValid++; continue; } int nCount = 0; double dfXSum = 0.0, dfYSum = 0.0; int nMarkedAsGood = nMaxIter - iIter; // left? if( iBMX > 0 && pabyValidFlag[iBMX-1+iBMY*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX-1+iBMY*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX-1+iBMY*nBMXSize]; nCount++; } // right? if( iBMX + 1 < nBMXSize && pabyValidFlag[iBMX+1+iBMY*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX+1+iBMY*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX+1+iBMY*nBMXSize]; nCount++; } // top? if( iBMY > 0 && pabyValidFlag[iBMX+(iBMY-1)*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX+(iBMY-1)*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX+(iBMY-1)*nBMXSize]; nCount++; } // bottom? if( iBMY + 1 < nBMYSize && pabyValidFlag[iBMX+(iBMY+1)*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX+(iBMY+1)*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX+(iBMY+1)*nBMXSize]; nCount++; } // top-left? if( iBMX > 0 && iBMY > 0 && pabyValidFlag[iBMX-1+(iBMY-1)*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX-1+(iBMY-1)*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX-1+(iBMY-1)*nBMXSize]; nCount++; } // top-right? if( iBMX + 1 < nBMXSize && iBMY > 0 && pabyValidFlag[iBMX+1+(iBMY-1)*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX+1+(iBMY-1)*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX+1+(iBMY-1)*nBMXSize]; nCount++; } // bottom-left? if( iBMX > 0 && iBMY + 1 < nBMYSize && pabyValidFlag[iBMX-1+(iBMY+1)*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX-1+(iBMY+1)*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX-1+(iBMY+1)*nBMXSize]; nCount++; } // bottom-right? if( iBMX + 1 < nBMXSize && iBMY + 1 < nBMYSize && pabyValidFlag[iBMX+1+(iBMY+1)*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX+1+(iBMY+1)*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX+1+(iBMY+1)*nBMXSize]; nCount++; } if( nCount > 0 ) { psTransform->pafBackMapX[iBMX + iBMY * nBMXSize] = (float)(dfXSum/nCount); psTransform->pafBackMapY[iBMX + iBMY * nBMXSize] = (float)(dfYSum/nCount); // genuinely valid points will have value iMaxIter+1 // On each iteration mark newly valid points with a // descending value so that it will not be used on the // current iteration only on subsequent ones. pabyValidFlag[iBMX+iBMY*nBMXSize] = (GByte) (nMaxIter - iIter); } } } if (nNumValid == nBMXSize * nBMYSize) break; } #ifdef notdef GDALDatasetH hBMDS = GDALCreate( GDALGetDriverByName( "GTiff" ), "backmap.tif", nBMXSize, nBMYSize, 2, GDT_Float32, NULL ); GDALSetGeoTransform( hBMDS, psTransform->adfBackMapGeoTransform ); GDALRasterIO( GDALGetRasterBand(hBMDS,1), GF_Write, 0, 0, nBMXSize, nBMYSize, psTransform->pafBackMapX, nBMXSize, nBMYSize, GDT_Float32, 0, 0 ); GDALRasterIO( GDALGetRasterBand(hBMDS,2), GF_Write, 0, 0, nBMXSize, nBMYSize, psTransform->pafBackMapY, nBMXSize, nBMYSize, GDT_Float32, 0, 0 ); GDALClose( hBMDS ); #endif CPLFree( pabyValidFlag ); return TRUE; }
int main(int argc, const char * argv[]) { boost::filesystem::path p = boost::filesystem::current_path(); fprintf(stdout,"cwp := %s\n",p.c_str()); GDALAllRegister(); // for (int i = 0; i < GDALGetDriverCount(); i++) { // GDALDriver * d = (GDALDriver *)GDALGetDriver(i); // const char * desc = d->GetDescription(); // fprintf(stdout, "GDAL: %s\n",desc); // } GDALDataset *poDataset = (GDALDataset *) GDALOpen(DataPath.c_str(), GA_ReadOnly ); std::string SupportedDriver = {"GTiff"}; if (poDataset != NULL) { GDALDriver * drv = poDataset->GetDriver(); assert(0 == SupportedDriver.compare(drv->GetDescription())); assert (1 == poDataset->GetRasterCount()); fprintf(stdout,"RasterXSize := %d\n",poDataset->GetRasterXSize()); fprintf(stdout,"RasterYSize := %d\n",poDataset->GetRasterYSize()); fprintf(stdout,"ProjectionRef := %s\n",poDataset->GetProjectionRef()); double adfGeoTransform[6]; if ( poDataset->GetGeoTransform(adfGeoTransform) == CE_None ) { fprintf(stdout, "Origin = (%.6f, %.6f)\n", adfGeoTransform[0],adfGeoTransform[3]); // upper left courner fprintf(stdout, "Pixel Size = (%.6f, %.6f)\n", adfGeoTransform[1],adfGeoTransform[5]); // pixel width/height } GDALRasterBand *poBand = poDataset->GetRasterBand(1); int nBlockXSize, nBlockYSize; poBand->GetBlockSize(&nBlockXSize, &nBlockYSize); std::string SupportedDataType = {"Int16"}; assert (GDT_Int16 == poBand->GetRasterDataType()); printf( "Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName( poBand->GetColorInterpretation()) ); FILE * patch = fopen("patch.txt","w"); for (int i = 0; i < poBand->GetYSize(); i++) { int nXSize = poBand->GetXSize(); float *pafScanline = (float *) CPLMalloc(sizeof(float)*nXSize); poBand->RasterIO( GF_Read, 0, 0, nXSize, 1, pafScanline, nXSize, 1, GDT_Float32, 0, 0); for (int j = 0; j < nXSize; j++) { fprintf(patch, "%f ", pafScanline[j]); } fprintf(patch, "\n"); CPLFree(pafScanline); } fclose(patch); GDALClose(poDataset); } DelaunayTriangulation dt; //std::srand(static_cast<unsigned int>(std::time(0))); // use current time as seed for random generator /* std::srand(static_cast<unsigned int>(3652123216145)); for (int i = 0; i < 10 ; i++) { double x = 180.0 * static_cast <float> (rand()) / static_cast <float> (RAND_MAX);; double y = 180.0 * static_cast <float> (rand()) / static_cast <float> (RAND_MAX);; dt.addPt(x, y, 0.0); } */ /* dt.addPt(-0.02222276248244826, -0.4979727817680433, 0.0); dt.addPt(-0.4285431913366012, 0.4745826469497594, 0.0); dt.addPt( 0.3105396575392593, 0.2400179190933871, 0.0); dt.addPt(-0.01883958887200765, 0.3630260628303755, 0.0); dt.addPt( 0.3790312361708201, 0.3779794437605696, 0.0); dt.addPt(-0.2994955874043476, 0.3776609263174803, 0.0); dt.addPt( 0.3471817493878135, 0.08365533089605659, 0.0); dt.addPt(-0.00485819764887746, 0.3482682405489201, 0.0); dt.addPt( 0.3443122672329771, -0.1437312230875075, 0.0); dt.addPt( 0.309330780347186, -0.07758103877080702, 0.0); dt.compute(); */ return 0; }
GDALDataset *CALSDataset::CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int bStrict, char ** /* papszOptionsUnused */, GDALProgressFunc pfnProgress, void *pProgressData ) { if( poSrcDS->GetRasterCount() == 0 || (bStrict && poSrcDS->GetRasterCount() != 1) ) { CPLError( CE_Failure, CPLE_NotSupported, "CALS driver only supports single band raster."); return NULL; } if( poSrcDS->GetRasterBand(1)-> GetMetadataItem("NBITS", "IMAGE_STRUCTURE") == NULL || !EQUAL(poSrcDS->GetRasterBand(1)-> GetMetadataItem("NBITS", "IMAGE_STRUCTURE"), "1") ) { CPLError( bStrict ? CE_Failure : CE_Warning, CPLE_NotSupported, "CALS driver only supports 1-bit."); if( bStrict ) return NULL; } if( poSrcDS->GetRasterXSize() > 999999 || poSrcDS->GetRasterYSize() > 999999 ) { CPLError( CE_Failure, CPLE_NotSupported, "CALS driver only supports datasets with dimension <= 999999."); return NULL; } GDALDriver* poGTiffDrv = static_cast<GDALDriver *>(GDALGetDriverByName("GTiff")); if( poGTiffDrv == NULL ) { CPLError( CE_Failure, CPLE_NotSupported, "CALS driver needs GTiff driver." ); return NULL; } // Write a in-memory TIFF with just the TIFF header to figure out // how large it will be. CPLString osTmpFilename(CPLSPrintf("/vsimem/cals/tmp_%p", poSrcDS)); char** papszOptions = NULL; papszOptions = CSLSetNameValue(papszOptions, "COMPRESS", "CCITTFAX4"); papszOptions = CSLSetNameValue(papszOptions, "NBITS", "1"); papszOptions = CSLSetNameValue(papszOptions, "BLOCKYSIZE", CPLSPrintf("%d", poSrcDS->GetRasterYSize())); papszOptions = CSLSetNameValue(papszOptions, "SPARSE_OK", "YES"); GDALDataset* poDS = poGTiffDrv->Create(osTmpFilename, poSrcDS->GetRasterXSize(), poSrcDS->GetRasterYSize(), 1, GDT_Byte, papszOptions); if( poDS == NULL ) { // Should not happen normally (except if CCITTFAX4 not available). CSLDestroy(papszOptions); return NULL; } const char INITIAL_PADDING[] = "12345"; // To adjust padding. poDS->SetMetadataItem("TIFFTAG_DOCUMENTNAME", INITIAL_PADDING); GDALClose(poDS); VSIStatBufL sStat; if( VSIStatL(osTmpFilename, &sStat) != 0 ) { // Shoudln't happen really. Just to make Coverity happy. CSLDestroy(papszOptions); return NULL; } int nTIFFHeaderSize = static_cast<int>(sStat.st_size); VSIUnlink(osTmpFilename); // Redo the same thing, but this time write it to the output file // and use a variable TIFF tag (TIFFTAG_DOCUMENTNAME) to enlarge the // header + the variable TIFF tag so that they are 2048 bytes large. char szBuffer[2048+1] = {}; memset(szBuffer, 'X', 2048 - nTIFFHeaderSize + strlen(INITIAL_PADDING)); szBuffer[2048 - nTIFFHeaderSize + strlen(INITIAL_PADDING)] = 0; GDALDataset* poTmpDS = new CALSWrapperSrcDataset(poSrcDS, szBuffer); poDS = poGTiffDrv->CreateCopy(pszFilename, poTmpDS, FALSE, papszOptions, pfnProgress, pProgressData ); delete poTmpDS; CSLDestroy(papszOptions); if( poDS == NULL ) return NULL; delete poDS; // Now replace the TIFF header by the CALS header. VSILFILE* fp = VSIFOpenL(pszFilename, "rb+"); if( fp == NULL ) return NULL; // Shoudln't happen normally. memset(szBuffer, ' ', 2048); CPLString osField; osField = "srcdocid: NONE"; memcpy(szBuffer, osField, osField.size()); osField = "dstdocid: NONE"; memcpy(szBuffer + 128, osField, osField.size()); osField = "txtfilid: NONE"; memcpy(szBuffer + 128*2, osField, osField.size()); osField = "figid: NONE"; memcpy(szBuffer + 128*3, osField, osField.size()); osField = "srcgph: NONE"; memcpy(szBuffer + 128*4, osField, osField.size()); osField = "doccls: NONE"; memcpy(szBuffer + 128*5, osField, osField.size()); osField = "rtype: 1"; memcpy(szBuffer + 128*6, osField, osField.size()); int nAngle1 = 0; int nAngle2 = 270; const char* pszPixelPath = poSrcDS->GetMetadataItem("PIXEL_PATH"); const char* pszLineProgression = poSrcDS->GetMetadataItem("LINE_PROGRESSION"); if( pszPixelPath && pszLineProgression ) { nAngle1 = atoi(pszPixelPath); nAngle2 = atoi(pszLineProgression); } osField = CPLSPrintf("rorient: %03d,%03d", nAngle1, nAngle2); memcpy(szBuffer + 128*7, osField, osField.size()); osField = CPLSPrintf("rpelcnt: %06d,%06d", poSrcDS->GetRasterXSize(), poSrcDS->GetRasterYSize()); memcpy(szBuffer + 128*8, osField, osField.size()); int nDensity = 200; const char* pszXRes = poSrcDS->GetMetadataItem("TIFFTAG_XRESOLUTION"); const char* pszYRes = poSrcDS->GetMetadataItem("TIFFTAG_YRESOLUTION"); const char* pszResUnit = poSrcDS->GetMetadataItem("TIFFTAG_RESOLUTIONUNIT"); if( pszXRes && pszYRes && pszResUnit && EQUAL(pszXRes, pszYRes) && atoi(pszResUnit) == 2 ) { nDensity = atoi(pszXRes); if( nDensity < 1 || nDensity > 9999 ) nDensity = 200; } osField = CPLSPrintf("rdensty: %04d", nDensity); memcpy(szBuffer + 128*9, osField, osField.size()); osField = "notes: NONE"; memcpy(szBuffer + 128*10, osField, osField.size()); VSIFWriteL(szBuffer, 1, 2048, fp); VSIFCloseL(fp); GDALOpenInfo oOpenInfo(pszFilename, GA_ReadOnly, NULL); return Open(&oOpenInfo); }
SEXP ogrListLayers (SEXP ogrSource) { #ifdef GDALV2 GDALDataset *poDS; GDALDriver *poDriver; #else OGRDataSource *poDS; OGRSFDriver *poDriver; #endif OGRLayer *poLayer; int i, nlayers; SEXP ans, debug; int pc=0; installErrorHandler(); #ifdef GDALV2 poDS=(GDALDataset*) GDALOpenEx(CHAR(STRING_ELT(ogrSource, 0)), GDAL_OF_VECTOR, NULL, NULL, NULL); if(poDS==NULL) { uninstallErrorHandlerAndTriggerError(); error("Cannot open data source"); } poDriver = poDS->GetDriver(); #else poDS=OGRSFDriverRegistrar::Open(CHAR(STRING_ELT(ogrSource, 0)), FALSE, &poDriver); #endif uninstallErrorHandlerAndTriggerError(); if(poDS==NULL) { error("Cannot open data source"); } debug = getAttrib(ogrSource, mkString("debug")); installErrorHandler(); nlayers = poDS->GetLayerCount(); uninstallErrorHandlerAndTriggerError(); if (LOGICAL_POINTER(debug)[0] == TRUE) Rprintf("ogrListLayers: nlayers %d\n", nlayers); PROTECT(ans=NEW_CHARACTER(nlayers+1)); pc++; for (i=0; i<nlayers; i++) { installErrorHandler(); poLayer = poDS->GetLayer(i); if(poLayer == NULL) { if (LOGICAL_POINTER(debug)[0] == TRUE) { SET_STRING_ELT(ans, i, mkChar("")); Rprintf("ogrListLayers: NULL layer %d\n", i); } else { uninstallErrorHandlerAndTriggerError(); error("Cannot open layer"); } } else { SET_STRING_ELT(ans, i, mkChar(poLayer->GetLayerDefn()->GetName())); } uninstallErrorHandlerAndTriggerError(); } installErrorHandler(); #ifdef GDALV2 SET_STRING_ELT(ans, nlayers, mkChar(poDriver->GetDescription())); #else SET_STRING_ELT(ans, nlayers, mkChar(poDriver->GetName())); #endif uninstallErrorHandlerAndTriggerError(); installErrorHandler(); #ifdef GDALV2 GDALClose( poDS ); #else OGRDataSource::DestroyDataSource( poDS ); #endif uninstallErrorHandlerAndTriggerError(); UNPROTECT(pc); return(ans); }
int equalize_density(char *infile, char *outfile, int fast, int accurate) { int xsize, ysize; // Size of the density grid. double *gridx, *gridy; // Array for grid double **rho; // Initial population density GDALDatasetH hDataset; // The input density raster file. GDALRasterBandH hBand; // The raster band we are going to use. FILE *outfp; // The morphing file (a text file). double adfGeoTransform[6]; // For the georeference of the raster. // Register all GDAL drivers. GDALAllRegister(); #if defined (_OPENMP) omp_set_num_threads(omp_get_num_procs()); #endif hDataset = GDALOpen(infile, GA_ReadOnly); if (hDataset == NULL) { fprintf(stderr,"Error. Unable to open file `%s'\n", infile); exit(1); } outfp = fopen(outfile, "w"); if (outfp == NULL) { fprintf(stderr,"Error. Unable to open file `%s'\n", outfile); exit(1); } // Get the raster band for the dataset; we are using the first band. hBand = GDALGetRasterBand(hDataset, 1); if (hBand == NULL) { fprintf(stderr, "Error. Unable to read band 1 in file `%s'\n", infile); exit(1); } // Determine the raster size xsize = GDALGetRasterBandXSize(hBand); ysize = GDALGetRasterBandYSize(hBand); // Allocate space for the cartogram code to use cart_makews(xsize, ysize); // Read in the population data, transform it, then destroy it again rho = cart_dmalloc(xsize, ysize); if (readpop(hBand, rho, xsize, ysize)) { fprintf(stderr,"Error. Density file contains too few or incorrect data\n"); exit(1); } cart_transform(rho, xsize, ysize); cart_dfree(rho); // Create the grid of points gridx = malloc((xsize+1)*(ysize+1)*sizeof(double)); gridy = malloc((xsize+1)*(ysize+1)*sizeof(double)); creategrid(gridx, gridy, xsize, ysize); // Compute the cartogram cart_makecart(gridx, gridy, (xsize+1)*(ysize+1), xsize, ysize, 0.0); // Write out the final positions of the grid points GDALGetGeoTransform(hDataset, adfGeoTransform); writepoints(outfp, gridx, gridy, xsize, ysize, adfGeoTransform); //writepoints(outfp, gridx, gridy, (xsize+1)*(ysize+1)); // Free up the allocated memory cart_freews(xsize, ysize); free(gridx); free(gridy); // Close the input and output files GDALClose(hDataset); fclose(outfp); return 0; }
//extern "C" { SEXP ogrFIDs(SEXP filename, SEXP layer) { SEXP fids, nf, ii; int /*layerNum,*/i; int nFeatures, pc=0; OGRLayer *poLayer; OGRFeature *poFeature; #ifdef GDALV2 GDALDataset *poDS; #else OGRDataSource *poDS; OGRSFDriver *poDriver; #endif installErrorHandler(); #ifdef GDALV2 poDS=(GDALDataset*) GDALOpenEx(CHAR(STRING_ELT(filename, 0)), GDAL_OF_VECTOR, NULL, NULL, NULL); #else poDS=OGRSFDriverRegistrar::Open(CHAR(STRING_ELT(filename, 0)), FALSE, &poDriver); #endif uninstallErrorHandlerAndTriggerError(); if(poDS==NULL) { error("Cannot open file"); } installErrorHandler(); poLayer = poDS->GetLayerByName(CHAR(STRING_ELT(layer, 0))); uninstallErrorHandlerAndTriggerError(); if(poLayer == NULL) { error("Cannot open layer"); } installErrorHandler(); #ifdef GDALV2 GIntBig nFIDs64 = poLayer->GetFeatureCount(); nFeatures = (nFIDs64 > INT_MAX) ? INT_MAX : (nFIDs64 < INT_MIN) ? INT_MIN : (int) nFIDs64; if ((GIntBig) nFeatures != nFIDs64) { uninstallErrorHandlerAndTriggerError(); error("ogrFIDs: feature count overflow"); } #else nFeatures=poLayer->GetFeatureCount(); #endif uninstallErrorHandlerAndTriggerError(); if (nFeatures == -1) { i=0; installErrorHandler(); while( ((poFeature = poLayer->GetNextFeature()) != NULL) && i <= INT_MAX) { i++; OGRFeature::DestroyFeature( poFeature ); // delete poFeature; } uninstallErrorHandlerAndTriggerError(); installErrorHandler(); poLayer->ResetReading(); uninstallErrorHandlerAndTriggerError(); if (i == INT_MAX) { error("ogrFIDs: feature count overflow"); } else { nFeatures = i; } } PROTECT(fids=allocVector(INTSXP,nFeatures)); pc++; PROTECT(nf = NEW_INTEGER(1)); pc++; INTEGER_POINTER(nf)[0] = nFeatures; PROTECT(ii = NEW_INTEGER(1)); pc++; installErrorHandler(); poLayer->ResetReading(); uninstallErrorHandlerAndTriggerError(); i=0; installErrorHandler(); while( (poFeature = poLayer->GetNextFeature()) != NULL ) { INTEGER(fids)[i]= (int) poFeature->GetFID(); i++; OGRFeature::DestroyFeature( poFeature ); // delete poFeature; } uninstallErrorHandlerAndTriggerError(); INTEGER_POINTER(ii)[0] = i; setAttrib(fids, install("nf"), nf); setAttrib(fids, install("i"), ii); installErrorHandler(); #ifdef GDALV2 GDALClose( poDS ); #else OGRDataSource::DestroyDataSource( poDS ); #endif uninstallErrorHandlerAndTriggerError(); // delete poDS; UNPROTECT(pc); return(fids); }
int NBHeightMapper::loadShapeFile(const std::string& file) { #ifdef HAVE_GDAL #if GDAL_VERSION_MAJOR < 2 OGRRegisterAll(); OGRDataSource* ds = OGRSFDriverRegistrar::Open(file.c_str(), FALSE); #else GDALAllRegister(); GDALDataset* ds = (GDALDataset*)GDALOpenEx(file.c_str(), GDAL_OF_VECTOR | GA_ReadOnly, NULL, NULL, NULL); #endif if (ds == NULL) { throw ProcessError("Could not open shape file '" + file + "'."); } // begin file parsing OGRLayer* layer = ds->GetLayer(0); layer->ResetReading(); // triangle coordinates are stored in WGS84 and later matched with network coordinates in WGS84 // build coordinate transformation OGRSpatialReference* sr_src = layer->GetSpatialRef(); OGRSpatialReference sr_dest; sr_dest.SetWellKnownGeogCS("WGS84"); OGRCoordinateTransformation* toWGS84 = OGRCreateCoordinateTransformation(sr_src, &sr_dest); if (toWGS84 == 0) { WRITE_WARNING("Could not create geocoordinates converter; check whether proj.4 is installed."); } int numFeatures = 0; OGRFeature* feature; layer->ResetReading(); while ((feature = layer->GetNextFeature()) != NULL) { OGRGeometry* geom = feature->GetGeometryRef(); assert(geom != 0); // @todo gracefull handling of shapefiles with unexpected contents or any error handling for that matter assert(std::string(geom->getGeometryName()) == std::string("POLYGON")); // try transform to wgs84 geom->transform(toWGS84); OGRLinearRing* cgeom = ((OGRPolygon*) geom)->getExteriorRing(); // assume TIN with with 4 points and point0 == point3 assert(cgeom->getNumPoints() == 4); PositionVector corners; for (int j = 0; j < 3; j++) { Position pos((double) cgeom->getX(j), (double) cgeom->getY(j), (double) cgeom->getZ(j)); corners.push_back(pos); myBoundary.add(pos); } addTriangle(corners); numFeatures++; /* OGRwkbGeometryType gtype = geom->getGeometryType(); switch (gtype) { case wkbPolygon: { break; } case wkbPoint: { WRITE_WARNING("got wkbPoint"); break; } case wkbLineString: { WRITE_WARNING("got wkbLineString"); break; } case wkbMultiPoint: { WRITE_WARNING("got wkbMultiPoint"); break; } case wkbMultiLineString: { WRITE_WARNING("got wkbMultiLineString"); break; } case wkbMultiPolygon: { WRITE_WARNING("got wkbMultiPolygon"); break; } default: WRITE_WARNING("Unsupported shape type occurred"); break; } */ OGRFeature::DestroyFeature(feature); } #if GDAL_VERSION_MAJOR < 2 OGRDataSource::DestroyDataSource(ds); #else GDALClose(ds); #endif OCTDestroyCoordinateTransformation(toWGS84); OGRCleanupAll(); return numFeatures; #else UNUSED_PARAMETER(file); WRITE_ERROR("Cannot load shape file since SUMO was compiled without GDAL support."); return 0; #endif }
// extern "C" { SEXP ogrInfo(SEXP ogrsourcename, SEXP Layer) { // return FIDs, nFields, fieldInfo SEXP ans, vec1, vec2, vec3,/*mat,*/drv, dvec; SEXP itemlist, itemnames, itemwidth, itemtype, itemTypeNames; SEXP itemlistmaxcount; #ifdef GDALV2 SEXP dFIDs; #endif /*SEXP geotype;*/ int nFIDs, nFields, iField, *nCount, pc=0; #ifdef GDALV2 GDALDriver *poDriver; GDALDataset *poDS; #else OGRDataSource *poDS; OGRSFDriver *poDriver; #endif OGRLayer *poLayer; OGRFeature *poFeature; OGRFeatureDefn *poDefn; /* OGRGeometry *poGeom;*/ installErrorHandler(); #ifdef GDALV2 poDS=(GDALDataset*) GDALOpenEx(CHAR(STRING_ELT(ogrsourcename, 0)), GDAL_OF_VECTOR, NULL, NULL, NULL); if(poDS==NULL) { uninstallErrorHandlerAndTriggerError(); error("Cannot open data source"); } poDriver = poDS->GetDriver(); #else poDS=OGRSFDriverRegistrar::Open(CHAR(STRING_ELT(ogrsourcename, 0)), FALSE, &poDriver); #endif uninstallErrorHandlerAndTriggerError(); if(poDS==NULL) { installErrorHandler(); #ifdef GDALV2 GDALClose( poDS ); #else OGRDataSource::DestroyDataSource( poDS ); #endif uninstallErrorHandlerAndTriggerError(); // delete poDS; error("Cannot open file"); } installErrorHandler(); poLayer = poDS->GetLayerByName(CHAR(STRING_ELT(Layer, 0))); uninstallErrorHandlerAndTriggerError(); if(poLayer == NULL) { installErrorHandler(); #ifdef GDALV2 GDALClose( poDS ); #else OGRDataSource::DestroyDataSource( poDS ); #endif uninstallErrorHandlerAndTriggerError(); // delete poDS; error("Cannot open layer"); } // allocate a list for return values PROTECT(ans=allocVector(VECSXP,6)); pc++; PROTECT(drv=allocVector(STRSXP,1)); pc++; installErrorHandler(); #ifdef GDALV2 SET_STRING_ELT(drv, 0, mkChar(poDriver->GetDescription())); #else SET_STRING_ELT(drv, 0, mkChar(poDriver->GetName())); #endif uninstallErrorHandlerAndTriggerError(); SET_VECTOR_ELT(ans,3,drv); PROTECT(vec1=allocVector(INTSXP,1)); pc++; installErrorHandler(); #ifdef GDALV2 GIntBig nFIDs64 = poLayer->GetFeatureCount(); nFIDs = (nFIDs64 > INT_MAX) ? INT_MAX : (nFIDs64 < INT_MIN) ? INT_MIN : (int) nFIDs64; if ((GIntBig) nFIDs != nFIDs64) { warning("ogrInfo: feature count overflow"); INTEGER(vec1)[0]=NA_INTEGER; PROTECT(dFIDs=NEW_NUMERIC(1)); pc++; NUMERIC_POINTER(dFIDs)[0] = (double) nFIDs64; setAttrib(vec1, install("dFIDs"), dFIDs); } else { // store number of FIDs INTEGER(vec1)[0]=nFIDs; } #else nFIDs = poLayer->GetFeatureCount(); // store number of FIDs INTEGER(vec1)[0]=nFIDs; #endif uninstallErrorHandlerAndTriggerError(); if (nFIDs == -1) { int i=0; installErrorHandler(); while( ((poFeature = poLayer->GetNextFeature()) != NULL) && i <= INT_MAX) { i++; OGRFeature::DestroyFeature( poFeature ); // delete poFeature; } uninstallErrorHandlerAndTriggerError(); if (i == INT_MAX) { error("ogrInfo: undeclared feature count overflow"); } else { nFIDs = i; warning("ogrInfo: feature count not given; %d counted", nFIDs); } installErrorHandler(); poLayer->ResetReading(); uninstallErrorHandlerAndTriggerError(); INTEGER(vec1)[0]=nFIDs; } SET_VECTOR_ELT(ans,0,vec1); // store other stuff.... installErrorHandler(); poDefn = poLayer->GetLayerDefn(); nFields = poDefn->GetFieldCount(); uninstallErrorHandlerAndTriggerError(); // store number of fields PROTECT(vec2=allocVector(INTSXP,1)); pc++; INTEGER(vec2)[0]=nFields; SET_VECTOR_ELT(ans,1,vec2); installErrorHandler(); OGREnvelope oExt; if (poLayer->GetExtent(&oExt, TRUE) == OGRERR_NONE) { PROTECT(dvec=allocVector(REALSXP,4)); pc++; REAL(dvec)[0] = oExt.MinX; REAL(dvec)[1] = oExt.MinY; REAL(dvec)[2] = oExt.MaxX; REAL(dvec)[3] = oExt.MaxY; SET_VECTOR_ELT(ans,4,dvec); } uninstallErrorHandlerAndTriggerError(); PROTECT(itemnames=allocVector(STRSXP,nFields)); pc++; PROTECT(itemtype=allocVector(INTSXP,nFields)); pc++; PROTECT(itemwidth=allocVector(INTSXP,nFields)); pc++; // try List types PROTECT(itemlistmaxcount=allocVector(INTSXP,nFields)); pc++; PROTECT(itemTypeNames=allocVector(STRSXP,nFields)); pc++; int listFieldCount=0; installErrorHandler(); for(iField=0; iField<nFields; iField++) { OGRFieldDefn *poField = poDefn->GetFieldDefn(iField); SET_STRING_ELT(itemnames,iField,mkChar(poField->GetNameRef())); INTEGER(itemtype)[iField]=poField->GetType(); if (INTEGER(itemtype)[iField] == OFTIntegerList || INTEGER(itemtype)[iField] == OFTRealList || INTEGER(itemtype)[iField] == OFTStringList) listFieldCount++; INTEGER(itemwidth)[iField]=poField->GetWidth(); SET_STRING_ELT(itemTypeNames,iField,mkChar(poField->GetFieldTypeName( poField->GetType()))); INTEGER(itemlistmaxcount)[iField] = 0; } uninstallErrorHandlerAndTriggerError(); PROTECT(vec3=allocVector(INTSXP,1)); pc++; INTEGER(vec3)[0]=listFieldCount; SET_VECTOR_ELT(ans,5,vec3); PROTECT(itemlist=allocVector(VECSXP,5)); pc++; SET_VECTOR_ELT(itemlist,0,itemnames); SET_VECTOR_ELT(itemlist,1,itemtype); SET_VECTOR_ELT(itemlist,2,itemwidth); SET_VECTOR_ELT(itemlist,3,itemTypeNames); // try List types if (listFieldCount > 0) { poLayer->ResetReading(); OGRFeature* poFeature; nCount = (int *) R_alloc((size_t) nFields, sizeof(int)); for (iField=0; iField<nFields; iField++) nCount[iField] = 0; installErrorHandler(); OGRField* psField; while( (poFeature = poLayer->GetNextFeature()) != NULL ) { for(iField=0; iField<nFields; iField++) { psField = poFeature->GetRawFieldRef(iField); if (INTEGER(itemtype)[iField] == OFTIntegerList) { nCount[iField] = psField->IntegerList.nCount; if (nCount[iField] > INTEGER(itemlistmaxcount)[iField]) INTEGER(itemlistmaxcount)[iField] = nCount[iField]; } else if (INTEGER(itemtype)[iField] == OFTRealList) { nCount[iField] = psField->RealList.nCount; if (nCount[iField] > INTEGER(itemlistmaxcount)[iField]) INTEGER(itemlistmaxcount)[iField] = nCount[iField]; } else if (INTEGER(itemtype)[iField] == OFTStringList) { nCount[iField] = psField->StringList.nCount; if (nCount[iField] > INTEGER(itemlistmaxcount)[iField]) INTEGER(itemlistmaxcount)[iField] = nCount[iField]; } } OGRFeature::DestroyFeature( poFeature ); // delete poFeature; } uninstallErrorHandlerAndTriggerError(); } SET_VECTOR_ELT(itemlist,4,itemlistmaxcount); SET_VECTOR_ELT(ans,2,itemlist); UNPROTECT(pc); installErrorHandler(); #ifdef GDALV2 GDALClose( poDS ); #else OGRDataSource::DestroyDataSource( poDS ); #endif uninstallErrorHandlerAndTriggerError(); // delete poDS; return(ans); }
int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) { VSILFILE* fp = VSIFileFromMemBuffer( "/vsimem/test.tar", reinterpret_cast<GByte*>(const_cast<uint8_t*>(buf)), len, FALSE ); VSIFCloseL(fp); CPLPushErrorHandler(CPLQuietErrorHandler); char** papszArgv = nullptr; // Prevent generating too big output raster. Make sure they are set at // the beginning to avoid being accidentally eaten by invalid arguments // afterwards. papszArgv = CSLAddString(papszArgv, "-limit_outsize"); papszArgv = CSLAddString(papszArgv, "1000000"); fp = VSIFOpenL("/vsitar//vsimem/test.tar/cmd.txt", "rb"); if( fp != nullptr ) { const char* pszLine = nullptr; while( (pszLine = CPLReadLineL(fp)) != nullptr ) { if( !EQUAL(pszLine, "-limit_outsize") ) papszArgv = CSLAddString(papszArgv, pszLine); } VSIFCloseL(fp); } int nXDim = -1; int nYDim = -1; bool bXDimPct = false; bool bYDimPct = false; bool bNonNearestResampling = false; int nBlockXSize = 0; int nBlockYSize = 0; bool bStatsEnabled = false; bool bHFA = false; if( papszArgv != nullptr ) { int nCount = CSLCount(papszArgv); for( int i = 0; i < nCount; i++ ) { if( EQUAL(papszArgv[i], "-outsize") && i + 2 < nCount ) { nXDim = atoi(papszArgv[i+1]); bXDimPct = (papszArgv[i+1][0] != '\0' && papszArgv[i+1][strlen(papszArgv[i+1])-1] == '%'); nYDim = atoi(papszArgv[i+2]); bYDimPct = (papszArgv[i+2][0] != '\0' && papszArgv[i+2][strlen(papszArgv[i+2])-1] == '%'); } else if( EQUAL(papszArgv[i], "-r") && i + 1 < nCount ) { bNonNearestResampling = !STARTS_WITH_CI(papszArgv[i+1], "NEAR"); } else if( EQUAL(papszArgv[i], "-co") && i + 1 < nCount ) { if( STARTS_WITH_CI(papszArgv[i+1], "BLOCKSIZE=") ) { nBlockXSize = std::max(nBlockXSize, atoi(papszArgv[i+1]+strlen("BLOCKSIZE="))); nBlockYSize = std::max(nBlockYSize, atoi(papszArgv[i+1]+strlen("BLOCKSIZE="))); } else if( STARTS_WITH_CI(papszArgv[i+1], "BLOCKXSIZE=") ) { nBlockXSize = std::max(nBlockXSize, atoi(papszArgv[i+1]+strlen("BLOCKXSIZE="))); } else if( STARTS_WITH_CI(papszArgv[i+1], "BLOCKYSIZE=") ) { nBlockYSize = std::max(nBlockYSize, atoi(papszArgv[i+1]+strlen("BLOCKYSIZE="))); } } else if( EQUAL(papszArgv[i], "-stats") ) { bStatsEnabled = true; } else if( EQUAL(papszArgv[i], "-of") && i + 1 < nCount ) { bHFA = EQUAL( papszArgv[i+1], "HFA" ); } } if( bHFA ) { // Disable statistics computation for HFA, as it can be time // consuming. // See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10067 papszArgv = CSLInsertString(papszArgv, 0, "-co"); papszArgv = CSLInsertString(papszArgv, 1, "STATISTICS=NO"); } } if( papszArgv != nullptr ) { GDALTranslateOptions* psOptions = GDALTranslateOptionsNew(papszArgv, nullptr); if( psOptions ) { GDALDatasetH hSrcDS = GDALOpen( "/vsitar//vsimem/test.tar/in", GA_ReadOnly ); if( hSrcDS != nullptr ) { // Also check that reading the source doesn't involve too // much memory GDALDataset* poSrcDS = reinterpret_cast<GDALDataset*>(hSrcDS); int nBands = poSrcDS->GetRasterCount(); if( nBands < 10 ) { // Prevent excessive downsampling which might require huge // memory allocation bool bOKForResampling = true; if( bNonNearestResampling && nXDim >= 0 && nYDim >= 0 ) { if( bXDimPct && nXDim > 0 ) { nXDim = static_cast<int>( poSrcDS->GetRasterXSize() / 100.0 * nXDim); } if( bYDimPct && nYDim > 0 ) { nYDim = static_cast<int>( poSrcDS->GetRasterYSize() / 100.0 * nYDim); } if( nXDim > 0 && poSrcDS->GetRasterXSize() / nXDim > 100 ) bOKForResampling = false; if( nYDim > 0 && poSrcDS->GetRasterYSize() / nYDim > 100 ) bOKForResampling = false; } bool bOKForSrc = true; if( nBands ) { const int nDTSize = GDALGetDataTypeSizeBytes( poSrcDS->GetRasterBand(1)->GetRasterDataType() ); vsi_l_offset nSize = static_cast<vsi_l_offset>(nBands) * poSrcDS->GetRasterXSize() * poSrcDS->GetRasterYSize() * nDTSize; if( nSize > 10 * 1024 * 1024 ) { bOKForSrc = false; } int nBXSize = 0, nBYSize = 0; GDALGetBlockSize( GDALGetRasterBand(hSrcDS, 1), &nBXSize, &nBYSize ); const char* pszInterleave = GDALGetMetadataItem( hSrcDS, "INTERLEAVE", "IMAGE_STRUCTURE" ); int nSimultaneousBands = (pszInterleave && EQUAL(pszInterleave, "PIXEL")) ? nBands : 1; if( static_cast<GIntBig>(nSimultaneousBands)* nBXSize * nBYSize * nDTSize > 10 * 1024 * 1024 ) { bOKForSrc = false; } if( static_cast<GIntBig>(nBlockXSize) * nBlockYSize > 10 * 1024 * 1024 / (nBands * nDTSize) ) { bOKForSrc = false; } } bool bOKForStats = true; if( nBands && bStatsEnabled ) { // Other types might be too slow with sanitization enabled // See https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10029 bOKForStats = poSrcDS->GetRasterBand(1)->GetRasterDataType() == GDT_Byte; } if( bOKForSrc && bOKForResampling && bOKForStats ) { GDALDatasetH hOutDS = GDALTranslate("/vsimem/out", hSrcDS, psOptions, nullptr); if( hOutDS ) GDALClose(hOutDS); } } GDALClose(hSrcDS); } GDALTranslateOptionsFree(psOptions); } } CSLDestroy(papszArgv); VSIRmdirRecursive("/vsimem/"); CPLPopErrorHandler(); return 0; }
// extern "C" { SEXP ogrDataFrame(SEXP ogrSource, SEXP Layer, SEXP FIDs, SEXP iFields) { // query an OGR data source and return a list SEXP ans; SEXP nListFields, ListFields=R_NilValue, int64; OGRLayer *poLayer; #ifdef GDALV2 GDALDataset *poDS; #else OGRDataSource *poDS; OGRSFDriver *poDriver; #endif int iField, nflds=length(iFields), j=0, k; int pc=0; // open the data source layer or error installErrorHandler(); #ifdef GDALV2 poDS=(GDALDataset*) GDALOpenEx(CHAR(STRING_ELT(ogrSource, 0)), GDAL_OF_VECTOR, NULL, NULL, NULL); #else poDS=OGRSFDriverRegistrar::Open(CHAR(STRING_ELT(ogrSource,0)), FALSE, &poDriver); #endif uninstallErrorHandlerAndTriggerError(); if(poDS==NULL) { error("Cannot open file"); } installErrorHandler(); poLayer = poDS->GetLayerByName(CHAR(STRING_ELT(Layer, 0))); uninstallErrorHandlerAndTriggerError(); if(poLayer == NULL) { error("Cannot open layer"); } int64 = getAttrib(iFields, mkString("int64")); nListFields = getAttrib(iFields, mkString("nListFields")); SEXP ENC_attr = getAttrib(iFields, mkString("ENCODING_DEBUG")); int ENC_DEBUG = LOGICAL_POINTER(ENC_attr)[0]; // reserve a list for the result if (INTEGER_POINTER(nListFields)[0] == 0) { PROTECT(ans=allocVector(VECSXP,length(iFields))); pc++; } else { nflds = INTEGER_POINTER(getAttrib(iFields, mkString("nflds")))[0]; PROTECT(ans=allocVector(VECSXP,nflds)); pc++; ListFields = getAttrib(iFields, mkString("ListFields")); } // now set each element of the list installErrorHandler(); if (INTEGER_POINTER(nListFields)[0] == 0) { for(iField=0; iField<length(iFields); iField++) { SET_VECTOR_ELT(ans,iField,ogrReadColumn(poLayer, FIDs, INTEGER(iFields)[iField], INTEGER(int64)[0], ENC_DEBUG)); } } else { j=0; for(iField=0; iField<length(iFields); iField++) { if (INTEGER_POINTER(ListFields)[iField] == 0) { SET_VECTOR_ELT(ans, j, ogrReadColumn(poLayer, FIDs, INTEGER(iFields)[iField], INTEGER(int64)[0], ENC_DEBUG)); j++; } else { for (k=0; k < INTEGER_POINTER(ListFields)[iField]; k++) { SET_VECTOR_ELT(ans, j, ogrReadListColumn(poLayer, FIDs, INTEGER(iFields)[iField], k, INTEGER(int64)[0])); j++; } } } } uninstallErrorHandlerAndTriggerError(); // clean up and return installErrorHandler(); #ifdef GDALV2 GDALClose( poDS ); #else OGRDataSource::DestroyDataSource( poDS ); #endif // delete poDS; uninstallErrorHandlerAndTriggerError(); UNPROTECT(pc); return(ans); }
CPLErr GDALWMSRasterBand::ReadBlockFromFile(int x, int y, const char *file_name, int to_buffer_band, void *buffer, int advise_read) { CPLErr ret = CE_None; GDALDataset *ds = 0; GByte *color_table = NULL; int i; //CPLDebug("WMS", "ReadBlockFromFile: to_buffer_band=%d, (x,y)=(%d, %d)", to_buffer_band, x, y); /* expected size */ const int esx = MIN(MAX(0, (x + 1) * nBlockXSize), nRasterXSize) - MIN(MAX(0, x * nBlockXSize), nRasterXSize); const int esy = MIN(MAX(0, (y + 1) * nBlockYSize), nRasterYSize) - MIN(MAX(0, y * nBlockYSize), nRasterYSize); ds = reinterpret_cast<GDALDataset*>(GDALOpen(file_name, GA_ReadOnly)); if (ds != NULL) { int sx = ds->GetRasterXSize(); int sy = ds->GetRasterYSize(); bool accepted_as_no_alpha = false; // if the request is for 4 bands but the wms returns 3 /* Allow bigger than expected so pre-tiled constant size images work on corners */ if ((sx > nBlockXSize) || (sy > nBlockYSize) || (sx < esx) || (sy < esy)) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Incorrect size %d x %d of downloaded block, expected %d x %d, max %d x %d.", sx, sy, esx, esy, nBlockXSize, nBlockYSize); ret = CE_Failure; } if (ret == CE_None) { int nDSRasterCount = ds->GetRasterCount(); if (nDSRasterCount != m_parent_dataset->nBands) { /* Maybe its an image with color table */ bool accepted_as_ct = false; if ((eDataType == GDT_Byte) && (ds->GetRasterCount() == 1)) { GDALRasterBand *rb = ds->GetRasterBand(1); if (rb->GetRasterDataType() == GDT_Byte) { GDALColorTable *ct = rb->GetColorTable(); if (ct != NULL) { accepted_as_ct = true; if (!advise_read) { color_table = new GByte[256 * 4]; const int count = MIN(256, ct->GetColorEntryCount()); for (i = 0; i < count; ++i) { GDALColorEntry ce; ct->GetColorEntryAsRGB(i, &ce); color_table[i] = static_cast<GByte>(ce.c1); color_table[i + 256] = static_cast<GByte>(ce.c2); color_table[i + 512] = static_cast<GByte>(ce.c3); color_table[i + 768] = static_cast<GByte>(ce.c4); } for (i = count; i < 256; ++i) { color_table[i] = 0; color_table[i + 256] = 0; color_table[i + 512] = 0; color_table[i + 768] = 0; } } } } } if (nDSRasterCount == 4 && m_parent_dataset->nBands == 3) { /* metacarta TMS service sometimes return a 4 band PNG instead of the expected 3 band... */ } else if (!accepted_as_ct) { if (ds->GetRasterCount()==3 && m_parent_dataset->nBands == 4 && (eDataType == GDT_Byte)) { // WMS returned a file with no alpha so we will fill the alpha band with "opaque" accepted_as_no_alpha = true; } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Incorrect bands count %d in downloaded block, expected %d.", nDSRasterCount, m_parent_dataset->nBands); ret = CE_Failure; } } } } if (!advise_read) { for (int ib = 1; ib <= m_parent_dataset->nBands; ++ib) { if (ret == CE_None) { void *p = NULL; GDALRasterBlock *b = NULL; if ((buffer != NULL) && (ib == to_buffer_band)) { p = buffer; } else { GDALWMSRasterBand *band = static_cast<GDALWMSRasterBand *>(m_parent_dataset->GetRasterBand(ib)); if (m_overview >= 0) band = static_cast<GDALWMSRasterBand *>(band->GetOverview(m_overview)); if (!band->IsBlockInCache(x, y)) { b = band->GetLockedBlockRef(x, y, true); if (b != NULL) { p = b->GetDataRef(); if (p == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: GetDataRef returned NULL."); ret = CE_Failure; } } } else { //CPLDebug("WMS", "Band %d, block (x,y)=(%d, %d) already in cache", band->GetBand(), x, y); } } if (p != NULL) { int pixel_space = GDALGetDataTypeSize(eDataType) / 8; int line_space = pixel_space * nBlockXSize; if (color_table == NULL) { if( ib <= ds->GetRasterCount()) { GDALDataType dt=eDataType; // Get the data from the PNG as stored instead of converting, if the server asks for that // TODO: This hack is from #3493 - not sure it really belongs here. if ((GDT_Int16==dt)&&(GDT_UInt16==ds->GetRasterBand(ib)->GetRasterDataType())) dt=GDT_UInt16; if (ds->RasterIO(GF_Read, 0, 0, sx, sy, p, sx, sy, dt, 1, &ib, pixel_space, line_space, 0) != CE_None) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: RasterIO failed on downloaded block."); ret = CE_Failure; } } else { // parent expects 4 bands but file only has 3 so generate a all "opaque" 4th band if (accepted_as_no_alpha) { // the file had 3 bands and we are reading band 4 (Alpha) so fill with 255 (no alpha) GByte *byte_buffer = reinterpret_cast<GByte *>(p); for (int y = 0; y < sy; ++y) { for (int x = 0; x < sx; ++x) { const int offset = x + y * line_space; byte_buffer[offset] = 255; // fill with opaque } } } else { // we should never get here because this case was caught above CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Incorrect bands count %d in downloaded block, expected %d.", ds->GetRasterCount(), m_parent_dataset->nBands); ret = CE_Failure; } } } else if (ib <= 4) { if (ds->RasterIO(GF_Read, 0, 0, sx, sy, p, sx, sy, eDataType, 1, NULL, pixel_space, line_space, 0) != CE_None) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: RasterIO failed on downloaded block."); ret = CE_Failure; } if (ret == CE_None) { GByte *band_color_table = color_table + 256 * (ib - 1); GByte *byte_buffer = reinterpret_cast<GByte *>(p); for (int y = 0; y < sy; ++y) { for (int x = 0; x < sx; ++x) { const int offset = x + y * line_space; byte_buffer[offset] = band_color_table[byte_buffer[offset]]; } } } } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Color table supports at most 4 components."); ret = CE_Failure; } } if (b != NULL) { b->DropLock(); } } } } GDALClose(ds); } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Unable to open downloaded block."); ret = CE_Failure; } if (color_table != NULL) { delete[] color_table; } return ret; }
GDALDataset *SAFEDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Is this a SENTINEL-1 manifest.safe definition? */ /* -------------------------------------------------------------------- */ if ( !SAFEDataset::Identify( poOpenInfo ) ) { return NULL; } /* -------------------------------------------------------------------- */ /* Get subdataset information, if relevant */ /* -------------------------------------------------------------------- */ CPLString osMDFilename; //Subdataset 1st level selection (ex: for swath selection) CPLString osSelectedSubDS1; //Subdataset 2nd level selection (ex: for polarisation selection) CPLString osSelectedSubDS2; if (STARTS_WITH_CI(poOpenInfo->pszFilename, "SENTINEL1_DS:")) { osMDFilename = poOpenInfo->pszFilename + strlen("SENTINEL1_DS:"); const char* pszSelection1 = strrchr(osMDFilename.c_str(), ':'); if (pszSelection1 == NULL || pszSelection1 == osMDFilename.c_str() ) { CPLError(CE_Failure, CPLE_AppDefined, "Invalid syntax for SENTINEL1_DS:"); return NULL; } osMDFilename.resize( pszSelection1 - osMDFilename.c_str() ); osSelectedSubDS1 = pszSelection1 + strlen(":"); const char* pszSelection2 = strchr(osSelectedSubDS1.c_str(), '_'); if (pszSelection2 != NULL && pszSelection2 != pszSelection1 ) { osSelectedSubDS1.resize( pszSelection2 - osSelectedSubDS1.c_str() ); osSelectedSubDS2 = pszSelection2 + strlen("_"); } //update directory check: VSIStatBufL sStat; if( VSIStatL( osMDFilename.c_str(), &sStat ) == 0 ) poOpenInfo->bIsDirectory = VSI_ISDIR( sStat.st_mode ); } else { osMDFilename = poOpenInfo->pszFilename; } if( poOpenInfo->bIsDirectory ) { osMDFilename = CPLFormCIFilename( osMDFilename.c_str(), "manifest.safe", NULL ); } /* -------------------------------------------------------------------- */ /* Ingest the manifest.safe file. */ /* -------------------------------------------------------------------- */ //TODO REMOVE CPLXMLNode *psImageAttributes, *psImageGenerationParameters; CPLXMLNode *psManifest = CPLParseXMLFile( osMDFilename ); if( psManifest == NULL ) return NULL; CPLString osPath(CPLGetPath( osMDFilename )); /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLDestroyXMLNode( psManifest ); CPLError( CE_Failure, CPLE_NotSupported, "The SAFE driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Get contentUnit parent element. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psContentUnits = CPLGetXMLNode( psManifest, "=xfdu:XFDU.informationPackageMap.xfdu:contentUnit" ); if( psContentUnits == NULL ) { CPLDestroyXMLNode( psManifest ); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to find <xfdu:XFDU><informationPackageMap>" "<xfdu:contentUnit> in manifest file." ); return NULL; } /* -------------------------------------------------------------------- */ /* Get Metadata Objects element. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psMetaDataObjects = CPLGetXMLNode( psManifest, "=xfdu:XFDU.metadataSection" ); if( psMetaDataObjects == NULL ) { CPLDestroyXMLNode( psManifest ); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to find <xfdu:XFDU><metadataSection>" "in manifest file." ); return NULL; } /* -------------------------------------------------------------------- */ /* Get Data Objects element. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psDataObjects = CPLGetXMLNode( psManifest, "=xfdu:XFDU.dataObjectSection" ); if( psDataObjects == NULL ) { CPLDestroyXMLNode( psManifest ); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to find <xfdu:XFDU><dataObjectSection> in document." ); return NULL; } /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ SAFEDataset *poDS = new SAFEDataset(); poDS->psManifest = psManifest; /* -------------------------------------------------------------------- */ /* Look for "Measurement Data Unit" contentUnit elements. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psAnnotation = NULL; //Map with all measures aggregated by swath std::map<CPLString, std::set<CPLString> > oMapSwaths2Pols; for( CPLXMLNode *psContentUnit = psContentUnits->psChild; psContentUnit != NULL; psContentUnit = psContentUnit->psNext ) { if( psContentUnit->eType != CXT_Element || !(EQUAL(psContentUnit->pszValue,"xfdu:contentUnit")) ) { continue; } const char *pszUnitType = CPLGetXMLValue( psContentUnit, "unitType", "" ); const char *pszAnnotation = NULL; const char *pszCalibration = NULL; const char *pszMeasurement = NULL; if ( EQUAL(pszUnitType, "Measurement Data Unit") ) { /* Get dmdID and dataObjectID */ const char *pszDmdID = CPLGetXMLValue(psContentUnit, "dmdID", ""); const char *pszDataObjectID = CPLGetXMLValue( psContentUnit, "dataObjectPointer.dataObjectID", "" ); if( *pszDataObjectID == '\0' || *pszDmdID == '\0' ) { continue; } CPLXMLNode *psDataObject = SAFEDataset::GetDataObject( psDataObjects, pszDataObjectID); const char *pszRepId = CPLGetXMLValue( psDataObject, "repID", "" ); if ( !EQUAL(pszRepId, "s1Level1MeasurementSchema") ) { continue; } pszMeasurement = CPLGetXMLValue( psDataObject, "byteStream.fileLocation.href", ""); if( *pszMeasurement == '\0' ) { continue; } char** papszTokens = CSLTokenizeString2( pszDmdID, " ", CSLT_ALLOWEMPTYTOKENS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES ); for( int j = 0; j < CSLCount( papszTokens ); j++ ) { const char* pszId = papszTokens[j]; if( *pszId == '\0' ) { continue; } //Map the metadata ID to the object element CPLXMLNode *psDO = SAFEDataset::GetDataObject( psMetaDataObjects, psDataObjects, pszId); if (psDO == NULL) { continue; } //check object type pszRepId = CPLGetXMLValue( psDO, "repID", "" ); if( EQUAL(pszRepId, "s1Level1ProductSchema") ) { /* Get annotation filename */ pszAnnotation = CPLGetXMLValue( psDO, "byteStream.fileLocation.href", ""); if( *pszAnnotation == '\0' ) { continue; } } else if( EQUAL(pszRepId, "s1Level1CalibrationSchema") ) { pszCalibration = CPLGetXMLValue( psDO, "byteStream.fileLocation.href", ""); if( *pszCalibration == '\0' ) { continue; } } else { continue; } } CSLDestroy(papszTokens); if (pszAnnotation == NULL || pszCalibration == NULL ) { continue; } //open Annotation XML file CPLString osAnnotationFilePath = CPLFormFilename( osPath, pszAnnotation, NULL ); if( psAnnotation ) CPLDestroyXMLNode(psAnnotation); psAnnotation = CPLParseXMLFile( osAnnotationFilePath ); if( psAnnotation == NULL ) continue; /* -------------------------------------------------------------------- */ /* Get overall image information. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = atoi(CPLGetXMLValue( psAnnotation, "=product.imageAnnotation.imageInformation.numberOfSamples", "-1" )); poDS->nRasterYSize = atoi(CPLGetXMLValue( psAnnotation, "=product.imageAnnotation.imageInformation.numberOfLines", "-1" )); if (poDS->nRasterXSize <= 1 || poDS->nRasterYSize <= 1) { CPLError( CE_Failure, CPLE_OpenFailed, "Non-sane raster dimensions provided in manifest.safe. " "If this is a valid SENTINEL-1 scene, please contact your " "data provider for a corrected dataset." ); delete poDS; CPLDestroyXMLNode(psAnnotation); return NULL; } CPLString osProductType = CPLGetXMLValue( psAnnotation, "=product.adsHeader.productType", "UNK" ); CPLString osMissionId = CPLGetXMLValue( psAnnotation, "=product.adsHeader.missionId", "UNK" ); CPLString osPolarisation = CPLGetXMLValue( psAnnotation, "=product.adsHeader.polarisation", "UNK" ); CPLString osMode = CPLGetXMLValue( psAnnotation, "=product.adsHeader.mode", "UNK" ); CPLString osSwath = CPLGetXMLValue( psAnnotation, "=product.adsHeader.swath", "UNK" ); oMapSwaths2Pols[osSwath].insert(osPolarisation); if (osSelectedSubDS1.empty()) { // If not subdataset was selected, // open the first one we can find. osSelectedSubDS1 = osSwath; } if (!EQUAL(osSelectedSubDS1.c_str(), osSwath.c_str())) { //do not mix swath, otherwise it does not work for SLC products continue; } if (!osSelectedSubDS2.empty() && (osSelectedSubDS2.find(osPolarisation)== std::string::npos)) { // Add only selected polarisations. continue; } poDS->SetMetadataItem("PRODUCT_TYPE", osProductType.c_str()); poDS->SetMetadataItem("MISSION_ID", osMissionId.c_str()); poDS->SetMetadataItem("MODE", osMode.c_str()); poDS->SetMetadataItem("SWATH", osSwath.c_str()); /* -------------------------------------------------------------------- */ /* Get dataType (so we can recognize complex data), and the */ /* bitsPerSample. */ /* -------------------------------------------------------------------- */ const char *pszDataType = CPLGetXMLValue( psAnnotation, "=product.imageAnnotation.imageInformation.outputPixels", "" ); GDALDataType eDataType; if( EQUAL(pszDataType,"16 bit Signed Integer") ) eDataType = GDT_CInt16; else if( EQUAL(pszDataType,"16 bit Unsigned Integer") ) eDataType = GDT_UInt16; else { delete poDS; CPLError( CE_Failure, CPLE_AppDefined, "dataType=%s: not a supported configuration.", pszDataType ); CPLDestroyXMLNode(psAnnotation); return NULL; } /* Extract pixel spacing information */ const char *pszPixelSpacing = CPLGetXMLValue( psAnnotation, "=product.imageAnnotation.imageInformation.rangePixelSpacing", "UNK" ); poDS->SetMetadataItem( "PIXEL_SPACING", pszPixelSpacing ); const char *pszLineSpacing = CPLGetXMLValue( psAnnotation, "=product.imageAnnotation.imageInformation.azimuthPixelSpacing", "UNK" ); poDS->SetMetadataItem( "LINE_SPACING", pszLineSpacing ); /* -------------------------------------------------------------------- */ /* Form full filename (path of manifest.safe + measurement file). */ /* -------------------------------------------------------------------- */ char *pszFullname = CPLStrdup(CPLFormFilename( osPath, pszMeasurement, NULL )); /* -------------------------------------------------------------------- */ /* Try and open the file. */ /* -------------------------------------------------------------------- */ GDALDataset *poBandFile = reinterpret_cast<GDALDataset *>( GDALOpen( pszFullname, GA_ReadOnly ) ); if( poBandFile == NULL ) { // NOP } else if (poBandFile->GetRasterCount() == 0) { GDALClose( (GDALRasterBandH) poBandFile ); } else { poDS->papszExtraFiles = CSLAddString( poDS->papszExtraFiles, osAnnotationFilePath ); poDS->papszExtraFiles = CSLAddString( poDS->papszExtraFiles, pszFullname ); /* -------------------------------------------------------------------- */ /* Create the band. */ /* -------------------------------------------------------------------- */ SAFERasterBand *poBand = new SAFERasterBand( poDS, eDataType, osSwath.c_str(), osPolarisation.c_str(), poBandFile ); poDS->SetBand( poDS->GetRasterCount() + 1, poBand ); } CPLFree( pszFullname ); } } //loop through all Swath/pols to add subdatasets int iSubDS = 1; for (std::map<CPLString, std::set<CPLString> >::iterator iterSwath=oMapSwaths2Pols.begin(); iterSwath!=oMapSwaths2Pols.end(); ++iterSwath) { CPLString osSubDS1 = iterSwath->first; CPLString osSubDS2; for (std::set<CPLString>::iterator iterPol=iterSwath->second.begin(); iterPol!=iterSwath->second.end(); ++iterPol) { if (!osSubDS2.empty()) { osSubDS2 += "+"; } osSubDS2 += *iterPol; //Create single band SubDataset SAFEDataset::AddSubDataset(poDS, iSubDS, CPLSPrintf("SENTINEL1_DS:%s:%s_%s", osPath.c_str(), osSubDS1.c_str(), (*iterPol).c_str()), CPLSPrintf("Single band with %s swath and %s polarisation", osSubDS1.c_str(), (*iterPol).c_str()) ); iSubDS++; } if (iterSwath->second.size()>1) { //Create single band SubDataset with all polarisations SAFEDataset::AddSubDataset(poDS, iSubDS, CPLSPrintf("SENTINEL1_DS:%s:%s", osPath.c_str(), osSubDS1.c_str()), CPLSPrintf("%s swath with all polarisations as bands", osSubDS1.c_str()) ); iSubDS++; } } if (poDS->GetRasterCount() == 0) { CPLError( CE_Failure, CPLE_OpenFailed, "Measurement bands not found." ); delete poDS; if( psAnnotation ) CPLDestroyXMLNode(psAnnotation); return NULL; } /* -------------------------------------------------------------------- */ /* Collect more metadata elements */ /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ /* Platform information */ /* -------------------------------------------------------------------- */ CPLXMLNode *psPlatformAttrs = SAFEDataset::GetMetaDataObject( psMetaDataObjects, "platform"); if (psPlatformAttrs != NULL) { const char *pszItem = CPLGetXMLValue( psPlatformAttrs, "metadataWrap.xmlData.safe:platform" ".safe:familyName", "" ); poDS->SetMetadataItem( "SATELLITE_IDENTIFIER", pszItem ); pszItem = CPLGetXMLValue( psPlatformAttrs, "metadataWrap.xmlData.safe:platform" ".safe:instrument.safe:familyName.abbreviation", "" ); poDS->SetMetadataItem( "SENSOR_IDENTIFIER", pszItem ); pszItem = CPLGetXMLValue( psPlatformAttrs, "metadataWrap.xmlData.safe:platform" ".safe:instrument.safe:extension" ".s1sarl1:instrumentMode.s1sarl1:mode", "UNK" ); poDS->SetMetadataItem( "BEAM_MODE", pszItem ); pszItem = CPLGetXMLValue( psPlatformAttrs, "metadataWrap.xmlData.safe:platform" ".safe:instrument.safe:extension" ".s1sarl1:instrumentMode.s1sarl1:swath", "UNK" ); poDS->SetMetadataItem( "BEAM_SWATH", pszItem ); } /* -------------------------------------------------------------------- */ /* Acquisition Period information */ /* -------------------------------------------------------------------- */ CPLXMLNode *psAcquisitionAttrs = SAFEDataset::GetMetaDataObject( psMetaDataObjects, "acquisitionPeriod"); if (psAcquisitionAttrs != NULL) { const char *pszItem = CPLGetXMLValue( psAcquisitionAttrs, "metadataWrap.xmlData.safe:acquisitionPeriod" ".safe:startTime", "UNK" ); poDS->SetMetadataItem( "ACQUISITION_START_TIME", pszItem ); pszItem = CPLGetXMLValue( psAcquisitionAttrs, "metadataWrap.xmlData.safe:acquisitionPeriod" ".safe:stopTime", "UNK" ); poDS->SetMetadataItem( "ACQUISITION_STOP_TIME", pszItem ); } /* -------------------------------------------------------------------- */ /* Processing information */ /* -------------------------------------------------------------------- */ CPLXMLNode *psProcessingAttrs = SAFEDataset::GetMetaDataObject( psMetaDataObjects, "processing"); if (psProcessingAttrs != NULL) { const char *pszItem = CPLGetXMLValue( psProcessingAttrs, "metadataWrap.xmlData.safe:processing.safe:facility.name", "UNK" ); poDS->SetMetadataItem( "FACILITY_IDENTIFIER", pszItem ); } /* -------------------------------------------------------------------- */ /* Measurement Orbit Reference information */ /* -------------------------------------------------------------------- */ CPLXMLNode *psOrbitAttrs = SAFEDataset::GetMetaDataObject( psMetaDataObjects, "measurementOrbitReference"); if (psOrbitAttrs != NULL) { const char *pszItem = CPLGetXMLValue( psOrbitAttrs, "metadataWrap.xmlData.safe:orbitReference" ".safe:orbitNumber", "UNK" ); poDS->SetMetadataItem( "ORBIT_NUMBER", pszItem ); pszItem = CPLGetXMLValue( psOrbitAttrs, "metadataWrap.xmlData.safe:orbitReference" ".safe:extension.s1:orbitProperties.s1:pass", "UNK" ); poDS->SetMetadataItem( "ORBIT_DIRECTION", pszItem ); } /* -------------------------------------------------------------------- */ /* Collect Annotation Processing Information */ /* -------------------------------------------------------------------- */ CPLXMLNode *psProcessingInfo = CPLGetXMLNode( psAnnotation, "=product.imageAnnotation.processingInformation" ); if ( psProcessingInfo != NULL ) { OGRSpatialReference oLL, oPrj; const char *pszEllipsoidName = CPLGetXMLValue( psProcessingInfo, "ellipsoidName", "" ); const double minor_axis = CPLAtof(CPLGetXMLValue( psProcessingInfo, "ellipsoidSemiMinorAxis", "0.0" )); const double major_axis = CPLAtof(CPLGetXMLValue( psProcessingInfo, "ellipsoidSemiMajorAxis", "0.0" )); if ( EQUAL(pszEllipsoidName, "") || ( minor_axis == 0.0 ) || ( major_axis == 0.0 ) ) { CPLError(CE_Warning,CPLE_AppDefined,"Warning- incomplete" " ellipsoid information. Using wgs-84 parameters.\n"); oLL.SetWellKnownGeogCS( "WGS84" ); oPrj.SetWellKnownGeogCS( "WGS84" ); } else if ( EQUAL( pszEllipsoidName, "WGS84" ) ) { oLL.SetWellKnownGeogCS( "WGS84" ); oPrj.SetWellKnownGeogCS( "WGS84" ); } else { const double inv_flattening = major_axis/(major_axis - minor_axis); oLL.SetGeogCS( "","",pszEllipsoidName, major_axis, inv_flattening); oPrj.SetGeogCS( "","",pszEllipsoidName, major_axis, inv_flattening); } CPLFree( poDS->pszGCPProjection ); poDS->pszGCPProjection = NULL; oLL.exportToWkt( &(poDS->pszGCPProjection) ); } /* -------------------------------------------------------------------- */ /* Collect GCPs. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psGeoGrid = CPLGetXMLNode( psAnnotation, "=product.geolocationGrid.geolocationGridPointList" ); if( psGeoGrid != NULL ) { /* count GCPs */ poDS->nGCPCount = 0; for( CPLXMLNode *psNode = psGeoGrid->psChild; psNode != NULL; psNode = psNode->psNext ) { if( EQUAL(psNode->pszValue,"geolocationGridPoint") ) poDS->nGCPCount++ ; } poDS->pasGCPList = reinterpret_cast<GDAL_GCP *>( CPLCalloc( sizeof(GDAL_GCP), poDS->nGCPCount ) ); poDS->nGCPCount = 0; for( CPLXMLNode *psNode = psGeoGrid->psChild; psNode != NULL; psNode = psNode->psNext ) { GDAL_GCP *psGCP = poDS->pasGCPList + poDS->nGCPCount; if( !EQUAL(psNode->pszValue,"geolocationGridPoint") ) continue; poDS->nGCPCount++ ; char szID[32]; snprintf( szID, sizeof(szID), "%d", poDS->nGCPCount ); psGCP->pszId = CPLStrdup( szID ); psGCP->pszInfo = CPLStrdup(""); psGCP->dfGCPPixel = CPLAtof(CPLGetXMLValue(psNode,"pixel","0")); psGCP->dfGCPLine = CPLAtof(CPLGetXMLValue(psNode,"line","0")); psGCP->dfGCPX = CPLAtof(CPLGetXMLValue(psNode,"longitude","")); psGCP->dfGCPY = CPLAtof(CPLGetXMLValue(psNode,"latitude","")); psGCP->dfGCPZ = CPLAtof(CPLGetXMLValue(psNode,"height","")); } } CPLDestroyXMLNode(psAnnotation); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ const CPLString osDescription = osMDFilename; /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( osDescription ); poDS->SetPhysicalFilename( osMDFilename ); poDS->SetSubdatasetName( osDescription ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, ":::VIRTUAL:::" ); return poDS; }