LCOV - code coverage report
Current view: directory - frmts/hdf5 - bagdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 246 206 83.7 %
Date: 2012-04-28 Functions: 22 14 63.6 %

       1                 : /******************************************************************************
       2                 :  * $Id: bagdataset.cpp 24084 2012-03-06 04:47:46Z warmerdam $
       3                 :  *
       4                 :  * Project:  Hierarchical Data Format Release 5 (HDF5)
       5                 :  * Purpose:  Read BAG datasets.
       6                 :  * Author:   Frank Warmerdam <warmerdam@pobox.com>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2009, Frank Warmerdam <warmerdam@pobox.com>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "gh5_convenience.h"
      31                 : 
      32                 : #include "gdal_pam.h"
      33                 : #include "gdal_priv.h"
      34                 : #include "ogr_spatialref.h"
      35                 : #include "cpl_string.h"
      36                 : 
      37                 : CPL_CVSID("$Id: bagdataset.cpp 24084 2012-03-06 04:47:46Z warmerdam $");
      38                 : 
      39                 : CPL_C_START
      40                 : void    GDALRegister_BAG(void);
      41                 : CPL_C_END
      42                 : 
      43                 : OGRErr OGR_SRS_ImportFromISO19115( OGRSpatialReference *poThis, 
      44                 :                                    const char *pszISOXML );
      45                 : 
      46                 : /************************************************************************/
      47                 : /* ==================================================================== */
      48                 : /*                               BAGDataset                             */
      49                 : /* ==================================================================== */
      50                 : /************************************************************************/
      51                 : class BAGDataset : public GDALPamDataset
      52                 : {
      53                 : 
      54                 :     friend class BAGRasterBand;
      55                 : 
      56                 :     hid_t        hHDF5;
      57                 : 
      58                 :     char        *pszProjection;
      59                 :     double       adfGeoTransform[6];
      60                 : 
      61                 :     void         LoadMetadata();
      62                 : 
      63                 :     char        *pszXMLMetadata;
      64                 :     char        *apszMDList[2];
      65                 :     
      66                 : public:
      67                 :     BAGDataset();
      68                 :     ~BAGDataset();
      69                 :     
      70                 :     virtual CPLErr GetGeoTransform( double * );
      71                 :     virtual const char *GetProjectionRef(void);
      72                 :     virtual char      **GetMetadata( const char * pszDomain = "" );
      73                 : 
      74                 :     static GDALDataset  *Open( GDALOpenInfo * );
      75                 :     static int          Identify( GDALOpenInfo * );
      76                 : };
      77                 : 
      78                 : /************************************************************************/
      79                 : /* ==================================================================== */
      80                 : /*                               BAGRasterBand                          */
      81                 : /* ==================================================================== */
      82                 : /************************************************************************/
      83                 : class BAGRasterBand : public GDALPamRasterBand
      84                 : {
      85                 :     friend class BAGDataset;
      86                 : 
      87                 :     hid_t       hDatasetID;
      88                 :     hid_t       native;
      89                 :     hid_t       dataspace;
      90                 : 
      91                 :     bool        bMinMaxSet;
      92                 :     double      dfMinimum;
      93                 :     double      dfMaximum;
      94                 : 
      95                 : public:
      96                 :   
      97                 :     BAGRasterBand( BAGDataset *, int );
      98                 :     ~BAGRasterBand();
      99                 : 
     100                 :     bool                    Initialize( hid_t hDataset, const char *pszName );
     101                 : 
     102                 :     virtual CPLErr          IReadBlock( int, int, void * );
     103                 :     virtual double      GetNoDataValue( int * ); 
     104                 : 
     105                 :     virtual double GetMinimum( int *pbSuccess = NULL );
     106                 :     virtual double GetMaximum(int *pbSuccess = NULL );
     107                 : };
     108                 : 
     109                 : /************************************************************************/
     110                 : /*                           BAGRasterBand()                            */
     111                 : /************************************************************************/
     112               6 : BAGRasterBand::BAGRasterBand( BAGDataset *poDS, int nBand )
     113                 : 
     114                 : {
     115               6 :     this->poDS       = poDS;
     116               6 :     this->nBand      = nBand;
     117                 :     
     118               6 :     hDatasetID = -1;
     119               6 :     dataspace = -1;
     120               6 :     native = -1;
     121               6 :     bMinMaxSet = false;
     122               6 : }
     123                 : 
     124                 : /************************************************************************/
     125                 : /*                           ~BAGRasterBand()                           */
     126                 : /************************************************************************/
     127                 : 
     128               6 : BAGRasterBand::~BAGRasterBand()
     129                 : {
     130               6 :   if( dataspace > 0 )
     131               6 :     H5Sclose(dataspace);
     132                 : 
     133               6 :   if( native > 0 )
     134               6 :     H5Tclose( native );
     135                 : 
     136               6 :   if( hDatasetID > 0 )
     137               6 :     H5Dclose( hDatasetID );
     138               6 : }
     139                 : 
     140                 : /************************************************************************/
     141                 : /*                             Initialize()                             */
     142                 : /************************************************************************/
     143                 : 
     144               6 : bool BAGRasterBand::Initialize( hid_t hDatasetID, const char *pszName )
     145                 : 
     146                 : {
     147               6 :     SetDescription( pszName );
     148                 : 
     149               6 :     this->hDatasetID = hDatasetID;
     150                 : 
     151               6 :     hid_t datatype     = H5Dget_type( hDatasetID );
     152               6 :     dataspace          = H5Dget_space( hDatasetID );
     153               6 :     hid_t n_dims       = H5Sget_simple_extent_ndims( dataspace );
     154               6 :     native             = H5Tget_native_type( datatype, H5T_DIR_ASCEND );
     155                 :     hsize_t dims[3], maxdims[3];
     156                 : 
     157               6 :     eDataType = GH5_GetDataType( native );
     158                 : 
     159               6 :     if( n_dims == 2 )
     160                 :     {
     161               6 :         H5Sget_simple_extent_dims( dataspace, dims, maxdims );
     162                 : 
     163               6 :         nRasterXSize = (int) dims[1];
     164               6 :         nRasterYSize = (int) dims[0];
     165                 :     }
     166                 :     else
     167                 :     {
     168                 :         CPLError( CE_Failure, CPLE_AppDefined,
     169               0 :                   "Dataset not of rank 2." );
     170               0 :         return false;
     171                 :     }
     172                 : 
     173               6 :     nBlockXSize   = nRasterXSize;
     174               6 :     nBlockYSize   = 1;
     175                 : 
     176                 : /* -------------------------------------------------------------------- */
     177                 : /*      Check for chunksize, and use it as blocksize for optimized      */
     178                 : /*      reading.                                                        */
     179                 : /* -------------------------------------------------------------------- */
     180               6 :     hid_t listid = H5Dget_create_plist( hDatasetID );
     181               6 :     if (listid>0)
     182                 :     {
     183               6 :         if(H5Pget_layout(listid) == H5D_CHUNKED)
     184                 :         {
     185                 :             hsize_t panChunkDims[3];
     186               0 :             int nDimSize = H5Pget_chunk(listid, 3, panChunkDims);
     187               0 :             nBlockXSize  = (int) panChunkDims[nDimSize-1];
     188               0 :             nBlockYSize  = (int) panChunkDims[nDimSize-2];
     189                 :         }
     190               6 :         H5Pclose(listid);
     191                 :     }
     192                 : 
     193                 : /* -------------------------------------------------------------------- */
     194                 : /*      Load min/max information.                                       */
     195                 : /* -------------------------------------------------------------------- */
     196               6 :     if( EQUAL(pszName,"elevation") 
     197                 :         && GH5_FetchAttribute( hDatasetID, "Maximum Elevation Value", 
     198                 :                             dfMaximum ) 
     199                 :         && GH5_FetchAttribute( hDatasetID, "Minimum Elevation Value", 
     200                 :                                dfMinimum ) )
     201               2 :         bMinMaxSet = true;
     202               4 :     else if( EQUAL(pszName,"uncertainty") 
     203                 :              && GH5_FetchAttribute( hDatasetID, "Maximum Uncertainty Value", 
     204                 :                                     dfMaximum ) 
     205                 :              && GH5_FetchAttribute( hDatasetID, "Minimum Uncertainty Value", 
     206                 :                                     dfMinimum ) )
     207               2 :         bMinMaxSet = true;
     208               2 :     else if( EQUAL(pszName,"nominal_elevation") 
     209                 :              && GH5_FetchAttribute( hDatasetID, "max_value", 
     210                 :                                     dfMaximum ) 
     211                 :              && GH5_FetchAttribute( hDatasetID, "min_value", 
     212                 :                                     dfMinimum ) )
     213               2 :         bMinMaxSet = true;
     214                 : 
     215               6 :     return true;
     216                 : }
     217                 : 
     218                 : /************************************************************************/
     219                 : /*                             GetMinimum()                             */
     220                 : /************************************************************************/
     221                 : 
     222               2 : double BAGRasterBand::GetMinimum( int * pbSuccess )
     223                 : 
     224                 : {
     225               2 :     if( bMinMaxSet )
     226                 :     {
     227               2 :         if( pbSuccess )
     228               2 :             *pbSuccess = TRUE;
     229               2 :         return dfMinimum;
     230                 :     }
     231                 :     else
     232               0 :         return GDALRasterBand::GetMinimum( pbSuccess );
     233                 : }
     234                 : 
     235                 : /************************************************************************/
     236                 : /*                             GetMaximum()                             */
     237                 : /************************************************************************/
     238                 : 
     239               2 : double BAGRasterBand::GetMaximum( int * pbSuccess )
     240                 : 
     241                 : {
     242               2 :     if( bMinMaxSet )
     243                 :     {
     244               2 :         if( pbSuccess )
     245               2 :             *pbSuccess = TRUE;
     246               2 :         return dfMaximum;
     247                 :     }
     248                 :     else
     249               0 :         return GDALRasterBand::GetMaximum( pbSuccess );
     250                 : }
     251                 : 
     252                 : /************************************************************************/
     253                 : /*                           GetNoDataValue()                           */
     254                 : /************************************************************************/
     255               6 : double BAGRasterBand::GetNoDataValue( int * pbSuccess )
     256                 : 
     257                 : {
     258               6 :     if( pbSuccess )
     259               6 :         *pbSuccess = TRUE;
     260                 : 
     261               6 :     if( EQUAL(GetDescription(),"elevation") )
     262               2 :         return  1000000.0;
     263               4 :     else if( EQUAL(GetDescription(),"uncertainty") )
     264               2 :         return 0.0;
     265               2 :     else if( EQUAL(GetDescription(),"nominal_elevation") )
     266               2 :         return 1000000.0;
     267                 :     else
     268               0 :         return GDALPamRasterBand::GetNoDataValue( pbSuccess );
     269                 : }
     270                 : 
     271                 : /************************************************************************/
     272                 : /*                             IReadBlock()                             */
     273                 : /************************************************************************/
     274              60 : CPLErr BAGRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     275                 :                                   void * pImage )
     276                 : {
     277                 :     herr_t      status;
     278                 :     hsize_t     count[3];
     279                 :     H5OFFSET_TYPE offset[3];
     280                 :     int         nSizeOfData;
     281                 :     hid_t       memspace;
     282                 :     hsize_t     col_dims[3];
     283                 :     hsize_t     rank;
     284                 : 
     285              60 :     rank=2;
     286                 : 
     287              60 :     offset[0] = MAX(0,nRasterYSize - (nBlockYOff+1)*nBlockYSize);
     288              60 :     offset[1] = nBlockXOff*nBlockXSize;
     289              60 :     count[0]  = nBlockYSize;
     290              60 :     count[1]  = nBlockXSize;
     291                 : 
     292              60 :     nSizeOfData = H5Tget_size( native );
     293              60 :     memset( pImage,0,nBlockXSize*nBlockYSize*nSizeOfData );
     294                 : 
     295                 : /*  blocksize may not be a multiple of imagesize */
     296              60 :     count[0]  = MIN( size_t(nBlockYSize), GetYSize() - offset[0]);
     297              60 :     count[1]  = MIN( size_t(nBlockXSize), GetXSize() - offset[1]);
     298                 : 
     299              60 :     if( nRasterYSize - (nBlockYOff+1)*nBlockYSize < 0 )
     300                 :     {
     301               0 :         count[0] += (nRasterYSize - (nBlockYOff+1)*nBlockYSize);
     302                 :     }
     303                 : 
     304                 : /* -------------------------------------------------------------------- */
     305                 : /*      Select block from file space                                    */
     306                 : /* -------------------------------------------------------------------- */
     307                 :     status =  H5Sselect_hyperslab( dataspace,
     308                 :                                    H5S_SELECT_SET,
     309                 :                                    offset, NULL,
     310              60 :                                    count, NULL );
     311                 : 
     312                 : /* -------------------------------------------------------------------- */
     313                 : /*      Create memory space to receive the data                         */
     314                 : /* -------------------------------------------------------------------- */
     315              60 :     col_dims[0]=nBlockYSize;
     316              60 :     col_dims[1]=nBlockXSize;
     317              60 :     memspace = H5Screate_simple( (int) rank, col_dims, NULL );
     318              60 :     H5OFFSET_TYPE mem_offset[3] = {0, 0, 0};
     319                 :     status =  H5Sselect_hyperslab(memspace,
     320                 :                                   H5S_SELECT_SET,
     321                 :                                   mem_offset, NULL,
     322              60 :                                   count, NULL);
     323                 : 
     324                 :     status = H5Dread ( hDatasetID,
     325                 :                        native,
     326                 :                        memspace,
     327                 :                        dataspace,
     328                 :                        H5P_DEFAULT,
     329              60 :                        pImage );
     330                 : 
     331              60 :     H5Sclose( memspace );
     332                 : 
     333                 : /* -------------------------------------------------------------------- */
     334                 : /*      Y flip the data.                                                */
     335                 : /* -------------------------------------------------------------------- */
     336              60 :     int nLinesToFlip = count[0];
     337              60 :     int nLineSize = nSizeOfData * nBlockXSize;
     338              60 :     GByte *pabyTemp = (GByte *) CPLMalloc(nLineSize);
     339                 : 
     340              60 :     for( int iY = 0; iY < nLinesToFlip/2; iY++ )
     341                 :     {
     342                 :         memcpy( pabyTemp, 
     343                 :                 ((GByte *)pImage) + iY * nLineSize,
     344               0 :                 nLineSize );
     345                 :         memcpy( ((GByte *)pImage) + iY * nLineSize,
     346                 :                 ((GByte *)pImage) + (nLinesToFlip-iY-1) * nLineSize,
     347               0 :                 nLineSize );
     348                 :         memcpy( ((GByte *)pImage) + (nLinesToFlip-iY-1) * nLineSize,
     349                 :                 pabyTemp,
     350               0 :                 nLineSize );
     351                 :     }
     352                 : 
     353              60 :     CPLFree( pabyTemp );
     354                 : 
     355                 : /* -------------------------------------------------------------------- */
     356                 : /*      Return success or failure.                                      */
     357                 : /* -------------------------------------------------------------------- */
     358              60 :     if( status < 0 )
     359                 :     {
     360                 :         CPLError( CE_Failure, CPLE_AppDefined,
     361               0 :                   "H5Dread() failed for block." );
     362               0 :         return CE_Failure;
     363                 :     }
     364                 :     else
     365              60 :         return CE_None;
     366                 : }
     367                 : 
     368                 : /************************************************************************/
     369                 : /* ==================================================================== */
     370                 : /*                              BAGDataset                              */
     371                 : /* ==================================================================== */
     372                 : /************************************************************************/
     373                 : 
     374                 : /************************************************************************/
     375                 : /*                             BAGDataset()                             */
     376                 : /************************************************************************/
     377                 : 
     378               2 : BAGDataset::BAGDataset()
     379                 : {
     380               2 :     hHDF5 = -1;
     381               2 :     pszXMLMetadata = NULL;
     382               2 :     pszProjection = NULL;
     383                 : 
     384               2 :     adfGeoTransform[0] = 0.0;
     385               2 :     adfGeoTransform[1] = 1.0;
     386               2 :     adfGeoTransform[2] = 0.0;
     387               2 :     adfGeoTransform[3] = 0.0;
     388               2 :     adfGeoTransform[4] = 0.0;
     389               2 :     adfGeoTransform[5] = 1.0;
     390               2 : }
     391                 : 
     392                 : /************************************************************************/
     393                 : /*                            ~BAGDataset()                             */
     394                 : /************************************************************************/
     395               2 : BAGDataset::~BAGDataset( )
     396                 : {
     397               2 :     FlushCache();
     398                 : 
     399               2 :     if( hHDF5 >= 0 )
     400               2 :         H5Fclose( hHDF5 );
     401                 : 
     402               2 :     CPLFree( pszXMLMetadata );
     403               2 :     CPLFree( pszProjection );
     404               2 : }
     405                 : 
     406                 : /************************************************************************/
     407                 : /*                              Identify()                              */
     408                 : /************************************************************************/
     409                 : 
     410           22270 : int BAGDataset::Identify( GDALOpenInfo * poOpenInfo )
     411                 : 
     412                 : {
     413                 : /* -------------------------------------------------------------------- */
     414                 : /*      Is it an HDF5 file?                                             */
     415                 : /* -------------------------------------------------------------------- */
     416                 :     static const char achSignature[] = "\211HDF\r\n\032\n";
     417                 : 
     418           22270 :     if( poOpenInfo->pabyHeader == NULL
     419                 :         || memcmp(poOpenInfo->pabyHeader,achSignature,8) != 0 )
     420           22260 :         return FALSE;
     421                 : 
     422                 : /* -------------------------------------------------------------------- */
     423                 : /*      Does it have the extension .bag?                                */
     424                 : /* -------------------------------------------------------------------- */
     425              10 :     if( !EQUAL(CPLGetExtension(poOpenInfo->pszFilename),"bag") )
     426               8 :         return FALSE;
     427                 : 
     428               2 :     return TRUE;
     429                 : }
     430                 : 
     431                 : /************************************************************************/
     432                 : /*                                Open()                                */
     433                 : /************************************************************************/
     434                 : 
     435            3362 : GDALDataset *BAGDataset::Open( GDALOpenInfo * poOpenInfo )
     436                 : 
     437                 : {
     438                 : /* -------------------------------------------------------------------- */
     439                 : /*      Confirm that this appears to be a BAG file.                     */
     440                 : /* -------------------------------------------------------------------- */
     441            3362 :     if( !Identify( poOpenInfo ) )
     442            3360 :         return NULL;
     443                 : 
     444                 : /* -------------------------------------------------------------------- */
     445                 : /*      Confirm the requested access is supported.                      */
     446                 : /* -------------------------------------------------------------------- */
     447               2 :     if( poOpenInfo->eAccess == GA_Update )
     448                 :     {
     449                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     450               0 :                   "The BAG driver does not support update access." );
     451               0 :         return NULL;
     452                 :     }
     453                 :     
     454                 : /* -------------------------------------------------------------------- */
     455                 : /*      Open the file as an HDF5 file.                                  */
     456                 : /* -------------------------------------------------------------------- */
     457                 :     hid_t hHDF5 = H5Fopen( poOpenInfo->pszFilename, 
     458               2 :                            H5F_ACC_RDONLY, H5P_DEFAULT );
     459                 : 
     460               2 :     if( hHDF5 < 0 )  
     461               0 :         return NULL;
     462                 : 
     463                 : /* -------------------------------------------------------------------- */
     464                 : /*      Confirm it is a BAG dataset by checking for the                 */
     465                 : /*      BAG_Root/Bag Version attribute.                                 */
     466                 : /* -------------------------------------------------------------------- */
     467               2 :     hid_t hBagRoot = H5Gopen( hHDF5, "/BAG_root" );
     468               2 :     hid_t hVersion = -1;
     469                 : 
     470               2 :     if( hBagRoot >= 0 )
     471               2 :         hVersion = H5Aopen_name( hBagRoot, "Bag Version" );
     472                 : 
     473               2 :     if( hVersion < 0 )
     474                 :     {
     475               0 :         H5Fclose( hHDF5 );
     476               0 :         return NULL;
     477                 :     }
     478               2 :     H5Aclose( hVersion );
     479                 : 
     480                 : /* -------------------------------------------------------------------- */
     481                 : /*      Create a corresponding dataset.                                 */
     482                 : /* -------------------------------------------------------------------- */
     483               2 :     BAGDataset *poDS = new BAGDataset();
     484                 : 
     485               2 :     poDS->hHDF5 = hHDF5;
     486                 : 
     487                 : /* -------------------------------------------------------------------- */
     488                 : /*      Extract version as metadata.                                    */
     489                 : /* -------------------------------------------------------------------- */
     490               2 :     CPLString osVersion;
     491                 : 
     492               4 :     if( GH5_FetchAttribute( hBagRoot, "Bag Version", osVersion ) )
     493               2 :         poDS->SetMetadataItem( "BagVersion", osVersion );
     494                 : 
     495               2 :     H5Gclose( hBagRoot );
     496                 : 
     497                 : /* -------------------------------------------------------------------- */
     498                 : /*      Fetch the elevation dataset and attach as a band.               */
     499                 : /* -------------------------------------------------------------------- */
     500               2 :     int nNextBand = 1;
     501               2 :     hid_t hElevation = H5Dopen( hHDF5, "/BAG_root/elevation" );
     502               2 :     if( hElevation < 0 )
     503                 :     {
     504               0 :         delete poDS;
     505               0 :         return NULL;
     506                 :     }
     507                 : 
     508               2 :     BAGRasterBand *poElevBand = new BAGRasterBand( poDS, nNextBand );
     509                 : 
     510               4 :     if( !poElevBand->Initialize( hElevation, "elevation" ) )
     511                 :     {
     512               0 :         delete poElevBand;
     513               0 :         delete poDS;
     514               0 :         return NULL;
     515                 :     }
     516                 : 
     517               2 :     poDS->nRasterXSize = poElevBand->nRasterXSize;
     518               2 :     poDS->nRasterYSize = poElevBand->nRasterYSize;
     519                 : 
     520               2 :     poDS->SetBand( nNextBand++, poElevBand );
     521                 : 
     522                 : /* -------------------------------------------------------------------- */
     523                 : /*      Try to do the same for the uncertainty band.                    */
     524                 : /* -------------------------------------------------------------------- */
     525               2 :     hid_t hUncertainty = H5Dopen( hHDF5, "/BAG_root/uncertainty" );
     526               2 :     BAGRasterBand *poUBand = new BAGRasterBand( poDS, nNextBand );
     527                 : 
     528               4 :     if( hUncertainty >= 0 && poUBand->Initialize( hUncertainty, "uncertainty") )
     529                 :     {
     530               2 :         poDS->SetBand( nNextBand++, poUBand );
     531                 :     }
     532                 :     else
     533               0 :         delete poUBand;
     534                 : 
     535                 : /* -------------------------------------------------------------------- */
     536                 : /*      Try to do the same for the uncertainty band.                    */
     537                 : /* -------------------------------------------------------------------- */
     538               2 :     hid_t hNominal = -1;
     539                 : 
     540               2 :     H5E_BEGIN_TRY {
     541               2 :         hNominal = H5Dopen( hHDF5, "/BAG_root/nominal_elevation" );
     542               2 :     } H5E_END_TRY;
     543                 : 
     544               2 :     BAGRasterBand *poNBand = new BAGRasterBand( poDS, nNextBand );
     545               4 :     if( hNominal >= 0 && poNBand->Initialize( hNominal,
     546                 :                                               "nominal_elevation" ) )
     547                 :     {
     548               2 :         poDS->SetBand( nNextBand++, poNBand );
     549                 :     }
     550                 :     else
     551               0 :         delete poNBand;
     552                 :         
     553                 : /* -------------------------------------------------------------------- */
     554                 : /*      Load the XML metadata.                                          */
     555                 : /* -------------------------------------------------------------------- */
     556               2 :     poDS->LoadMetadata();
     557                 : 
     558                 : /* -------------------------------------------------------------------- */
     559                 : /*      Setup/check for pam .aux.xml.                                   */
     560                 : /* -------------------------------------------------------------------- */
     561               2 :     poDS->SetDescription( poOpenInfo->pszFilename );
     562               2 :     poDS->TryLoadXML();
     563                 : 
     564                 : /* -------------------------------------------------------------------- */
     565                 : /*      Setup overviews.                                                */
     566                 : /* -------------------------------------------------------------------- */
     567               2 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     568                 : 
     569               2 :     return( poDS );
     570                 : }
     571                 : 
     572                 : /************************************************************************/
     573                 : /*                            LoadMetadata()                            */
     574                 : /************************************************************************/
     575                 : 
     576               2 : void BAGDataset::LoadMetadata()
     577                 : 
     578                 : {
     579                 : /* -------------------------------------------------------------------- */
     580                 : /*      Load the metadata from the file.                                */
     581                 : /* -------------------------------------------------------------------- */
     582               2 :     hid_t hMDDS = H5Dopen( hHDF5, "/BAG_root/metadata" );
     583               2 :     hid_t datatype     = H5Dget_type( hMDDS );
     584               2 :     hid_t dataspace    = H5Dget_space( hMDDS );
     585               2 :     hid_t native       = H5Tget_native_type( datatype, H5T_DIR_ASCEND );
     586                 :     hsize_t dims[3], maxdims[3];
     587                 : 
     588               2 :     H5Sget_simple_extent_dims( dataspace, dims, maxdims );
     589                 : 
     590               2 :     pszXMLMetadata = (char *) CPLCalloc((int) (dims[0]+1),1);
     591                 : 
     592               2 :     H5Dread( hMDDS, native, H5S_ALL, dataspace, H5P_DEFAULT, pszXMLMetadata );
     593                 : 
     594               2 :     H5Tclose( native );
     595               2 :     H5Sclose( dataspace );
     596               2 :     H5Tclose( datatype );
     597               2 :     H5Dclose( hMDDS );
     598                 : 
     599               2 :     if( strlen(pszXMLMetadata) == 0 )
     600               0 :         return;
     601                 : 
     602                 : /* -------------------------------------------------------------------- */
     603                 : /*      Try to get the geotransform.                                    */
     604                 : /* -------------------------------------------------------------------- */
     605               2 :     CPLXMLNode *psRoot = CPLParseXMLString( pszXMLMetadata );
     606                 : 
     607               2 :     if( psRoot == NULL )
     608               0 :         return;
     609                 : 
     610               2 :     CPLStripXMLNamespace( psRoot, NULL, TRUE );
     611                 : 
     612               2 :     CPLXMLNode *psGeo = CPLSearchXMLNode( psRoot, "=MD_Georectified" );
     613                 : 
     614               2 :     if( psGeo != NULL )
     615                 :     {
     616                 :         char **papszCornerTokens = 
     617                 :             CSLTokenizeStringComplex( 
     618                 :                 CPLGetXMLValue( psGeo, "cornerPoints.Point.coordinates", "" ),
     619               2 :                 " ,", FALSE, FALSE );
     620                 : 
     621               2 :         if( CSLCount(papszCornerTokens ) == 4 )
     622                 :         {
     623               2 :             double dfLLX = atof( papszCornerTokens[0] );
     624               2 :             double dfLLY = atof( papszCornerTokens[1] );
     625               2 :             double dfURX = atof( papszCornerTokens[2] );
     626               2 :             double dfURY = atof( papszCornerTokens[3] );
     627                 : 
     628               2 :             adfGeoTransform[0] = dfLLX;
     629               2 :             adfGeoTransform[1] = (dfURX - dfLLX) / (GetRasterXSize()-1);
     630               2 :             adfGeoTransform[3] = dfURY;
     631               2 :             adfGeoTransform[5] = (dfLLY - dfURY) / (GetRasterYSize()-1);
     632                 : 
     633               2 :             adfGeoTransform[0] -= adfGeoTransform[1] * 0.5;
     634               2 :             adfGeoTransform[3] -= adfGeoTransform[5] * 0.5;
     635                 :         }
     636               2 :         CSLDestroy( papszCornerTokens );
     637                 :     }
     638                 : 
     639                 : /* -------------------------------------------------------------------- */
     640                 : /*      Try to get the coordinate system.                               */
     641                 : /* -------------------------------------------------------------------- */
     642               2 :     OGRSpatialReference oSRS;
     643                 : 
     644               2 :     if( OGR_SRS_ImportFromISO19115( &oSRS, pszXMLMetadata )
     645                 :         == OGRERR_NONE )
     646                 :     {
     647               0 :         oSRS.exportToWkt( &pszProjection );
     648                 :     }
     649                 : 
     650                 : /* -------------------------------------------------------------------- */
     651                 : /*      Fetch acquisition date.                                         */
     652                 : /* -------------------------------------------------------------------- */
     653               2 :     CPLXMLNode *psDateTime = CPLSearchXMLNode( psRoot, "=dateTime" );
     654               2 :     if( psDateTime != NULL )
     655                 :     {
     656               2 :         const char *pszDateTimeValue = CPLGetXMLValue( psDateTime, NULL, "" );
     657               2 :         if( pszDateTimeValue )
     658               2 :             SetMetadataItem( "BAG_DATETIME", pszDateTimeValue );
     659                 :     }
     660                 : 
     661               2 :     CPLDestroyXMLNode( psRoot );
     662                 : }
     663                 : 
     664                 : /************************************************************************/
     665                 : /*                          GetGeoTransform()                           */
     666                 : /************************************************************************/
     667                 : 
     668               0 : CPLErr BAGDataset::GetGeoTransform( double *padfGeoTransform )
     669                 : 
     670                 : {
     671               0 :     if( adfGeoTransform[0] != 0.0 || adfGeoTransform[3] != 0.0 )
     672                 :     {
     673               0 :         memcpy( padfGeoTransform, adfGeoTransform, sizeof(double)*6 );
     674               0 :         return CE_None;
     675                 :     }
     676                 :     else
     677               0 :         return GDALPamDataset::GetGeoTransform( padfGeoTransform );
     678                 : }
     679                 : 
     680                 : /************************************************************************/
     681                 : /*                          GetProjectionRef()                          */
     682                 : /************************************************************************/
     683                 : 
     684               0 : const char *BAGDataset::GetProjectionRef()
     685                 : 
     686                 : {
     687               0 :     if( pszProjection )
     688               0 :         return pszProjection;
     689                 :     else 
     690               0 :         return GDALPamDataset::GetProjectionRef();
     691                 : }
     692                 : 
     693                 : /************************************************************************/
     694                 : /*                            GetMetadata()                             */
     695                 : /************************************************************************/
     696                 : 
     697               2 : char **BAGDataset::GetMetadata( const char *pszDomain )
     698                 : 
     699                 : {
     700               2 :     if( pszDomain != NULL && EQUAL(pszDomain,"xml:BAG") )
     701                 :     {
     702               2 :         apszMDList[0] = pszXMLMetadata;
     703               2 :         apszMDList[1] = NULL;
     704                 : 
     705               2 :         return apszMDList;
     706                 :     }
     707                 :     else
     708               0 :         return GDALPamDataset::GetMetadata( pszDomain );
     709                 : }
     710                 : 
     711                 : /************************************************************************/
     712                 : /*                          GDALRegister_BAG()                          */
     713                 : /************************************************************************/
     714            1135 : void GDALRegister_BAG( )
     715                 : 
     716                 : {
     717                 :     GDALDriver  *poDriver;
     718                 :     
     719            1135 :     if (! GDAL_CHECK_VERSION("BAG"))
     720               0 :         return;
     721                 : 
     722            1135 :     if(  GDALGetDriverByName( "BAG" ) == NULL )
     723                 :     {
     724            1093 :         poDriver = new GDALDriver();
     725                 :         
     726            1093 :         poDriver->SetDescription( "BAG" );
     727                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     728            1093 :                                    "Bathymetry Attributed Grid" );
     729                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     730            1093 :                                    "frmt_bag.html" );
     731            1093 :         poDriver->pfnOpen = BAGDataset::Open;
     732            1093 :         poDriver->pfnIdentify = BAGDataset::Identify;
     733                 : 
     734            1093 :         GetGDALDriverManager( )->RegisterDriver( poDriver );
     735                 :     }
     736                 : }

Generated by: LCOV version 1.7