LCOV - code coverage report
Current view: directory - frmts/dimap - dimapdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 382 192 50.3 %
Date: 2012-12-26 Functions: 23 15 65.2 %

       1                 : /******************************************************************************
       2                 :  * $Id $
       3                 :  *
       4                 :  * Project:  SPOT Dimap Driver
       5                 :  * Purpose:  Implementation of SPOT Dimap driver.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  * Docs: http://www.spotimage.fr/dimap/spec/documentation/refdoc.htm
       9                 :  * 
      10                 :  ******************************************************************************
      11                 :  * Copyright (c) 2007, Frank Warmerdam <warmerdam@pobox.com>
      12                 :  *
      13                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      14                 :  * copy of this software and associated documentation files (the "Software"),
      15                 :  * to deal in the Software without restriction, including without limitation
      16                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      17                 :  * and/or sell copies of the Software, and to permit persons to whom the
      18                 :  * Software is furnished to do so, subject to the following conditions:
      19                 :  *
      20                 :  * The above copyright notice and this permission notice shall be included
      21                 :  * in all copies or substantial portions of the Software.
      22                 :  *
      23                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      24                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      26                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      28                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      29                 :  * DEALINGS IN THE SOFTWARE.
      30                 :  ****************************************************************************/
      31                 : 
      32                 : #include "gdal_pam.h"
      33                 : #include "cpl_minixml.h"
      34                 : #include "ogr_spatialref.h"
      35                 : #include "gdal_proxy.h"
      36                 : 
      37                 : CPL_CVSID("$Id: dimapdataset.cpp 25110 2012-10-13 13:53:53Z rouault $");
      38                 : 
      39                 : CPL_C_START
      40                 : void  GDALRegister_DIMAP(void);
      41                 : CPL_C_END
      42                 : 
      43                 : /************************************************************************/
      44                 : /* ==================================================================== */
      45                 : /*        DIMAPDataset        */
      46                 : /* ==================================================================== */
      47                 : /************************************************************************/
      48                 : 
      49                 : class DIMAPDataset : public GDALPamDataset
      50                 : {
      51                 :     CPLXMLNode *psProduct;
      52                 : 
      53                 :     CPLXMLNode *psProductDim; /* DIMAP2, DIM_<product_id>.XML */
      54                 :     CPLXMLNode *psProductStrip; /* DIMAP2, STRIP_<product_id>.XML */
      55                 : 
      56                 :     GDALDataset   *poImageDS;
      57                 : 
      58                 :     int           nGCPCount;
      59                 :     GDAL_GCP      *pasGCPList;
      60                 :     char          *pszGCPProjection;
      61                 : 
      62                 :     CPLString     osProjection;
      63                 : 
      64                 :     int           bHaveGeoTransform;
      65                 :     double        adfGeoTransform[6];
      66                 : 
      67                 :     CPLString     osMDFilename;
      68                 :     CPLString     osImageDSFilename;
      69                 :     CPLString     osDIMAPFilename;
      70                 :     int           nProductVersion;
      71                 :     
      72                 :     char          **papszXMLDimapMetadata;
      73                 : 
      74                 :   protected:
      75                 :     virtual int         CloseDependentDatasets();
      76                 : 
      77                 :     int ReadImageInformation();
      78                 :     int ReadImageInformation2(); /* DIMAP 2 */
      79                 : 
      80                 :     void SetMetadataFromXML(CPLXMLNode *psProduct, const char *apszMetadataTranslation[]);
      81                 :   public:
      82                 :     DIMAPDataset();
      83                 :           ~DIMAPDataset();
      84                 :     
      85                 :     virtual const char *GetProjectionRef(void);
      86                 :     virtual CPLErr GetGeoTransform( double * );
      87                 :     virtual int    GetGCPCount();
      88                 :     virtual const char *GetGCPProjection();
      89                 :     virtual const GDAL_GCP *GetGCPs();
      90                 :     virtual char **GetMetadata( const char *pszDomain );
      91                 :     virtual char **GetFileList(void);
      92                 : 
      93                 :     static int          Identify( GDALOpenInfo * );
      94                 :     static GDALDataset *Open( GDALOpenInfo * );
      95                 : 
      96                 :     CPLXMLNode *GetProduct() { return psProduct; }
      97                 : };
      98                 : 
      99                 : /************************************************************************/
     100                 : /* ==================================================================== */
     101                 : /*                        DIMAPWrapperRasterBand                        */
     102                 : /* ==================================================================== */
     103                 : /************************************************************************/
     104                 : class DIMAPWrapperRasterBand : public GDALProxyRasterBand
     105                 : {
     106                 :   GDALRasterBand* poBaseBand;
     107                 : 
     108                 :   protected:
     109             112 :     virtual GDALRasterBand* RefUnderlyingRasterBand() { return poBaseBand; }
     110                 : 
     111                 :   public:
     112               2 :     DIMAPWrapperRasterBand( GDALRasterBand* poBaseBand )
     113               2 :         {
     114               2 :             this->poBaseBand = poBaseBand;
     115               2 :             eDataType = poBaseBand->GetRasterDataType();
     116               2 :             poBaseBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
     117               2 :         }
     118               2 :     ~DIMAPWrapperRasterBand() {}
     119                 : };
     120                 : /************************************************************************/
     121                 : /* ==================================================================== */
     122                 : /*        DIMAPDataset        */
     123                 : /* ==================================================================== */
     124                 : /************************************************************************/
     125                 : 
     126                 : /************************************************************************/
     127                 : /*                             DIMAPDataset()                             */
     128                 : /************************************************************************/
     129                 : 
     130               2 : DIMAPDataset::DIMAPDataset()
     131                 : {
     132               2 :     psProduct = NULL;
     133                 : 
     134               2 :     psProductDim = NULL;
     135               2 :     psProductStrip = NULL;
     136                 : 
     137               2 :     nGCPCount = 0;
     138               2 :     pasGCPList = NULL;
     139               2 :     pszGCPProjection = CPLStrdup("");
     140                 : 
     141               2 :     poImageDS = NULL;
     142               2 :     bHaveGeoTransform = FALSE;
     143                 : 
     144               2 :     nProductVersion = 1;
     145                 : 
     146               2 :     papszXMLDimapMetadata = NULL;
     147               2 : }
     148                 : 
     149                 : /************************************************************************/
     150                 : /*                            ~DIMAPDataset()                             */
     151                 : /************************************************************************/
     152                 : 
     153               2 : DIMAPDataset::~DIMAPDataset()
     154                 : 
     155                 : {
     156               2 :     FlushCache();
     157                 : 
     158               2 :     CPLDestroyXMLNode( psProduct );
     159                 : 
     160               2 :     if( nProductVersion == 2 )
     161                 :     {
     162               0 :   CPLDestroyXMLNode( psProductDim );
     163               0 :   CPLDestroyXMLNode( psProductStrip );
     164                 :     }
     165                 : 
     166               2 :     CPLFree( pszGCPProjection );
     167               2 :     if( nGCPCount > 0 )
     168                 :     {
     169               2 :         GDALDeinitGCPs( nGCPCount, pasGCPList );
     170               2 :         CPLFree( pasGCPList );
     171                 :     }
     172                 : 
     173               2 :     CSLDestroy(papszXMLDimapMetadata);
     174                 : 
     175               2 :     CloseDependentDatasets();
     176               2 : }
     177                 : 
     178                 : 
     179                 : /************************************************************************/
     180                 : /*                        CloseDependentDatasets()                      */
     181                 : /************************************************************************/
     182                 : 
     183               2 : int DIMAPDataset::CloseDependentDatasets()
     184                 : {
     185               2 :     int bHasDroppedRef = GDALPamDataset::CloseDependentDatasets();
     186                 : 
     187               2 :     if( poImageDS != NULL )
     188                 :     {
     189               2 :         delete poImageDS;
     190               2 :         poImageDS = NULL;
     191               2 :         bHasDroppedRef = TRUE;
     192                 :     }
     193                 : 
     194                 : /* -------------------------------------------------------------------- */
     195                 : /*      Disconnect the bands so our destructor doesn't try and          */
     196                 : /*      delete them since they really belonged to poImageDS.            */
     197                 : /* -------------------------------------------------------------------- */
     198                 :     int iBand;
     199               4 :     for( iBand = 0; iBand < nBands; iBand++ )
     200               2 :         delete papoBands[iBand];
     201               2 :     nBands = 0;
     202                 : 
     203               2 :     return bHasDroppedRef;
     204                 : }
     205                 : 
     206                 : /************************************************************************/
     207                 : /*                            GetMetadata()                             */
     208                 : /*                                                                      */
     209                 : /*      We implement special support for fetching the full product      */
     210                 : /*      metadata as xml.                                                */
     211                 : /************************************************************************/
     212                 : 
     213               2 : char **DIMAPDataset::GetMetadata( const char *pszDomain )
     214                 : 
     215                 : {
     216               2 :     if( pszDomain && EQUAL(pszDomain,"xml:dimap") )
     217                 :     {
     218               0 :         if (papszXMLDimapMetadata == NULL)
     219                 :         {
     220               0 :             papszXMLDimapMetadata = (char **) CPLCalloc(sizeof(char*),2);
     221               0 :             papszXMLDimapMetadata[0] = CPLSerializeXMLTree( psProduct );
     222                 :         }
     223               0 :         return papszXMLDimapMetadata;
     224                 :     }
     225                 :     else
     226               2 :         return GDALPamDataset::GetMetadata( pszDomain );
     227                 : }
     228                 : 
     229                 : /************************************************************************/
     230                 : /*                          GetProjectionRef()                          */
     231                 : /************************************************************************/
     232                 : 
     233               0 : const char *DIMAPDataset::GetProjectionRef()
     234                 : 
     235                 : {
     236               0 :     if( strlen(osProjection) > 0 )
     237               0 :         return osProjection;
     238                 :     else
     239               0 :         return GDALPamDataset::GetProjectionRef();
     240                 : }
     241                 : 
     242                 : /************************************************************************/
     243                 : /*                          GetGeoTransform()                           */
     244                 : /************************************************************************/
     245                 : 
     246               0 : CPLErr DIMAPDataset::GetGeoTransform( double *padfGeoTransform )
     247                 : 
     248                 : {
     249               0 :     if( bHaveGeoTransform )
     250                 :     {
     251               0 :         memcpy( padfGeoTransform, adfGeoTransform, sizeof(double)*6 );
     252               0 :         return CE_None;
     253                 :     }
     254                 :     else
     255               0 :         return GDALPamDataset::GetGeoTransform( padfGeoTransform );
     256                 : }
     257                 : 
     258                 : /************************************************************************/
     259                 : /*                            GetFileList()                             */
     260                 : /************************************************************************/
     261                 : 
     262               0 : char **DIMAPDataset::GetFileList()
     263                 : 
     264                 : {
     265               0 :     char **papszFileList = GDALPamDataset::GetFileList();
     266               0 :     char **papszImageFiles = poImageDS->GetFileList();
     267                 : 
     268               0 :     papszFileList = CSLInsertStrings( papszFileList, -1, papszImageFiles );
     269                 : 
     270               0 :     CSLDestroy( papszImageFiles );
     271                 :     
     272               0 :     return papszFileList;
     273                 : }
     274                 : 
     275                 : /************************************************************************/
     276                 : /*                              Identify()                              */
     277                 : /************************************************************************/
     278                 : 
     279           13614 : int DIMAPDataset::Identify( GDALOpenInfo * poOpenInfo )
     280                 : 
     281                 : {
     282           13614 :     if( poOpenInfo->nHeaderBytes >= 100 )
     283                 :     {
     284            1668 :       if( ( strstr((const char *) poOpenInfo->pabyHeader, 
     285                 :                    "<Dimap_Document" ) == NULL ) &&
     286                 :     ( strstr((const char *) poOpenInfo->pabyHeader, 
     287                 :                    "<PHR_DIMAP_Document" ) == NULL ) )
     288            1666 :             return FALSE;
     289                 :         else
     290               2 :             return TRUE;
     291                 :     }
     292           11946 :     else if( poOpenInfo->bIsDirectory )
     293                 :     {
     294                 :         VSIStatBufL sStat;
     295                 : 
     296                 :   /* DIMAP file */
     297                 :         CPLString osMDFilename = 
     298              42 :             CPLFormCIFilename( poOpenInfo->pszFilename, "METADATA.DIM", NULL );
     299                 :         
     300              42 :         if( VSIStatL( osMDFilename, &sStat ) == 0 )
     301                 :         {
     302                 :             /* Make sure this is really a Dimap format */
     303               0 :             GDALOpenInfo  oOpenInfo( osMDFilename, GA_ReadOnly, NULL );
     304               0 :             if( oOpenInfo.nHeaderBytes >= 100 )
     305                 :             {
     306               0 :                 if( strstr((const char *) oOpenInfo.pabyHeader, 
     307                 :                            "<Dimap_Document" ) == NULL )
     308               0 :                     return FALSE;
     309                 :                 else
     310               0 :                     return TRUE;
     311               0 :             }
     312                 :         }
     313                 :         else
     314                 :   {
     315                 :     /* DIMAP 2 file */
     316                 :     osMDFilename = 
     317              42 :             CPLFormCIFilename( poOpenInfo->pszFilename, "VOL_PHR.XML", NULL );
     318                 :     
     319              42 :     if( VSIStatL( osMDFilename, &sStat ) == 0 )
     320               0 :             return TRUE;
     321                 :     else
     322              42 :             return FALSE;
     323               0 :   }
     324                 :     }
     325                 : 
     326           11904 :     return FALSE;
     327                 : }
     328                 : 
     329                 : /************************************************************************/
     330                 : /*                                Open()                                */
     331                 : /************************************************************************/
     332                 : 
     333            3520 : GDALDataset *DIMAPDataset::Open( GDALOpenInfo * poOpenInfo )
     334                 : 
     335                 : {
     336            3520 :     int nProductVersion = 1;
     337                 : 
     338            3520 :     if( !Identify( poOpenInfo ) )
     339            3518 :         return NULL;
     340                 :         
     341                 : /* -------------------------------------------------------------------- */
     342                 : /*      Confirm the requested access is supported.                      */
     343                 : /* -------------------------------------------------------------------- */
     344               2 :     if( poOpenInfo->eAccess == GA_Update )
     345                 :     {
     346                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     347                 :                   "The DIMAP driver does not support update access to existing"
     348               0 :                   " datasets.\n" );
     349               0 :         return NULL;
     350                 :     }
     351                 : /* -------------------------------------------------------------------- */
     352                 : /*      Get the metadata filename.                                      */
     353                 : /* -------------------------------------------------------------------- */
     354               2 :     CPLString osMDFilename, osImageDSFilename, osDIMAPFilename;
     355                 : 
     356               2 :     if( poOpenInfo->bIsDirectory )
     357                 :     {
     358                 :         VSIStatBufL sStat;
     359                 : 
     360                 :         osMDFilename = 
     361               0 :             CPLFormCIFilename( poOpenInfo->pszFilename, "METADATA.DIM", NULL );
     362                 : 
     363                 :   /* DIMAP2 */
     364               0 :   if( VSIStatL( osMDFilename, &sStat ) != 0 )
     365                 :     osMDFilename = 
     366               0 :             CPLFormCIFilename( poOpenInfo->pszFilename, "VOL_PHR.XML", NULL );
     367                 :     }
     368                 :     else
     369               2 :         osMDFilename = poOpenInfo->pszFilename;
     370                 : 
     371                 : /* -------------------------------------------------------------------- */
     372                 : /*      Ingest the xml file.                                            */
     373                 : /* -------------------------------------------------------------------- */
     374                 :     CPLXMLNode *psProduct, *psImageAttributes;
     375               2 :     CPLXMLNode *psProductDim = NULL, *psProductStrip = NULL;
     376                 : 
     377                 :     float nMetadataFormatVersion;
     378                 : 
     379               2 :     psProduct = CPLParseXMLFile( osMDFilename );
     380               2 :     if( psProduct == NULL )
     381               0 :     return NULL;
     382                 : 
     383               2 :     CPLXMLNode *psDoc = CPLGetXMLNode( psProduct, "=Dimap_Document" );
     384               2 :     if( !psDoc )
     385               0 :         psDoc = CPLGetXMLNode( psProduct, "=PHR_DIMAP_Document" );
     386                 : 
     387                 :     /* We check the for the tag Metadata_Identification.METADATA_FORMAT.
     388                 :     *  The metadata will be set to 2.0 for DIMAP2 */
     389                 :     nMetadataFormatVersion = atof( CPLGetXMLValue(CPLGetXMLNode(psDoc, "Metadata_Identification.METADATA_FORMAT"), 
     390               2 :               "version", "1") );
     391               2 :     if( nMetadataFormatVersion >= 2.0 )
     392                 :     {
     393               0 :       nProductVersion = 2;
     394                 :     }
     395                 :     
     396                 :     /* Check needed information for the DIMAP format */ 
     397               2 :     if (nProductVersion == 1)
     398                 :     {
     399               2 :         psImageAttributes = CPLGetXMLNode( psDoc, "Raster_Dimensions" );
     400               2 :   if( psImageAttributes == NULL )
     401                 :   {
     402                 :       CPLError( CE_Failure, CPLE_OpenFailed, 
     403               0 :           "Failed to find <Raster_Dimensions> in document." );
     404               0 :       return NULL;
     405                 :   }
     406                 :     }
     407                 :     else /* DIMAP2 */
     408                 :     {
     409                 :         /* Verify the presence of the DIMAP product file */
     410               0 :         CPLXMLNode *psDatasetComponents = CPLGetXMLNode(psDoc, "Dataset_Content.Dataset_Components");
     411                 : 
     412               0 :   if( psDatasetComponents == NULL )
     413                 :   {
     414                 :       CPLError( CE_Failure, CPLE_OpenFailed, 
     415               0 :           "Failed to find <Dataset_Components> in document." );
     416               0 :       return NULL;
     417                 :   }
     418                 :       
     419               0 :   CPLXMLNode *psDatasetComponent = psDatasetComponents->psChild;
     420                 : 
     421               0 :         for( ; psDatasetComponent != NULL; psDatasetComponent = psDatasetComponent->psNext ) 
     422                 :         {
     423               0 :       const char* pszComponentType = CPLGetXMLValue(psDatasetComponent, "COMPONENT_TYPE","");
     424               0 :       if( strcmp(pszComponentType, "DIMAP") == 0 )
     425                 :       {
     426                 :     const char *pszHref = CPLGetXMLValue(
     427               0 :               psDatasetComponent, "COMPONENT_PATH.href", "" );
     428                 : 
     429               0 :     if( strlen(pszHref) > 0 ) /* DIMAP product found*/
     430                 :     {
     431               0 :         if( poOpenInfo->bIsDirectory )
     432                 :         {
     433                 :       osDIMAPFilename = 
     434               0 :           CPLFormCIFilename( poOpenInfo->pszFilename, pszHref, NULL );
     435                 :         }
     436                 :         else
     437                 :         {
     438               0 :       CPLString osPath = CPLGetPath(osMDFilename);
     439                 :       osDIMAPFilename = 
     440               0 :           CPLFormFilename( osPath, pszHref, NULL );
     441                 :         }
     442                 :       
     443                 :         /* Data file might be specified there */
     444                 :         const char *pszDataFileHref = CPLGetXMLValue(
     445               0 :               psDatasetComponent, "Data_Files.Data_File.DATA_FILE_PATH.href", "" );
     446                 :         
     447               0 :         if( strlen(pszDataFileHref) > 0 )
     448                 :         {
     449               0 :       CPLString osPath = CPLGetPath(osMDFilename);
     450                 :       osImageDSFilename = 
     451               0 :           CPLFormFilename( osPath, pszDataFileHref, NULL );
     452                 :         }
     453                 : 
     454               0 :         break;
     455                 :     }
     456                 :       }
     457                 :   }
     458                 : 
     459               0 :   psProductDim = CPLParseXMLFile( osDIMAPFilename );
     460               0 :   if( psProductDim == NULL )
     461               0 :       return NULL;
     462                 : 
     463                 :   /* We need the STRIP_<product_id>.XML file for a few metadata */
     464               0 :   CPLXMLNode *psDocDim = CPLGetXMLNode( psProductDim, "=Dimap_Document" );
     465               0 :   if( !psDocDim )
     466               0 :             psDocDim = CPLGetXMLNode( psProductDim, "=PHR_DIMAP_Document" );
     467                 : 
     468               0 :         CPLXMLNode *psDatasetSources = CPLGetXMLNode(psDocDim, "Dataset_Sources");
     469               0 :   if( psDatasetSources != NULL )
     470                 :   {
     471               0 :       CPLString osSTRIPFilename;
     472               0 :       CPLXMLNode *psDatasetSource = psDatasetSources->psChild;
     473                 :       
     474               0 :       for( ; psDatasetSource != NULL; psDatasetSource = psDatasetSource->psNext ) 
     475                 :       {
     476               0 :     const char* pszSourceType = CPLGetXMLValue(psDatasetSource, "SOURCE_TYPE","");
     477               0 :     if( strcmp(pszSourceType, "Strip_Source") == 0 )
     478                 :     {
     479                 :         const char *pszHref = CPLGetXMLValue(
     480               0 :               psDatasetSource, "Component.COMPONENT_PATH.href", "" );
     481                 :         
     482               0 :         if( strlen(pszHref) > 0 ) /* STRIP product found*/
     483                 :         { 
     484               0 :       CPLString osPath = CPLGetPath(osDIMAPFilename);
     485                 :       osSTRIPFilename = 
     486               0 :           CPLFormFilename( osPath, pszHref, NULL );
     487                 :       
     488               0 :       break;
     489                 :         }
     490                 :     }
     491                 :       }
     492                 : 
     493               0 :       psProductStrip = CPLParseXMLFile( osSTRIPFilename );
     494               0 :       if( psProductStrip == NULL )
     495               0 :     return NULL;
     496                 :   }
     497                 :     }
     498                 : 
     499                 : /* -------------------------------------------------------------------- */
     500                 : /*      Create the dataset.                                             */
     501                 : /* -------------------------------------------------------------------- */
     502               2 :     DIMAPDataset *poDS = new DIMAPDataset();
     503                 : 
     504               2 :     poDS->psProduct = psProduct;
     505               2 :     poDS->psProductDim = psProductDim;
     506               2 :     poDS->psProductStrip = psProductStrip;
     507               2 :     poDS->nProductVersion = nProductVersion;
     508               2 :     poDS->osMDFilename = osMDFilename;
     509               2 :     poDS->osImageDSFilename = osImageDSFilename;
     510               2 :     poDS->osDIMAPFilename = osDIMAPFilename;    
     511                 : 
     512               2 :     int res = TRUE;
     513               2 :     if( nProductVersion == 2 )
     514               0 :   res = poDS->ReadImageInformation2();
     515                 :     else
     516               2 :   res = poDS->ReadImageInformation();
     517                 :     
     518               2 :     if( res == FALSE )
     519                 :     {
     520               0 :   delete poDS;
     521               0 :   return NULL;
     522                 :     }
     523                 : 
     524               2 :     return( poDS );
     525                 : }
     526                 : 
     527                 : 
     528                 : /************************************************************************/
     529                 : /*               ReadImageInformation() DIMAP Version 1                 */
     530                 : /************************************************************************/
     531                 : 
     532               2 : int DIMAPDataset::ReadImageInformation()
     533                 : {
     534               2 :     CPLXMLNode *psDoc = CPLGetXMLNode( psProduct, "=Dimap_Document" );
     535               2 :     if( !psDoc )
     536               0 :         psDoc = CPLGetXMLNode( psProduct, "=PHR_DIMAP_Document" );
     537                 : 
     538               2 :     CPLXMLNode *psImageAttributes = CPLGetXMLNode( psDoc, "Raster_Dimensions" );
     539                 : 
     540                 : /* -------------------------------------------------------------------- */
     541                 : /*      Get overall image information.                                  */
     542                 : /* -------------------------------------------------------------------- */
     543                 : #ifdef DEBUG
     544                 :     int nBands = 
     545               2 :         atoi(CPLGetXMLValue( psImageAttributes, "NBANDS", "-1" ));
     546                 : #endif
     547                 : 
     548                 :     nRasterXSize = 
     549               2 :         atoi(CPLGetXMLValue( psImageAttributes, "NCOLS", "-1" ));
     550                 :     nRasterYSize = 
     551               2 :         atoi(CPLGetXMLValue( psImageAttributes, "NROWS", "-1" ));
     552                 : 
     553                 : /* -------------------------------------------------------------------- */
     554                 : /*      Get the name of the underlying file.                            */
     555                 : /* -------------------------------------------------------------------- */
     556                 : 
     557                 :     const char *pszHref = CPLGetXMLValue(
     558               2 :         psDoc, "Data_Access.Data_File.DATA_FILE_PATH.href", "" );
     559               2 :     CPLString osPath = CPLGetPath(osMDFilename);
     560                 :     CPLString osImageFilename = 
     561               2 :         CPLFormFilename( osPath, pszHref, NULL );
     562                 :                                    
     563                 : /* -------------------------------------------------------------------- */
     564                 : /*      Try and open the file.                                          */
     565                 : /* -------------------------------------------------------------------- */
     566                 : 
     567               2 :     poImageDS = (GDALDataset *) GDALOpen( osImageFilename, GA_ReadOnly );
     568               2 :     if( poImageDS == NULL )
     569                 :     {
     570               0 :         return FALSE;
     571                 :     }
     572                 : 
     573                 : /* -------------------------------------------------------------------- */
     574                 : /*      Attach the bands.                                               */
     575                 : /* -------------------------------------------------------------------- */
     576                 :     int iBand;
     577               2 :     CPLAssert( nBands == poImageDS->GetRasterCount() );
     578                 : 
     579               4 :     for( iBand = 1; iBand <= poImageDS->GetRasterCount(); iBand++ )
     580               2 :         SetBand( iBand, new DIMAPWrapperRasterBand(poImageDS->GetRasterBand( iBand )) );
     581                 : 
     582                 : /* -------------------------------------------------------------------- */
     583                 : /*      Try to collect simple insertion point.                          */
     584                 : /* -------------------------------------------------------------------- */
     585                 :     CPLXMLNode *psGeoLoc =  
     586               2 :         CPLGetXMLNode( psDoc, "Geoposition.Geoposition_Insert" );
     587                 : 
     588               2 :     if( psGeoLoc != NULL )
     589                 :     {
     590               0 :         bHaveGeoTransform = TRUE;
     591               0 :         adfGeoTransform[0] = atof(CPLGetXMLValue(psGeoLoc,"ULXMAP","0"));
     592               0 :         adfGeoTransform[1] = atof(CPLGetXMLValue(psGeoLoc,"XDIM","0"));
     593               0 :         adfGeoTransform[2] = 0.0;
     594               0 :         adfGeoTransform[3] = atof(CPLGetXMLValue(psGeoLoc,"ULYMAP","0"));
     595               0 :         adfGeoTransform[4] = 0.0;
     596               0 :         adfGeoTransform[5] = -atof(CPLGetXMLValue(psGeoLoc,"YDIM","0"));
     597                 :     }
     598                 : 
     599                 : /* -------------------------------------------------------------------- */
     600                 : /*      Collect GCPs.                                                   */
     601                 : /* -------------------------------------------------------------------- */
     602               2 :     psGeoLoc = CPLGetXMLNode( psDoc, "Geoposition.Geoposition_Points" );
     603                 : 
     604               2 :     if( psGeoLoc != NULL )
     605                 :     {
     606                 :         CPLXMLNode *psNode;                
     607                 : 
     608                 :         // count gcps.
     609               2 :         nGCPCount = 0;
     610              10 :         for( psNode = psGeoLoc->psChild; psNode != NULL;
     611                 :              psNode = psNode->psNext )
     612                 :         {
     613               8 :             if( EQUAL(psNode->pszValue,"Tie_Point") )
     614               8 :                 nGCPCount++ ;
     615                 :         }
     616                 : 
     617                 :         pasGCPList = (GDAL_GCP *) 
     618               2 :             CPLCalloc(sizeof(GDAL_GCP),nGCPCount);
     619                 :         
     620               2 :         nGCPCount = 0;
     621                 :         
     622              10 :         for( psNode = psGeoLoc->psChild; psNode != NULL;
     623                 :              psNode = psNode->psNext )
     624                 :         {
     625                 :             char  szID[32];
     626               8 :             GDAL_GCP   *psGCP = pasGCPList + nGCPCount;
     627                 :             
     628               8 :             if( !EQUAL(psNode->pszValue,"Tie_Point") )
     629               0 :                 continue;
     630                 : 
     631               8 :             nGCPCount++ ;
     632                 : 
     633               8 :             sprintf( szID, "%d", nGCPCount );
     634               8 :             psGCP->pszId = CPLStrdup( szID );
     635               8 :             psGCP->pszInfo = CPLStrdup("");
     636                 :             psGCP->dfGCPPixel = 
     637               8 :                 atof(CPLGetXMLValue(psNode,"TIE_POINT_DATA_X","0"))-0.5;
     638                 :             psGCP->dfGCPLine = 
     639               8 :                 atof(CPLGetXMLValue(psNode,"TIE_POINT_DATA_Y","0"))-0.5;
     640                 :             psGCP->dfGCPX = 
     641               8 :                 atof(CPLGetXMLValue(psNode,"TIE_POINT_CRS_X",""));
     642                 :             psGCP->dfGCPY = 
     643               8 :                 atof(CPLGetXMLValue(psNode,"TIE_POINT_CRS_Y",""));
     644                 :             psGCP->dfGCPZ = 
     645               8 :                 atof(CPLGetXMLValue(psNode,"TIE_POINT_CRS_Z",""));
     646                 :         }
     647                 :     }
     648                 : 
     649                 : /* -------------------------------------------------------------------- */
     650                 : /*      Collect the CRS.  For now we look only for EPSG codes.          */
     651                 : /* -------------------------------------------------------------------- */
     652                 :     const char *pszSRS = CPLGetXMLValue( 
     653                 :         psDoc, 
     654                 :         "Coordinate_Reference_System.Horizontal_CS.HORIZONTAL_CS_CODE", 
     655               2 :         NULL );
     656                 : 
     657               2 :     if( pszSRS != NULL )
     658                 :     {
     659               2 :         OGRSpatialReference oSRS;
     660               2 :         if( oSRS.SetFromUserInput( pszSRS ) == OGRERR_NONE )
     661                 :         {
     662               2 :             if( nGCPCount > 0 )
     663                 :             {
     664               2 :                 CPLFree(pszGCPProjection);
     665               2 :                 oSRS.exportToWkt( &(pszGCPProjection) );
     666                 :             }
     667                 :             else
     668                 :             {
     669               0 :                 char *pszProjection = NULL;
     670               0 :                 oSRS.exportToWkt( &pszProjection );
     671               0 :                 osProjection = pszProjection;
     672               0 :                 CPLFree( pszProjection );
     673                 :             }
     674               2 :         }
     675                 :     }
     676                 :     else  
     677                 :     { 
     678                 :         // Check underlying raster for SRS. We have cases where 
     679                 :         // HORIZONTAL_CS_CODE is empty and the underlying raster 
     680                 :         // is georeferenced (rprinceley).
     681               0 :         if ( poImageDS->GetProjectionRef() ) 
     682                 :         { 
     683               0 :             osProjection = poImageDS->GetProjectionRef(); 
     684                 :         } 
     685                 :     } 
     686                 : 
     687                 : /* -------------------------------------------------------------------- */
     688                 : /*      Translate other metadata of interest.                           */
     689                 : /* -------------------------------------------------------------------- */
     690                 :     static const char *apszMetadataTranslation[] = 
     691                 :         {
     692                 :             "Production", "", 
     693                 :             "Production.Facility", "FACILITY_", 
     694                 :             "Dataset_Sources.Source_Information.Scene_Source", "",
     695                 :             "Data_Processing", "",
     696                 :             "Image_Interpretation.Spectral_Band_Info", "SPECTRAL_", 
     697                 :             NULL, NULL
     698                 :         };
     699                 : 
     700               2 :     SetMetadataFromXML(psProduct, apszMetadataTranslation);
     701                 : 
     702                 : /* -------------------------------------------------------------------- */
     703                 : /*      Set Band metadata from the <Spectral_Band_Info> content         */
     704                 : /* -------------------------------------------------------------------- */
     705                 : 
     706                 :     CPLXMLNode *psImageInterpretationNode = 
     707               2 :         CPLGetXMLNode( psDoc, "Image_Interpretation" );
     708               2 :     if (psImageInterpretationNode != NULL)
     709                 :     {
     710               2 :         CPLXMLNode *psSpectralBandInfoNode = psImageInterpretationNode->psChild;
     711               6 :         while (psSpectralBandInfoNode != NULL)
     712                 :         {
     713               2 :             if (psSpectralBandInfoNode->eType == CXT_Element &&
     714                 :                 EQUAL(psSpectralBandInfoNode->pszValue, "Spectral_Band_Info"))
     715                 :             {
     716               2 :                 CPLXMLNode *psTag = psSpectralBandInfoNode->psChild;
     717               2 :                 int nBandIndex = 0;
     718              16 :                 while(psTag != NULL)
     719                 :                 {
     720              12 :                     if (psTag->eType == CXT_Element && psTag->psChild != NULL &&
     721                 :                         psTag->psChild->eType == CXT_Text && psTag->pszValue != NULL)
     722                 :                     {
     723              12 :                         if (EQUAL(psTag->pszValue, "BAND_INDEX"))
     724                 :                         {
     725               2 :                             nBandIndex = atoi(psTag->psChild->pszValue);
     726               2 :                             if (nBandIndex <= 0 ||
     727                 :                                 nBandIndex > poImageDS->GetRasterCount())
     728                 :                             {
     729                 :                                 CPLError(CE_Warning, CPLE_AppDefined,
     730               0 :                                          "Bad BAND_INDEX value : %s", psTag->psChild->pszValue);
     731               0 :                                 nBandIndex = 0;
     732                 :                             }
     733                 :                         }
     734              10 :                         else if (nBandIndex >= 1)
     735                 :                         {
     736                 :                             GetRasterBand(nBandIndex)->SetMetadataItem(
     737              10 :                                 psTag->pszValue, psTag->psChild->pszValue);
     738                 :                         }
     739                 :                     }
     740              12 :                     psTag = psTag->psNext;
     741                 :                 }
     742                 :             }
     743               2 :             psSpectralBandInfoNode = psSpectralBandInfoNode->psNext;
     744                 :         }
     745                 :     }
     746                 : 
     747                 : /* -------------------------------------------------------------------- */
     748                 : /*      Initialize any PAM information.                                 */
     749                 : /* -------------------------------------------------------------------- */
     750               2 :     SetDescription( osMDFilename );
     751               2 :     TryLoadXML();
     752                 : 
     753                 : /* -------------------------------------------------------------------- */
     754                 : /*      Check for overviews.                                            */
     755                 : /* -------------------------------------------------------------------- */
     756               2 :     oOvManager.Initialize( this, osMDFilename );
     757                 : 
     758               2 :     return TRUE;
     759                 : }
     760                 : 
     761                 : 
     762                 : /************************************************************************/
     763                 : /*               ReadImageInformation() DIMAP Version 2                 */
     764                 : /************************************************************************/
     765                 : 
     766               0 : int DIMAPDataset::ReadImageInformation2()
     767                 : {
     768               0 :     CPLXMLNode *psDoc = CPLGetXMLNode( psProductDim, "=Dimap_Document" );
     769               0 :     if( !psDoc )
     770               0 :         psDoc = CPLGetXMLNode( psProductDim, "=PHR_DIMAP_Document" );
     771                 : 
     772               0 :     CPLXMLNode *psImageAttributes = CPLGetXMLNode( psDoc, "Raster_Data.Raster_Dimensions" );
     773               0 :     if( psImageAttributes == NULL )
     774                 :     {
     775                 :   CPLError( CE_Failure, CPLE_OpenFailed, 
     776               0 :       "Failed to find <Raster_Dimensions> in document." );
     777               0 :   return FALSE;
     778                 :     }
     779                 : 
     780                 : /* -------------------------------------------------------------------- */
     781                 : /*      Get overall image information.                                  */
     782                 : /* -------------------------------------------------------------------- */
     783                 : #ifdef DEBUG
     784                 :     int nBands = 
     785               0 :         atoi(CPLGetXMLValue( psImageAttributes, "NBANDS", "-1" ));
     786                 : #endif
     787                 : 
     788                 :     nRasterXSize = 
     789               0 :         atoi(CPLGetXMLValue( psImageAttributes, "NCOLS", "-1" ));
     790                 :     nRasterYSize = 
     791               0 :         atoi(CPLGetXMLValue( psImageAttributes, "NROWS", "-1" ));
     792                 : 
     793                 : /* -------------------------------------------------------------------- */
     794                 : /*      Get the name of the underlying file.                            */
     795                 : /* -------------------------------------------------------------------- */
     796                 : 
     797                 :     /* If the data file was not in the product file, it should be here */
     798               0 :     if ( osImageDSFilename.size() == 0 )
     799                 :     {
     800                 :   const char *pszHref = CPLGetXMLValue(
     801               0 :                psDoc, "Raster_Data.Data_Access.Data_Files.Data_File.DATA_FILE_PATH.href", "" );
     802               0 :   if( strlen(pszHref) > 0 )
     803                 :   {
     804               0 :       CPLString osPath = CPLGetPath( osDIMAPFilename );
     805                 :       osImageDSFilename = 
     806               0 :     CPLFormFilename( osPath, pszHref, NULL );
     807                 :   }
     808                 :   else
     809                 :   {
     810                 :       CPLError( CE_Failure, CPLE_OpenFailed, 
     811               0 :           "Failed to find <DATA_FILE_PATH> in document." );
     812               0 :       return FALSE;
     813                 :   }
     814                 :     }
     815                 : 
     816                 : 
     817                 : /* -------------------------------------------------------------------- */
     818                 : /*      Try and open the file.                                          */
     819                 : /* -------------------------------------------------------------------- */
     820               0 :     poImageDS = (GDALDataset *) GDALOpen( osImageDSFilename, GA_ReadOnly );
     821               0 :     if( poImageDS == NULL )
     822                 :     {
     823               0 :         return FALSE;
     824                 :     }
     825                 : 
     826                 : 
     827                 : /* -------------------------------------------------------------------- */
     828                 : /*      Attach the bands.                                               */
     829                 : /* -------------------------------------------------------------------- */
     830                 :     int iBand;
     831               0 :     CPLAssert( nBands == poImageDS->GetRasterCount() );
     832                 : 
     833               0 :     for( iBand = 1; iBand <= poImageDS->GetRasterCount(); iBand++ )
     834               0 :         SetBand( iBand, new DIMAPWrapperRasterBand(poImageDS->GetRasterBand( iBand )) );
     835                 : 
     836                 : /* -------------------------------------------------------------------- */
     837                 : /*      Try to collect simple insertion point.                          */
     838                 : /* -------------------------------------------------------------------- */
     839                 :     CPLXMLNode *psGeoLoc =  
     840               0 :         CPLGetXMLNode( psDoc, "Geoposition.Geoposition_Insert" );
     841                 : 
     842               0 :     if( psGeoLoc != NULL )
     843                 :     {
     844               0 :         bHaveGeoTransform = TRUE;
     845               0 :         adfGeoTransform[0] = atof(CPLGetXMLValue(psGeoLoc,"ULXMAP","0"));
     846               0 :         adfGeoTransform[1] = atof(CPLGetXMLValue(psGeoLoc,"XDIM","0"));
     847               0 :         adfGeoTransform[2] = 0.0;
     848               0 :         adfGeoTransform[3] = atof(CPLGetXMLValue(psGeoLoc,"ULYMAP","0"));
     849               0 :         adfGeoTransform[4] = 0.0;
     850               0 :         adfGeoTransform[5] = -atof(CPLGetXMLValue(psGeoLoc,"YDIM","0"));
     851                 :     }
     852                 : 
     853                 : /* -------------------------------------------------------------------- */
     854                 : /*      Collect the CRS.  For now we look only for EPSG codes.          */
     855                 : /* -------------------------------------------------------------------- */
     856                 :     const char *pszSRS = CPLGetXMLValue( 
     857                 :         psDoc, 
     858                 :         "Coordinate_Reference_System.Projected_CRS..PROJECTED_CRS_CODE", 
     859               0 :         NULL );
     860                 : 
     861               0 :     if( pszSRS != NULL )
     862                 :     {
     863               0 :         OGRSpatialReference oSRS;
     864               0 :         if( oSRS.SetFromUserInput( pszSRS ) == OGRERR_NONE )
     865                 :         {
     866               0 :             if( nGCPCount > 0 )
     867                 :             {
     868               0 :                 CPLFree(pszGCPProjection);
     869               0 :                 oSRS.exportToWkt( &(pszGCPProjection) );
     870                 :             }
     871                 :             else
     872                 :             {
     873               0 :                 char *pszProjection = NULL;
     874               0 :                 oSRS.exportToWkt( &pszProjection );
     875               0 :                 osProjection = pszProjection;
     876               0 :                 CPLFree( pszProjection );
     877                 :             }
     878               0 :         }
     879                 :     }
     880                 :     else  
     881                 :     { 
     882                 :         // Check underlying raster for SRS. We have cases where 
     883                 :         // HORIZONTAL_CS_CODE is empty and the underlying raster 
     884                 :         // is georeferenced (rprinceley).
     885               0 :         if ( poImageDS->GetProjectionRef() ) 
     886                 :         { 
     887               0 :             osProjection = poImageDS->GetProjectionRef(); 
     888                 :         } 
     889                 :     } 
     890                 : 
     891                 : /* -------------------------------------------------------------------- */
     892                 : /*      Translate other metadata of interest: DIM_<product_name>.XML    */
     893                 : /* -------------------------------------------------------------------- */
     894                 : 
     895                 :     static const char *apszMetadataTranslationDim[] = 
     896                 :     {
     897                 :       "Product_Information.Delivery_Identification", "DATASET_",
     898                 :             "Product_Information.Producer_Information", "DATASET_",  
     899                 :       "Dataset_Sources.Source_Identification.Strip_Source", "",
     900                 :       "Processing_Information.Production_Facility", "FACILITY_",
     901                 :       "Processing_Information.Product_Settings", "",
     902                 :       "Processing_Information.Product_Settings.Geometric_Settings", "GEOMETRIC_",
     903                 :       "Quality_Assessment.Imaging_Quality_Measurement", "CLOUDCOVER_",
     904                 :             NULL, NULL
     905                 :         };
     906                 : 
     907               0 :     SetMetadataFromXML(psProductDim, apszMetadataTranslationDim);
     908                 : 
     909                 : /* -------------------------------------------------------------------- */
     910                 : /*      Translate other metadata of interest: STRIP_<product_name>.XML    */
     911                 : /* -------------------------------------------------------------------- */
     912                 : 
     913                 :     static const char *apszMetadataTranslationStrip[] = 
     914                 :     {
     915                 :       "Catalog.Full_Strip.Notations.Cloud_And_Quality_Notation.Data_Strip_Notation", "CLOUDCOVER_",
     916                 :       "Acquisition_Configuration.Platform_Configuration.Ephemeris_Configuration", "EPHEMERIS_",
     917                 :             NULL, NULL
     918                 :     };
     919                 : 
     920               0 :     SetMetadataFromXML(psProductStrip, apszMetadataTranslationStrip);
     921                 : 
     922                 : /* -------------------------------------------------------------------- */
     923                 : /*      Set Band metadata from the <Band_Radiance> and                  */
     924                 : /*                                <Band_Spectral_Range> content         */
     925                 : /* -------------------------------------------------------------------- */
     926                 :     
     927                 :     CPLXMLNode *psImageInterpretationNode = 
     928                 :         CPLGetXMLNode( psDoc, 
     929               0 :                "Radiometric_Data.Radiometric_Calibration.Instrument_Calibration.Band_Measurement_List" );
     930               0 :     if (psImageInterpretationNode != NULL)
     931                 :     {
     932               0 :         CPLXMLNode *psSpectralBandInfoNode = psImageInterpretationNode->psChild;
     933               0 :         while (psSpectralBandInfoNode != NULL)
     934                 :         {
     935               0 :             if (psSpectralBandInfoNode->eType == CXT_Element &&
     936                 :                 (EQUAL(psSpectralBandInfoNode->pszValue, "Band_Radiance") ||
     937                 :      EQUAL(psSpectralBandInfoNode->pszValue, "Band_Spectral_Range") ||
     938                 :      EQUAL(psSpectralBandInfoNode->pszValue, "Band_Solar_Irradiance")))
     939                 :             {
     940               0 :         CPLString osName;
     941                 :     
     942               0 :         if (EQUAL(psSpectralBandInfoNode->pszValue, "Band_Radiance"))
     943               0 :             osName = "RADIANCE_";
     944               0 :         else if (EQUAL(psSpectralBandInfoNode->pszValue, "Band_Spectral_Range"))
     945               0 :             osName = "SPECTRAL_RANGE_";
     946               0 :         else if (EQUAL(psSpectralBandInfoNode->pszValue, "Band_Solar_Irradiance"))
     947               0 :             osName = "SOLAR_IRRADIANCE_";
     948                 : 
     949               0 :                 CPLXMLNode *psTag = psSpectralBandInfoNode->psChild;
     950               0 :                 int nBandIndex = 0;
     951               0 :                 while(psTag != NULL)
     952                 :         {
     953               0 :                     if (psTag->eType == CXT_Element && psTag->psChild != NULL &&
     954                 :                         psTag->psChild->eType == CXT_Text && psTag->pszValue != NULL)
     955                 :                     {
     956               0 :                         if (EQUAL(psTag->pszValue, "BAND_ID"))
     957                 :                         {
     958                 :               /* BAND_ID is: B0, B1, .... P */
     959               0 :               if (!EQUAL(psTag->psChild->pszValue, "P")) 
     960                 :               {
     961               0 :             if (strlen(psTag->psChild->pszValue) < 2) /* shouldn't happen */
     962                 :             {
     963                 :                 CPLError(CE_Warning, CPLE_AppDefined,
     964               0 :                    "Bad BAND_INDEX value : %s", psTag->psChild->pszValue);
     965               0 :                 nBandIndex = 0;
     966                 :             }
     967                 :             else 
     968                 :             {
     969               0 :                 nBandIndex = atoi(&psTag->psChild->pszValue[1]) + 1; 
     970               0 :                 if (nBandIndex <= 0 ||
     971                 :               nBandIndex > poImageDS->GetRasterCount())
     972                 :                 {
     973                 :               CPLError(CE_Warning, CPLE_AppDefined,
     974               0 :                  "Bad BAND_INDEX value : %s", psTag->psChild->pszValue);
     975               0 :               nBandIndex = 0;
     976                 :                 }
     977                 :             }
     978                 :               }
     979                 :           }
     980               0 :           else if (nBandIndex >= 1)
     981                 :           {
     982               0 :             CPLString osMDName = osName;
     983               0 :         osMDName += psTag->pszValue;
     984                 : 
     985                 :         GetRasterBand(nBandIndex)->SetMetadataItem(
     986               0 :               osMDName, psTag->psChild->pszValue);
     987                 :           }
     988                 : 
     989                 :             }
     990               0 :             psTag = psTag->psNext;
     991               0 :         }
     992                 :           }
     993               0 :           psSpectralBandInfoNode = psSpectralBandInfoNode->psNext;
     994                 :       }
     995                 :     }
     996                 : 
     997                 : /* -------------------------------------------------------------------- */
     998                 : /*      Initialize any PAM information.                                 */
     999                 : /* -------------------------------------------------------------------- */
    1000               0 :     SetDescription( osMDFilename );
    1001               0 :     TryLoadXML();
    1002                 : 
    1003                 : /* -------------------------------------------------------------------- */
    1004                 : /*      Check for overviews.                                            */
    1005                 : /* -------------------------------------------------------------------- */
    1006               0 :     oOvManager.Initialize( this, osMDFilename );
    1007                 : 
    1008               0 :     return TRUE;
    1009                 : }
    1010                 : 
    1011                 : /************************************************************************/
    1012                 : /*                          SetMetadataFromXML()                        */
    1013                 : /************************************************************************/
    1014                 : 
    1015               2 : void DIMAPDataset::SetMetadataFromXML(CPLXMLNode *psProduct, const char *apszMetadataTranslation[])
    1016                 : {
    1017               2 :     CPLXMLNode *psDoc = CPLGetXMLNode( psProduct, "=Dimap_Document" );
    1018               2 :     if( psDoc == NULL ) 
    1019                 :     {
    1020               0 :       psDoc = CPLGetXMLNode( psProduct, "=PHR_DIMAP_Document" );
    1021                 :     }
    1022                 : 
    1023                 :     int iTrItem;
    1024                 :     
    1025              12 :     for( iTrItem = 0; apszMetadataTranslation[iTrItem] != NULL; iTrItem += 2 )
    1026                 :     {
    1027                 :         CPLXMLNode *psParent = 
    1028              10 :             CPLGetXMLNode( psDoc, apszMetadataTranslation[iTrItem] );
    1029                 : 
    1030              10 :         if( psParent == NULL )
    1031               2 :             continue;
    1032                 : 
    1033                 :         // hackey logic to support directly access a name/value entry
    1034                 :         // or a parent element with many name/values. 
    1035                 : 
    1036                 :         CPLXMLNode *psTarget;
    1037               8 :         if( psParent->psChild != NULL 
    1038                 :             && psParent->psChild->eType == CXT_Text )
    1039               0 :             psTarget = psParent;
    1040                 :         else
    1041               8 :             psTarget = psParent->psChild;
    1042                 : 
    1043              70 :         for( ; psTarget != NULL && psTarget != psParent; 
    1044                 :              psTarget = psTarget->psNext ) 
    1045                 :         {
    1046              62 :             if( psTarget->eType == CXT_Element
    1047                 :                 && psTarget->psChild != NULL)
    1048                 :             {
    1049              62 :     CPLString osName = apszMetadataTranslation[iTrItem+1];
    1050                 : 
    1051              62 :     if (psTarget->psChild->eType == CXT_Text)
    1052                 :     {       
    1053              54 :         osName += psTarget->pszValue;
    1054              54 :         SetMetadataItem( osName, psTarget->psChild->pszValue );
    1055               8 :     } else if (psTarget->psChild->eType == CXT_Attribute)
    1056                 :     { 
    1057                 :         /* find the tag value, at the end of the attributes */
    1058               2 :         CPLXMLNode *psNode = psTarget->psChild;
    1059               4 :         for( ; psNode != NULL;  psNode = psNode->psNext ) 
    1060                 :         {
    1061               2 :       if (psNode->eType == CXT_Attribute)
    1062               2 :           continue;
    1063               0 :       else if (psNode->eType == CXT_Text)
    1064                 :       {
    1065               0 :           osName += psTarget->pszValue;
    1066               0 :           SetMetadataItem( osName, psNode->pszValue );
    1067                 :       }   
    1068                 :         }
    1069              62 :     }
    1070                 :       } 
    1071                 :   }
    1072                 :     }
    1073               2 : }
    1074                 : 
    1075                 : /************************************************************************/
    1076                 : /*                            GetGCPCount()                             */
    1077                 : /************************************************************************/
    1078                 : 
    1079               1 : int DIMAPDataset::GetGCPCount()
    1080                 : 
    1081                 : {
    1082               1 :     return nGCPCount;
    1083                 : }
    1084                 : 
    1085                 : /************************************************************************/
    1086                 : /*                          GetGCPProjection()                          */
    1087                 : /************************************************************************/
    1088                 : 
    1089               1 : const char *DIMAPDataset::GetGCPProjection()
    1090                 : 
    1091                 : {
    1092               1 :     return pszGCPProjection;
    1093                 : }
    1094                 : 
    1095                 : /************************************************************************/
    1096                 : /*                               GetGCPs()                              */
    1097                 : /************************************************************************/
    1098                 : 
    1099               1 : const GDAL_GCP *DIMAPDataset::GetGCPs()
    1100                 : 
    1101                 : {
    1102               1 :     return pasGCPList;
    1103                 : }
    1104                 : 
    1105                 : /************************************************************************/
    1106                 : /*                         GDALRegister_DIMAP()                         */
    1107                 : /************************************************************************/
    1108                 : 
    1109             582 : void GDALRegister_DIMAP()
    1110                 : 
    1111                 : {
    1112                 :     GDALDriver  *poDriver;
    1113                 : 
    1114             582 :     if( GDALGetDriverByName( "DIMAP" ) == NULL )
    1115                 :     {
    1116             561 :         poDriver = new GDALDriver();
    1117                 :         
    1118             561 :         poDriver->SetDescription( "DIMAP" );
    1119                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
    1120             561 :                                    "SPOT DIMAP" );
    1121                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
    1122             561 :                                    "frmt_various.html#DIMAP" );
    1123             561 :         poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
    1124                 : 
    1125             561 :         poDriver->pfnOpen = DIMAPDataset::Open;
    1126             561 :         poDriver->pfnIdentify = DIMAPDataset::Identify;
    1127                 : 
    1128             561 :         GetGDALDriverManager()->RegisterDriver( poDriver );
    1129                 :     }
    1130             582 : }
    1131                 : 

Generated by: LCOV version 1.7