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

Generated by: LCOV version 1.7