Beispiel #1
0
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;
}
Beispiel #2
0
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 );
}
Beispiel #3
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
}
Beispiel #4
0
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 );
}
Beispiel #6
0
// 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() );
  }
}
Beispiel #7
0
// -------------------------------------------------------------------
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;
}
Beispiel #8
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;
}
Beispiel #9
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;
}
Beispiel #11
0
int FindSRS( const char *pszInput, OGRSpatialReference &oSRS )

{
    int            bGotSRS = FALSE;
    VSILFILE      *fp = NULL;
    GDALDataset	  *poGDALDS = NULL; 
    OGRLayer      *poLayer = NULL;
    const char    *pszProjection = NULL;
    CPLErrorHandler oErrorHandler = NULL;
    int bIsFile = FALSE;
    OGRErr eErr = OGRERR_NONE;
    int bDebug  = FALSE;

    /* temporarily suppress error messages we may get from xOpen() */
    bDebug = CSLTestBoolean(CPLGetConfigOption("CPL_DEBUG", "OFF"));
    if ( ! bDebug )
        oErrorHandler = CPLSetErrorHandler ( CPLQuietErrorHandler );

    /* Test if argument is a file */
    fp = VSIFOpenL( pszInput, "r" );
    if ( fp )  {
        bIsFile = TRUE;
        VSIFCloseL( fp );
        CPLDebug( "gdalsrsinfo", "argument is a file" );
    } 
       
    /* try to open with GDAL */
    if( strncmp(pszInput, "http://spatialreference.org/",
                strlen("http://spatialreference.org/")) != 0 )
    {
        CPLDebug( "gdalsrsinfo", "trying to open with GDAL" );
        poGDALDS = (GDALDataset *) GDALOpenEx( pszInput, 0, NULL, NULL, NULL );
    }
    if ( poGDALDS != NULL ) {
        pszProjection = poGDALDS->GetProjectionRef( );
        if( pszProjection != NULL && pszProjection[0] != '\0' )
        {
            char* pszProjectionTmp = (char*) pszProjection;
            if( oSRS.importFromWkt( &pszProjectionTmp ) == OGRERR_NONE ) {
                CPLDebug( "gdalsrsinfo", "got SRS from GDAL" );
                bGotSRS = TRUE;
            }
        }
        else if( poGDALDS->GetLayerCount() > 0 )
        {
            poLayer = poGDALDS->GetLayer( 0 );
            if ( poLayer != NULL ) {
                OGRSpatialReference *poSRS = poLayer->GetSpatialRef( );
                if ( poSRS != NULL ) {
                    CPLDebug( "gdalsrsinfo", "got SRS from OGR" );
                    bGotSRS = TRUE;
                    OGRSpatialReference* poSRSClone = poSRS->Clone();
                    oSRS = *poSRSClone;
                    OGRSpatialReference::DestroySpatialReference( poSRSClone );
                }
            }
        }
        GDALClose( (GDALDatasetH) poGDALDS );
        if ( ! bGotSRS ) 
            CPLDebug( "gdalsrsinfo", "did not open with GDAL" );
    }    
    
    /* Try ESRI file */
    if ( ! bGotSRS && bIsFile && (strstr(pszInput,".prj") != NULL) ) {
        CPLDebug( "gdalsrsinfo", 
                  "trying to get SRS from ESRI .prj file [%s]", pszInput );

        char **pszTemp;
        if ( strstr(pszInput,"ESRI::") != NULL )
            pszTemp = CSLLoad( pszInput+6 );
        else 
            pszTemp = CSLLoad( pszInput );

        if( pszTemp ) {
            eErr = oSRS.importFromESRI( pszTemp );
            CSLDestroy( pszTemp );
        }
        else 
            eErr = OGRERR_UNSUPPORTED_SRS;

        if( eErr != OGRERR_NONE ) {
            CPLDebug( "gdalsrsinfo", "did not get SRS from ESRI .prj file" );
        }
        else {
            CPLDebug( "gdalsrsinfo", "got SRS from ESRI .prj file" );
            bGotSRS = TRUE;
        }
    }

    /* Last resort, try OSRSetFromUserInput() */
    if ( ! bGotSRS ) {
        CPLDebug( "gdalsrsinfo", 
                  "trying to get SRS from user input [%s]", pszInput );

        eErr = oSRS.SetFromUserInput( pszInput );
 
       if(  eErr != OGRERR_NONE ) {
            CPLDebug( "gdalsrsinfo", "did not get SRS from user input" );
        }
        else {
            CPLDebug( "gdalsrsinfo", "got SRS from user input" );
            bGotSRS = TRUE;
        }
    }
    
    /* restore error messages */
    if ( ! bDebug )
        CPLSetErrorHandler ( oErrorHandler );	


    return bGotSRS;
}
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;
}
Beispiel #14
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;
  } 
Beispiel #15
0
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);
}
Beispiel #16
0
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;
}
Beispiel #17
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);
}
Beispiel #18
0
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;
}
Beispiel #19
0
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;
}
Beispiel #20
0
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;
}
Beispiel #21
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);
}
Beispiel #22
0
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;
}
Beispiel #24
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);

}
Beispiel #25
0
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
}
Beispiel #26
0
// 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);

}
Beispiel #27
0
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;
}
Beispiel #28
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;
}
Beispiel #30
0
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;
}