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 ); }
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; }
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; }