LCOV - code coverage report
Current view: directory - frmts/dimap - dimapdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 198 153 77.3 %
Date: 2011-12-18 Functions: 20 13 65.0 %

       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 22012 2011-03-22 23:47:56Z warmerdam $");
      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                 :     GDALDataset   *poImageDS;
      54                 : 
      55                 :     int           nGCPCount;
      56                 :     GDAL_GCP      *pasGCPList;
      57                 :     char          *pszGCPProjection;
      58                 : 
      59                 :     CPLString     osProjection;
      60                 : 
      61                 :     int           bHaveGeoTransform;
      62                 :     double        adfGeoTransform[6];
      63                 : 
      64                 :     char          **papszXMLDimapMetadata;
      65                 : 
      66                 :   protected:
      67                 :     virtual int         CloseDependentDatasets();
      68                 : 
      69                 :   public:
      70                 :     DIMAPDataset();
      71                 :           ~DIMAPDataset();
      72                 :     
      73                 :     virtual const char *GetProjectionRef(void);
      74                 :     virtual CPLErr GetGeoTransform( double * );
      75                 :     virtual int    GetGCPCount();
      76                 :     virtual const char *GetGCPProjection();
      77                 :     virtual const GDAL_GCP *GetGCPs();
      78                 :     virtual char **GetMetadata( const char *pszDomain );
      79                 :     virtual char **GetFileList(void);
      80                 : 
      81                 :     static int          Identify( GDALOpenInfo * );
      82                 :     static GDALDataset *Open( GDALOpenInfo * );
      83                 : 
      84                 :     CPLXMLNode *GetProduct() { return psProduct; }
      85                 : };
      86                 : 
      87                 : /************************************************************************/
      88                 : /* ==================================================================== */
      89                 : /*                        DIMAPWrapperRasterBand                        */
      90                 : /* ==================================================================== */
      91                 : /************************************************************************/
      92                 : class DIMAPWrapperRasterBand : public GDALProxyRasterBand
      93                 : {
      94                 :   GDALRasterBand* poBaseBand;
      95                 : 
      96                 :   protected:
      97             112 :     virtual GDALRasterBand* RefUnderlyingRasterBand() { return poBaseBand; }
      98                 : 
      99                 :   public:
     100               2 :     DIMAPWrapperRasterBand( GDALRasterBand* poBaseBand )
     101               2 :         {
     102               2 :             this->poBaseBand = poBaseBand;
     103               2 :             eDataType = poBaseBand->GetRasterDataType();
     104               2 :             poBaseBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
     105               2 :         }
     106               2 :     ~DIMAPWrapperRasterBand() {}
     107                 : };
     108                 : /************************************************************************/
     109                 : /* ==================================================================== */
     110                 : /*        DIMAPDataset        */
     111                 : /* ==================================================================== */
     112                 : /************************************************************************/
     113                 : 
     114                 : /************************************************************************/
     115                 : /*                             DIMAPDataset()                             */
     116                 : /************************************************************************/
     117                 : 
     118               2 : DIMAPDataset::DIMAPDataset()
     119                 : {
     120               2 :     psProduct = NULL;
     121                 : 
     122               2 :     nGCPCount = 0;
     123               2 :     pasGCPList = NULL;
     124               2 :     pszGCPProjection = CPLStrdup("");
     125                 : 
     126               2 :     poImageDS = NULL;
     127               2 :     bHaveGeoTransform = FALSE;
     128                 : 
     129               2 :     papszXMLDimapMetadata = NULL;
     130               2 : }
     131                 : 
     132                 : /************************************************************************/
     133                 : /*                            ~DIMAPDataset()                             */
     134                 : /************************************************************************/
     135                 : 
     136               2 : DIMAPDataset::~DIMAPDataset()
     137                 : 
     138                 : {
     139               2 :     FlushCache();
     140                 : 
     141               2 :     CPLDestroyXMLNode( psProduct );
     142                 : 
     143               2 :     CPLFree( pszGCPProjection );
     144               2 :     if( nGCPCount > 0 )
     145                 :     {
     146               2 :         GDALDeinitGCPs( nGCPCount, pasGCPList );
     147               2 :         CPLFree( pasGCPList );
     148                 :     }
     149                 : 
     150               2 :     CSLDestroy(papszXMLDimapMetadata);
     151                 : 
     152               2 :     CloseDependentDatasets();
     153               2 : }
     154                 : 
     155                 : 
     156                 : /************************************************************************/
     157                 : /*                        CloseDependentDatasets()                      */
     158                 : /************************************************************************/
     159                 : 
     160               2 : int DIMAPDataset::CloseDependentDatasets()
     161                 : {
     162               2 :     int bHasDroppedRef = GDALPamDataset::CloseDependentDatasets();
     163                 : 
     164               2 :     if( poImageDS != NULL )
     165                 :     {
     166               2 :         delete poImageDS;
     167               2 :         poImageDS = NULL;
     168               2 :         bHasDroppedRef = TRUE;
     169                 :     }
     170                 : 
     171                 : /* -------------------------------------------------------------------- */
     172                 : /*      Disconnect the bands so our destructor doesn't try and          */
     173                 : /*      delete them since they really belonged to poImageDS.            */
     174                 : /* -------------------------------------------------------------------- */
     175                 :     int iBand;
     176               4 :     for( iBand = 0; iBand < nBands; iBand++ )
     177               2 :         delete papoBands[iBand];
     178               2 :     nBands = 0;
     179                 : 
     180               2 :     return bHasDroppedRef;
     181                 : }
     182                 : 
     183                 : /************************************************************************/
     184                 : /*                            GetMetadata()                             */
     185                 : /*                                                                      */
     186                 : /*      We implement special support for fetching the full product      */
     187                 : /*      metadata as xml.                                                */
     188                 : /************************************************************************/
     189                 : 
     190               2 : char **DIMAPDataset::GetMetadata( const char *pszDomain )
     191                 : 
     192                 : {
     193               2 :     if( pszDomain && EQUAL(pszDomain,"xml:dimap") )
     194                 :     {
     195               0 :         if (papszXMLDimapMetadata == NULL)
     196                 :         {
     197               0 :             papszXMLDimapMetadata = (char **) CPLCalloc(sizeof(char*),2);
     198               0 :             papszXMLDimapMetadata[0] = CPLSerializeXMLTree( psProduct );
     199                 :         }
     200               0 :         return papszXMLDimapMetadata;
     201                 :     }
     202                 :     else
     203               2 :         return GDALPamDataset::GetMetadata( pszDomain );
     204                 : }
     205                 : 
     206                 : /************************************************************************/
     207                 : /*                          GetProjectionRef()                          */
     208                 : /************************************************************************/
     209                 : 
     210               0 : const char *DIMAPDataset::GetProjectionRef()
     211                 : 
     212                 : {
     213               0 :     if( strlen(osProjection) > 0 )
     214               0 :         return osProjection;
     215                 :     else
     216               0 :         return GDALPamDataset::GetProjectionRef();
     217                 : }
     218                 : 
     219                 : /************************************************************************/
     220                 : /*                          GetGeoTransform()                           */
     221                 : /************************************************************************/
     222                 : 
     223               0 : CPLErr DIMAPDataset::GetGeoTransform( double *padfGeoTransform )
     224                 : 
     225                 : {
     226               0 :     if( bHaveGeoTransform )
     227                 :     {
     228               0 :         memcpy( padfGeoTransform, adfGeoTransform, sizeof(double)*6 );
     229               0 :         return CE_None;
     230                 :     }
     231                 :     else
     232               0 :         return GDALPamDataset::GetGeoTransform( padfGeoTransform );
     233                 : }
     234                 : 
     235                 : /************************************************************************/
     236                 : /*                            GetFileList()                             */
     237                 : /************************************************************************/
     238                 : 
     239               0 : char **DIMAPDataset::GetFileList()
     240                 : 
     241                 : {
     242               0 :     char **papszFileList = GDALPamDataset::GetFileList();
     243               0 :     char **papszImageFiles = poImageDS->GetFileList();
     244                 : 
     245               0 :     papszFileList = CSLInsertStrings( papszFileList, -1, papszImageFiles );
     246                 : 
     247               0 :     CSLDestroy( papszImageFiles );
     248                 :     
     249               0 :     return papszFileList;
     250                 : }
     251                 : 
     252                 : /************************************************************************/
     253                 : /*                              Identify()                              */
     254                 : /************************************************************************/
     255                 : 
     256           12353 : int DIMAPDataset::Identify( GDALOpenInfo * poOpenInfo )
     257                 : 
     258                 : {
     259           12353 :     if( poOpenInfo->nHeaderBytes >= 100 )
     260                 :     {
     261            1391 :         if( strstr((const char *) poOpenInfo->pabyHeader, 
     262                 :                    "<Dimap_Document" ) == NULL )
     263            1389 :             return FALSE;
     264                 :         else
     265               2 :             return TRUE;
     266                 :     }
     267           10962 :     else if( poOpenInfo->bIsDirectory )
     268                 :     {
     269                 :         VSIStatBufL sStat;
     270                 : 
     271                 :         CPLString osMDFilename = 
     272              42 :             CPLFormCIFilename( poOpenInfo->pszFilename, "METADATA.DIM", NULL );
     273                 :         
     274              42 :         if( VSIStatL( osMDFilename, &sStat ) == 0 )
     275               0 :             return TRUE;
     276                 :         else
     277              42 :             return FALSE;
     278                 :     }
     279                 : 
     280           10920 :     return FALSE;
     281                 : }
     282                 : 
     283                 : /************************************************************************/
     284                 : /*                                Open()                                */
     285                 : /************************************************************************/
     286                 : 
     287            3107 : GDALDataset *DIMAPDataset::Open( GDALOpenInfo * poOpenInfo )
     288                 : 
     289                 : {
     290            3107 :     if( !Identify( poOpenInfo ) )
     291            3105 :         return NULL;
     292                 :         
     293                 : /* -------------------------------------------------------------------- */
     294                 : /*      Confirm the requested access is supported.                      */
     295                 : /* -------------------------------------------------------------------- */
     296               2 :     if( poOpenInfo->eAccess == GA_Update )
     297                 :     {
     298                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     299                 :                   "The DIMAP driver does not support update access to existing"
     300               0 :                   " datasets.\n" );
     301               0 :         return NULL;
     302                 :     }
     303                 : /* -------------------------------------------------------------------- */
     304                 : /*      Get the metadata filename.                                      */
     305                 : /* -------------------------------------------------------------------- */
     306               2 :     CPLString osMDFilename;
     307                 : 
     308               2 :     if( poOpenInfo->bIsDirectory )
     309                 :     {
     310                 :         osMDFilename = 
     311               0 :             CPLFormCIFilename( poOpenInfo->pszFilename, "METADATA.DIM", NULL );
     312                 :     }
     313                 :     else
     314               2 :         osMDFilename = poOpenInfo->pszFilename;
     315                 : 
     316                 : /* -------------------------------------------------------------------- */
     317                 : /*      Ingest the xml file.                                            */
     318                 : /* -------------------------------------------------------------------- */
     319                 :     CPLXMLNode *psProduct, *psImageAttributes;
     320                 : 
     321               2 :     psProduct = CPLParseXMLFile( osMDFilename );
     322               2 :     if( psProduct == NULL )
     323               0 :         return NULL;
     324                 : 
     325               2 :     CPLXMLNode *psDoc = CPLGetXMLNode( psProduct, "=Dimap_Document" );
     326               2 :     psImageAttributes = CPLGetXMLNode( psDoc, "Raster_Dimensions" );
     327               2 :     if( psImageAttributes == NULL )
     328                 :     {
     329                 :         CPLError( CE_Failure, CPLE_OpenFailed, 
     330               0 :                   "Failed to find <Raster_Dimensions> in document." );
     331               0 :         return NULL;
     332                 :     }
     333                 : 
     334                 : 
     335                 : /* -------------------------------------------------------------------- */
     336                 : /*      Create the dataset.                                             */
     337                 : /* -------------------------------------------------------------------- */
     338               2 :     DIMAPDataset *poDS = new DIMAPDataset();
     339                 : 
     340               2 :     poDS->psProduct = psProduct;
     341                 : 
     342                 : /* -------------------------------------------------------------------- */
     343                 : /*      Get overall image information.                                  */
     344                 : /* -------------------------------------------------------------------- */
     345                 : #ifdef DEBUG
     346                 :     int nBands = 
     347               4 :         atoi(CPLGetXMLValue( psImageAttributes, "NBANDS", "-1" ));
     348                 : #endif
     349                 : 
     350                 :     poDS->nRasterXSize = 
     351               2 :         atoi(CPLGetXMLValue( psImageAttributes, "NCOLS", "-1" ));
     352                 :     poDS->nRasterYSize = 
     353               2 :         atoi(CPLGetXMLValue( psImageAttributes, "NROWS", "-1" ));
     354                 : 
     355                 : /* -------------------------------------------------------------------- */
     356                 : /*      Get the name of the underlying file.                            */
     357                 : /* -------------------------------------------------------------------- */
     358                 :     const char *pszHref = CPLGetXMLValue(
     359               2 :         psDoc, "Data_Access.Data_File.DATA_FILE_PATH.href", "" );
     360               2 :     CPLString osPath = CPLGetPath(osMDFilename);
     361                 :     CPLString osImageFilename = 
     362               2 :         CPLFormFilename( osPath, pszHref, NULL );
     363                 :                                    
     364                 : /* -------------------------------------------------------------------- */
     365                 : /*      Try and open the file.                                          */
     366                 : /* -------------------------------------------------------------------- */
     367               2 :     poDS->poImageDS = (GDALDataset *) GDALOpen( osImageFilename, GA_ReadOnly );
     368               2 :     if( poDS->poImageDS == NULL )
     369                 :     {
     370               0 :         delete poDS;
     371               0 :         return NULL;
     372                 :     }
     373                 :         
     374                 : /* -------------------------------------------------------------------- */
     375                 : /*      Attach the bands.                                               */
     376                 : /* -------------------------------------------------------------------- */
     377                 :     int iBand;
     378               2 :     CPLAssert( nBands == poDS->poImageDS->GetRasterCount() );
     379                 : 
     380               4 :     for( iBand = 1; iBand <= poDS->poImageDS->GetRasterCount(); iBand++ )
     381               2 :         poDS->SetBand( iBand, new DIMAPWrapperRasterBand(poDS->poImageDS->GetRasterBand( iBand )) );
     382                 : 
     383                 : /* -------------------------------------------------------------------- */
     384                 : /*      Try to collect simple insertion point.                          */
     385                 : /* -------------------------------------------------------------------- */
     386                 :     CPLXMLNode *psGeoLoc =  
     387               2 :         CPLGetXMLNode( psDoc, "Geoposition.Geoposition_Insert" );
     388                 : 
     389               2 :     if( psGeoLoc != NULL )
     390                 :     {
     391               0 :         poDS->bHaveGeoTransform = TRUE;
     392               0 :         poDS->adfGeoTransform[0] = atof(CPLGetXMLValue(psGeoLoc,"ULXMAP","0"));
     393               0 :         poDS->adfGeoTransform[1] = atof(CPLGetXMLValue(psGeoLoc,"XDIM","0"));
     394               0 :         poDS->adfGeoTransform[2] = 0.0;
     395               0 :         poDS->adfGeoTransform[3] = atof(CPLGetXMLValue(psGeoLoc,"ULYMAP","0"));
     396               0 :         poDS->adfGeoTransform[4] = 0.0;
     397               0 :         poDS->adfGeoTransform[5] = -atof(CPLGetXMLValue(psGeoLoc,"YDIM","0"));
     398                 :     }
     399                 : 
     400                 : /* -------------------------------------------------------------------- */
     401                 : /*      Collect GCPs.                                                   */
     402                 : /* -------------------------------------------------------------------- */
     403               2 :     psGeoLoc = CPLGetXMLNode( psDoc, "Geoposition.Geoposition_Points" );
     404                 : 
     405               2 :     if( psGeoLoc != NULL )
     406                 :     {
     407                 :         CPLXMLNode *psNode;                
     408                 : 
     409                 :         // count gcps.
     410               2 :         poDS->nGCPCount = 0;
     411              10 :         for( psNode = psGeoLoc->psChild; psNode != NULL;
     412                 :              psNode = psNode->psNext )
     413                 :         {
     414               8 :             if( EQUAL(psNode->pszValue,"Tie_Point") )
     415               8 :                 poDS->nGCPCount++ ;
     416                 :         }
     417                 : 
     418                 :         poDS->pasGCPList = (GDAL_GCP *) 
     419               2 :             CPLCalloc(sizeof(GDAL_GCP),poDS->nGCPCount);
     420                 :         
     421               2 :         poDS->nGCPCount = 0;
     422                 :         
     423              10 :         for( psNode = psGeoLoc->psChild; psNode != NULL;
     424                 :              psNode = psNode->psNext )
     425                 :         {
     426                 :             char  szID[32];
     427               8 :             GDAL_GCP   *psGCP = poDS->pasGCPList + poDS->nGCPCount;
     428                 :             
     429               8 :             if( !EQUAL(psNode->pszValue,"Tie_Point") )
     430               0 :                 continue;
     431                 : 
     432               8 :             poDS->nGCPCount++ ;
     433                 : 
     434               8 :             sprintf( szID, "%d", poDS->nGCPCount );
     435               8 :             psGCP->pszId = CPLStrdup( szID );
     436               8 :             psGCP->pszInfo = CPLStrdup("");
     437                 :             psGCP->dfGCPPixel = 
     438               8 :                 atof(CPLGetXMLValue(psNode,"TIE_POINT_DATA_X","0"))-0.5;
     439                 :             psGCP->dfGCPLine = 
     440               8 :                 atof(CPLGetXMLValue(psNode,"TIE_POINT_DATA_Y","0"))-0.5;
     441                 :             psGCP->dfGCPX = 
     442               8 :                 atof(CPLGetXMLValue(psNode,"TIE_POINT_CRS_X",""));
     443                 :             psGCP->dfGCPY = 
     444               8 :                 atof(CPLGetXMLValue(psNode,"TIE_POINT_CRS_Y",""));
     445                 :             psGCP->dfGCPZ = 
     446               8 :                 atof(CPLGetXMLValue(psNode,"TIE_POINT_CRS_Z",""));
     447                 :         }
     448                 :     }
     449                 : 
     450                 : /* -------------------------------------------------------------------- */
     451                 : /*      Collect the CRS.  For now we look only for EPSG codes.          */
     452                 : /* -------------------------------------------------------------------- */
     453                 :     const char *pszSRS = CPLGetXMLValue( 
     454                 :         psDoc, 
     455                 :         "Coordinate_Reference_System.Horizontal_CS.HORIZONTAL_CS_CODE", 
     456               2 :         NULL );
     457                 : 
     458               2 :     if( pszSRS != NULL )
     459                 :     {
     460               2 :         OGRSpatialReference oSRS;
     461               2 :         if( oSRS.SetFromUserInput( pszSRS ) == OGRERR_NONE )
     462                 :         {
     463               2 :             if( poDS->nGCPCount > 0 )
     464                 :             {
     465               2 :                 CPLFree(poDS->pszGCPProjection);
     466               2 :                 oSRS.exportToWkt( &(poDS->pszGCPProjection) );
     467                 :             }
     468                 :             else
     469                 :             {
     470               0 :                 char *pszProjection = NULL;
     471               0 :                 oSRS.exportToWkt( &pszProjection );
     472               0 :                 poDS->osProjection = pszProjection;
     473               0 :                 CPLFree( pszProjection );
     474                 :             }
     475               2 :         }
     476                 :     }
     477                 :     else  
     478                 :     { 
     479                 :         // Check underlying raster for SRS. We have cases where 
     480                 :         // HORIZONTAL_CS_CODE is empty and the underlying raster 
     481                 :         // is georeferenced (rprinceley).
     482               0 :         if ( poDS->poImageDS->GetProjectionRef() ) 
     483                 :         { 
     484               0 :             poDS->osProjection = poDS->poImageDS->GetProjectionRef(); 
     485                 :         } 
     486                 :     } 
     487                 : 
     488                 : /* -------------------------------------------------------------------- */
     489                 : /*      Translate other metadata of interest.                           */
     490                 : /* -------------------------------------------------------------------- */
     491                 :     static const char *apszMetadataTranslation[] = 
     492                 :         {
     493                 :             "Production", "", 
     494                 :             "Production.Facility", "FACILITY_", 
     495                 :             "Dataset_Sources.Source_Information.Scene_Source", "",
     496                 :             "Data_Processing", "",
     497                 :             "Image_Interpretation.Spectral_Band_Info", "SPECTRAL_", 
     498                 :             NULL, NULL
     499                 :         };
     500                 : 
     501                 :     int iTrItem;
     502                 :     
     503              12 :     for( iTrItem = 0; apszMetadataTranslation[iTrItem] != NULL; iTrItem += 2 )
     504                 :     {
     505                 :         CPLXMLNode *psParent = 
     506              10 :             CPLGetXMLNode( psDoc, apszMetadataTranslation[iTrItem] );
     507                 : 
     508              10 :         if( psParent == NULL )
     509               2 :             continue;
     510                 : 
     511                 :         // hackey logic to support directly access a name/value entry
     512                 :         // or a parent element with many name/values. 
     513                 : 
     514                 :         CPLXMLNode *psTarget;
     515               8 :         if( psParent->psChild != NULL 
     516                 :             && psParent->psChild->eType == CXT_Text )
     517               0 :             psTarget = psParent;
     518                 :         else
     519               8 :             psTarget = psParent->psChild;
     520                 : 
     521              70 :         for( ; psTarget != NULL && psTarget != psParent; 
     522                 :              psTarget = psTarget->psNext ) 
     523                 :         {
     524              62 :             if( psTarget->eType == CXT_Element
     525                 :                 && psTarget->psChild != NULL
     526                 :                 && psTarget->psChild->eType == CXT_Text )
     527                 :             {
     528              54 :                 CPLString osName = apszMetadataTranslation[iTrItem+1];
     529                 : 
     530              54 :                 osName += psTarget->pszValue;
     531              54 :                 poDS->SetMetadataItem( osName, psTarget->psChild->pszValue );
     532                 :             }
     533                 :         }
     534                 :     }
     535                 : 
     536                 : /* -------------------------------------------------------------------- */
     537                 : /*      Set Band metadata from the <Spectral_Band_Info> content         */
     538                 : /* -------------------------------------------------------------------- */
     539                 : 
     540                 :     CPLXMLNode *psImageInterpretationNode = 
     541               2 :         CPLGetXMLNode( psDoc, "Image_Interpretation" );
     542               2 :     if (psImageInterpretationNode != NULL)
     543                 :     {
     544               2 :         CPLXMLNode *psSpectralBandInfoNode = psImageInterpretationNode->psChild;
     545               6 :         while (psSpectralBandInfoNode != NULL)
     546                 :         {
     547               2 :             if (psSpectralBandInfoNode->eType == CXT_Element &&
     548                 :                 EQUAL(psSpectralBandInfoNode->pszValue, "Spectral_Band_Info"))
     549                 :             {
     550               2 :                 CPLXMLNode *psTag = psSpectralBandInfoNode->psChild;
     551               2 :                 int nBandIndex = 0;
     552              16 :                 while(psTag != NULL)
     553                 :                 {
     554              12 :                     if (psTag->eType == CXT_Element && psTag->psChild != NULL &&
     555                 :                         psTag->psChild->eType == CXT_Text && psTag->pszValue != NULL)
     556                 :                     {
     557              12 :                         if (EQUAL(psTag->pszValue, "BAND_INDEX"))
     558                 :                         {
     559               2 :                             nBandIndex = atoi(psTag->psChild->pszValue);
     560               2 :                             if (nBandIndex <= 0 ||
     561                 :                                 nBandIndex > poDS->poImageDS->GetRasterCount())
     562                 :                             {
     563                 :                                 CPLError(CE_Warning, CPLE_AppDefined,
     564               0 :                                          "Bad BAND_INDEX value : %s", psTag->psChild->pszValue);
     565               0 :                                 nBandIndex = 0;
     566                 :                             }
     567                 :                         }
     568              10 :                         else if (nBandIndex >= 1)
     569                 :                         {
     570                 :                             poDS->GetRasterBand(nBandIndex)->SetMetadataItem(
     571              10 :                                 psTag->pszValue, psTag->psChild->pszValue);
     572                 :                         }
     573                 :                     }
     574              12 :                     psTag = psTag->psNext;
     575                 :                 }
     576                 :             }
     577               2 :             psSpectralBandInfoNode = psSpectralBandInfoNode->psNext;
     578                 :         }
     579                 :     }
     580                 : 
     581                 : /* -------------------------------------------------------------------- */
     582                 : /*      Initialize any PAM information.                                 */
     583                 : /* -------------------------------------------------------------------- */
     584               2 :     poDS->SetDescription( osMDFilename );
     585               2 :     poDS->TryLoadXML();
     586                 : 
     587                 : /* -------------------------------------------------------------------- */
     588                 : /*      Check for overviews.                                            */
     589                 : /* -------------------------------------------------------------------- */
     590               2 :     poDS->oOvManager.Initialize( poDS, osMDFilename );
     591                 : 
     592               2 :     return( poDS );
     593                 : }
     594                 : 
     595                 : /************************************************************************/
     596                 : /*                            GetGCPCount()                             */
     597                 : /************************************************************************/
     598                 : 
     599               1 : int DIMAPDataset::GetGCPCount()
     600                 : 
     601                 : {
     602               1 :     return nGCPCount;
     603                 : }
     604                 : 
     605                 : /************************************************************************/
     606                 : /*                          GetGCPProjection()                          */
     607                 : /************************************************************************/
     608                 : 
     609               1 : const char *DIMAPDataset::GetGCPProjection()
     610                 : 
     611                 : {
     612               1 :     return pszGCPProjection;
     613                 : }
     614                 : 
     615                 : /************************************************************************/
     616                 : /*                               GetGCPs()                              */
     617                 : /************************************************************************/
     618                 : 
     619               1 : const GDAL_GCP *DIMAPDataset::GetGCPs()
     620                 : 
     621                 : {
     622               1 :     return pasGCPList;
     623                 : }
     624                 : 
     625                 : /************************************************************************/
     626                 : /*                         GDALRegister_DIMAP()                         */
     627                 : /************************************************************************/
     628                 : 
     629             558 : void GDALRegister_DIMAP()
     630                 : 
     631                 : {
     632                 :     GDALDriver  *poDriver;
     633                 : 
     634             558 :     if( GDALGetDriverByName( "DIMAP" ) == NULL )
     635                 :     {
     636             537 :         poDriver = new GDALDriver();
     637                 :         
     638             537 :         poDriver->SetDescription( "DIMAP" );
     639                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     640             537 :                                    "SPOT DIMAP" );
     641                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     642             537 :                                    "frmt_various.html#DIMAP" );
     643             537 :         poDriver->SetMetadataItem( GDAL_DCAP_VIRTUALIO, "YES" );
     644                 : 
     645             537 :         poDriver->pfnOpen = DIMAPDataset::Open;
     646             537 :         poDriver->pfnIdentify = DIMAPDataset::Identify;
     647                 : 
     648             537 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     649                 :     }
     650             558 : }
     651                 : 

Generated by: LCOV version 1.7