GDALDataset *BAGDataset::Open( GDALOpenInfo * poOpenInfo )

{
/* -------------------------------------------------------------------- */
/*      Confirm that this appears to be a BAG file.                     */
/* -------------------------------------------------------------------- */
    if( !Identify( poOpenInfo ) )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The BAG driver does not support update access." );
        return NULL;
    }
    
/* -------------------------------------------------------------------- */
/*      Open the file as an HDF5 file.                                  */
/* -------------------------------------------------------------------- */
    hid_t hHDF5 = H5Fopen( poOpenInfo->pszFilename, 
                           H5F_ACC_RDONLY, H5P_DEFAULT );

    if( hHDF5 < 0 )  
        return NULL;

/* -------------------------------------------------------------------- */
/*      Confirm it is a BAG dataset by checking for the                 */
/*      BAG_Root/Bag Version attribute.                                 */
/* -------------------------------------------------------------------- */
    hid_t hBagRoot = H5Gopen( hHDF5, "/BAG_root" );
    hid_t hVersion = -1;

    if( hBagRoot >= 0 )
        hVersion = H5Aopen_name( hBagRoot, "Bag Version" );

    if( hVersion < 0 )
    {
        H5Fclose( hHDF5 );
        return NULL;
    }
    H5Aclose( hVersion );

/* -------------------------------------------------------------------- */
/*      Create a corresponding dataset.                                 */
/* -------------------------------------------------------------------- */
    BAGDataset *poDS = new BAGDataset();

    poDS->hHDF5 = hHDF5;

/* -------------------------------------------------------------------- */
/*      Extract version as metadata.                                    */
/* -------------------------------------------------------------------- */
    CPLString osVersion;

    if( GH5_FetchAttribute( hBagRoot, "Bag Version", osVersion ) )
        poDS->SetMetadataItem( "BagVersion", osVersion );

    H5Gclose( hBagRoot );

/* -------------------------------------------------------------------- */
/*      Fetch the elevation dataset and attach as a band.               */
/* -------------------------------------------------------------------- */
    int nNextBand = 1;
    hid_t hElevation = H5Dopen( hHDF5, "/BAG_root/elevation" );
    if( hElevation < 0 )
    {
        delete poDS;
        return NULL;
    }

    BAGRasterBand *poElevBand = new BAGRasterBand( poDS, nNextBand );

    if( !poElevBand->Initialize( hElevation, "elevation" ) )
    {
        delete poElevBand;
        delete poDS;
        return NULL;
    }

    poDS->nRasterXSize = poElevBand->nRasterXSize;
    poDS->nRasterYSize = poElevBand->nRasterYSize;

    poDS->SetBand( nNextBand++, poElevBand );

/* -------------------------------------------------------------------- */
/*      Try to do the same for the uncertainty band.                    */
/* -------------------------------------------------------------------- */
    hid_t hUncertainty = H5Dopen( hHDF5, "/BAG_root/uncertainty" );
    BAGRasterBand *poUBand = new BAGRasterBand( poDS, nNextBand );

    if( hUncertainty >= 0 && poUBand->Initialize( hUncertainty, "uncertainty") )
    {
        poDS->SetBand( nNextBand++, poUBand );
    }
    else
        delete poUBand;

/* -------------------------------------------------------------------- */
/*      Try to do the same for the uncertainty band.                    */
/* -------------------------------------------------------------------- */
    hid_t hNominal = -1;

    H5E_BEGIN_TRY {
        hNominal = H5Dopen( hHDF5, "/BAG_root/nominal_elevation" );
    } H5E_END_TRY;

    BAGRasterBand *poNBand = new BAGRasterBand( poDS, nNextBand );
    if( hNominal >= 0 && poNBand->Initialize( hNominal,
                                              "nominal_elevation" ) )
    {
        poDS->SetBand( nNextBand++, poNBand );
    }
    else
        delete poNBand;
        
/* -------------------------------------------------------------------- */
/*      Load the XML metadata.                                          */
/* -------------------------------------------------------------------- */
    poDS->LoadMetadata();

/* -------------------------------------------------------------------- */
/*      Setup/check for pam .aux.xml.                                   */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Setup overviews.                                                */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    return( poDS );
}
Example #2
0
bool BAGRasterBand::Initialize( hid_t hDatasetID, const char *pszName )

{
    SetDescription( pszName );

    this->hDatasetID = hDatasetID;

    hid_t datatype     = H5Dget_type( hDatasetID );
    dataspace          = H5Dget_space( hDatasetID );
    int n_dims         = H5Sget_simple_extent_ndims( dataspace );
    native             = H5Tget_native_type( datatype, H5T_DIR_ASCEND );
    hsize_t dims[3], maxdims[3];

    eDataType = GH5_GetDataType( native );

    if( n_dims == 2 )
    {
        H5Sget_simple_extent_dims( dataspace, dims, maxdims );

        nRasterXSize = (int) dims[1];
        nRasterYSize = (int) dims[0];
    }
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Dataset not of rank 2." );
        return false;
    }

    nBlockXSize   = nRasterXSize;
    nBlockYSize   = 1;

/* -------------------------------------------------------------------- */
/*      Check for chunksize, and use it as blocksize for optimized      */
/*      reading.                                                        */
/* -------------------------------------------------------------------- */
    hid_t listid = H5Dget_create_plist( hDatasetID );
    if (listid>0)
    {
        if(H5Pget_layout(listid) == H5D_CHUNKED)
        {
            hsize_t panChunkDims[3];
            int nDimSize = H5Pget_chunk(listid, 3, panChunkDims);
            nBlockXSize  = (int) panChunkDims[nDimSize-1];
            nBlockYSize  = (int) panChunkDims[nDimSize-2];
        }

        int nfilters = H5Pget_nfilters( listid );

        H5Z_filter_t filter;
        char         name[120];
        size_t       cd_nelmts = 20;
        unsigned int cd_values[20];
        unsigned int flags;
        for (int i = 0; i < nfilters; i++) 
        {
          filter = H5Pget_filter(listid, i, &flags, (size_t *)&cd_nelmts, cd_values, 120, name);
          if (filter == H5Z_FILTER_DEFLATE)
            poDS->SetMetadataItem( "COMPRESSION", "DEFLATE", "IMAGE_STRUCTURE" );
          else if (filter == H5Z_FILTER_NBIT)
            poDS->SetMetadataItem( "COMPRESSION", "NBIT", "IMAGE_STRUCTURE" );
          else if (filter == H5Z_FILTER_SCALEOFFSET)
            poDS->SetMetadataItem( "COMPRESSION", "SCALEOFFSET", "IMAGE_STRUCTURE" );
          else if (filter == H5Z_FILTER_SZIP)
            poDS->SetMetadataItem( "COMPRESSION", "SZIP", "IMAGE_STRUCTURE" );
        }

        H5Pclose(listid);
    }

/* -------------------------------------------------------------------- */
/*      Load min/max information.                                       */
/* -------------------------------------------------------------------- */
    if( EQUAL(pszName,"elevation") 
        && GH5_FetchAttribute( hDatasetID, "Maximum Elevation Value", 
                            dfMaximum ) 
        && GH5_FetchAttribute( hDatasetID, "Minimum Elevation Value", 
                               dfMinimum ) )
        bMinMaxSet = true;
    else if( EQUAL(pszName,"uncertainty")
             && GH5_FetchAttribute( hDatasetID, "Maximum Uncertainty Value", 
                                    dfMaximum ) 
             && GH5_FetchAttribute( hDatasetID, "Minimum Uncertainty Value", 
                                    dfMinimum ) )
    {
        /* Some products where uncertainty band is completely set to nodata */
        /* wrongly declare minimum and maximum to 0.0 */
        if( dfMinimum != 0.0 && dfMaximum != 0.0 )
            bMinMaxSet = true;
    }
    else if( EQUAL(pszName,"nominal_elevation") 
             && GH5_FetchAttribute( hDatasetID, "max_value", 
                                    dfMaximum ) 
             && GH5_FetchAttribute( hDatasetID, "min_value", 
                                    dfMinimum ) )
        bMinMaxSet = true;

    return true;
}
bool BAGRasterBand::Initialize( hid_t hDatasetID, const char *pszName )

{
    SetDescription( pszName );

    this->hDatasetID = hDatasetID;

    hid_t datatype     = H5Dget_type( hDatasetID );
    dataspace          = H5Dget_space( hDatasetID );
    hid_t n_dims       = H5Sget_simple_extent_ndims( dataspace );
    native             = H5Tget_native_type( datatype, H5T_DIR_ASCEND );
    hsize_t dims[3], maxdims[3];

    eDataType = GH5_GetDataType( native );

    if( n_dims == 2 )
    {
        H5Sget_simple_extent_dims( dataspace, dims, maxdims );

        nRasterXSize = dims[1];
        nRasterYSize = dims[0];
    }
    else
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Dataset not of rank 2." );
        return false;
    }

    nBlockXSize   = nRasterXSize;
    nBlockYSize   = 1;

/* -------------------------------------------------------------------- */
/*      Check for chunksize, and use it as blocksize for optimized      */
/*      reading.                                                        */
/* -------------------------------------------------------------------- */
    hid_t listid = H5Dget_create_plist( hDatasetID );
    if (listid>0)
    {
        if(H5Pget_layout(listid) == H5D_CHUNKED)
        {
            hsize_t panChunkDims[3];
            int nDimSize = H5Pget_chunk(listid, 3, panChunkDims);
            nBlockXSize   = panChunkDims[nDimSize-1];
            nBlockYSize   = panChunkDims[nDimSize-2];
        }
        H5Pclose(listid);
    }

/* -------------------------------------------------------------------- */
/*      Load min/max information.                                       */
/* -------------------------------------------------------------------- */
    if( EQUAL(pszName,"elevation") 
        && GH5_FetchAttribute( hDatasetID, "Maximum Elevation Value", 
                            dfMaximum ) 
        && GH5_FetchAttribute( hDatasetID, "Minimum Elevation Value", 
                               dfMinimum ) )
        bMinMaxSet = true;
    else if( EQUAL(pszName,"uncertainty") 
             && GH5_FetchAttribute( hDatasetID, "Maximum Uncertainty Value", 
                                    dfMaximum ) 
             && GH5_FetchAttribute( hDatasetID, "Minimum Uncertainty Value", 
                                    dfMinimum ) )
        bMinMaxSet = true;
    else if( EQUAL(pszName,"nominal_elevation") 
             && GH5_FetchAttribute( hDatasetID, "max_value", 
                                    dfMaximum ) 
             && GH5_FetchAttribute( hDatasetID, "min_value", 
                                    dfMinimum ) )
        bMinMaxSet = true;

    return true;
}
Example #4
0
GDALDataset *BAGDataset::Open( GDALOpenInfo *poOpenInfo )

{
    // Confirm that this appears to be a BAG file.
    if( !Identify(poOpenInfo) )
        return nullptr;

    // Confirm the requested access is supported.
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "The BAG driver does not support update access.");
        return nullptr;
    }

    // Open the file as an HDF5 file.
    hid_t hHDF5 = H5Fopen(poOpenInfo->pszFilename, H5F_ACC_RDONLY, H5P_DEFAULT);

    if( hHDF5 < 0 )
        return nullptr;

    // Confirm it is a BAG dataset by checking for the
    // BAG_Root/Bag Version attribute.
    const hid_t hBagRoot = H5Gopen(hHDF5, "/BAG_root");
    const hid_t hVersion =
        hBagRoot >= 0 ? H5Aopen_name(hBagRoot, "Bag Version") : -1;

    if( hVersion < 0 )
    {
        if( hBagRoot >= 0 )
            H5Gclose(hBagRoot);
        H5Fclose(hHDF5);
        return nullptr;
    }
    H5Aclose(hVersion);

    // Create a corresponding dataset.
    BAGDataset *const poDS = new BAGDataset();

    poDS->hHDF5 = hHDF5;

    // Extract version as metadata.
    CPLString osVersion;

    if( GH5_FetchAttribute(hBagRoot, "Bag Version", osVersion) )
        poDS->SetMetadataItem("BagVersion", osVersion);

    H5Gclose(hBagRoot);

    // Fetch the elevation dataset and attach as a band.
    int nNextBand = 1;
    const hid_t hElevation = H5Dopen(hHDF5, "/BAG_root/elevation");
    if( hElevation < 0 )
    {
        delete poDS;
        return nullptr;
    }

    BAGRasterBand *poElevBand = new BAGRasterBand(poDS, nNextBand);

    if( !poElevBand->Initialize(hElevation, "elevation") )
    {
        delete poElevBand;
        delete poDS;
        return nullptr;
    }

    poDS->nRasterXSize = poElevBand->nRasterXSize;
    poDS->nRasterYSize = poElevBand->nRasterYSize;

    poDS->SetBand(nNextBand++, poElevBand);

    // Try to do the same for the uncertainty band.
    const hid_t hUncertainty = H5Dopen(hHDF5, "/BAG_root/uncertainty");
    BAGRasterBand *poUBand = new BAGRasterBand(poDS, nNextBand);

    if( hUncertainty >= 0 && poUBand->Initialize(hUncertainty, "uncertainty") )
    {
        poDS->SetBand(nNextBand++, poUBand);
    }
    else
    {
        delete poUBand;
    }

    // Try to do the same for the nominal_elevation band.
    hid_t hNominal = -1;

#ifdef HAVE_GCC_WARNING_ZERO_AS_NULL_POINTER_CONSTANT
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
#endif
    H5E_BEGIN_TRY {
        hNominal = H5Dopen(hHDF5, "/BAG_root/nominal_elevation");
    } H5E_END_TRY;

#ifdef HAVE_GCC_WARNING_ZERO_AS_NULL_POINTER_CONSTANT
#pragma GCC diagnostic pop
#endif

    BAGRasterBand *const poNBand = new BAGRasterBand(poDS, nNextBand);
    if( hNominal >= 0 && poNBand->Initialize(hNominal, "nominal_elevation") )
    {
        poDS->SetBand(nNextBand++, poNBand);
    }
    else
    {
        delete poNBand;
    }

    // Load the XML metadata.
    poDS->LoadMetadata();

    // Setup/check for pam .aux.xml.
    poDS->SetDescription(poOpenInfo->pszFilename);
    poDS->TryLoadXML();

    // Setup overviews.
    poDS->oOvManager.Initialize(poDS, poOpenInfo->pszFilename);

    return poDS;
}