LCOV - code coverage report
Current view: directory - frmts/til - tildataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 143 16 11.2 %
Date: 2010-01-09 Functions: 10 3 30.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: tildataset.cpp 17664 2009-09-21 21:16:45Z rouault $
       3                 :  *
       4                 :  * Project:  EarthWatch .TIL Driver
       5                 :  * Purpose:  Implementation of the TILDataset class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2009, Frank Warmerdam
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "gdal_pam.h"
      31                 : #include "gdal_proxy.h"
      32                 : #include "ogr_spatialref.h"
      33                 : #include "cpl_string.h"
      34                 : #include "vrtdataset.h"
      35                 : #include "cpl_multiproc.h"
      36                 : #include "cplkeywordparser.h"
      37                 : 
      38                 : CPL_CVSID("$Id: tildataset.cpp 17664 2009-09-21 21:16:45Z rouault $");
      39                 : 
      40                 : /************************************************************************/
      41                 : /* ==================================================================== */
      42                 : /*        TILDataset        */
      43                 : /* ==================================================================== */
      44                 : /************************************************************************/
      45                 : 
      46                 : class CPL_DLL TILDataset : public GDALPamDataset
      47                 : {
      48                 :     VRTDataset *poVRTDS;
      49                 :     std::vector<GDALDataset *> apoTileDS;
      50                 : 
      51                 :   public:
      52                 :     TILDataset();
      53                 :     ~TILDataset();
      54                 : 
      55                 :     static GDALDataset *Open( GDALOpenInfo * );
      56                 :     static int Identify( GDALOpenInfo *poOpenInfo );
      57                 : };
      58                 : 
      59                 : /************************************************************************/
      60                 : /* ==================================================================== */
      61                 : /*                            TILRasterBand                             */
      62                 : /* ==================================================================== */
      63                 : /************************************************************************/
      64                 : 
      65                 : class TILRasterBand : public GDALPamRasterBand
      66                 : {
      67                 :     friend class TILDataset;
      68                 : 
      69                 :     VRTRasterBand *poVRTBand;
      70                 : 
      71                 :   public:
      72                 :                    TILRasterBand( TILDataset *, int, VRTRasterBand * );
      73               0 :     virtual       ~TILRasterBand() {};
      74                 : 
      75                 :     virtual CPLErr IReadBlock( int, int, void * );
      76                 : };
      77                 : 
      78                 : /************************************************************************/
      79                 : /*                           TILRasterBand()                            */
      80                 : /************************************************************************/
      81                 : 
      82               0 : TILRasterBand::TILRasterBand( TILDataset *poTILDS, int nBand, 
      83               0 :                               VRTRasterBand *poVRTBand )
      84                 : 
      85                 : {
      86               0 :     this->poDS = poTILDS;
      87               0 :     this->poVRTBand = poVRTBand;
      88               0 :     this->nBand = nBand;
      89               0 :     this->eDataType = poVRTBand->GetRasterDataType();
      90                 : 
      91               0 :     poVRTBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
      92               0 : }
      93                 : 
      94                 : /************************************************************************/
      95                 : /*                             IReadBlock()                             */
      96                 : /************************************************************************/
      97                 : 
      98               0 : CPLErr TILRasterBand::IReadBlock( int iBlockX, int iBlockY, void *pBuffer )
      99                 : 
     100                 : {
     101               0 :     return poVRTBand->ReadBlock( iBlockX, iBlockY, pBuffer );
     102                 : }
     103                 : 
     104                 : /************************************************************************/
     105                 : /* ==================================================================== */
     106                 : /*                             TILDataset                               */
     107                 : /* ==================================================================== */
     108                 : /************************************************************************/
     109                 : 
     110                 : /************************************************************************/
     111                 : /*                             TILDataset()                             */
     112                 : /************************************************************************/
     113                 : 
     114               0 : TILDataset::TILDataset()
     115                 : 
     116                 : {
     117               0 :     poVRTDS = NULL;
     118               0 : }
     119                 : 
     120                 : /************************************************************************/
     121                 : /*                            ~TILDataset()                             */
     122                 : /************************************************************************/
     123                 : 
     124               0 : TILDataset::~TILDataset()
     125                 : 
     126                 : {
     127               0 :     if( poVRTDS )
     128               0 :         delete poVRTDS;
     129                 : 
     130               0 :     while( !apoTileDS.empty() )
     131                 :     {
     132               0 :         GDALClose( (GDALDatasetH) apoTileDS.back() );
     133               0 :         apoTileDS.pop_back();
     134                 :     }
     135               0 : }
     136                 : 
     137                 : /************************************************************************/
     138                 : /*                              Identify()                              */
     139                 : /************************************************************************/
     140                 : 
     141            9020 : int TILDataset::Identify( GDALOpenInfo *poOpenInfo )
     142                 : 
     143                 : {
     144            9020 :     if( poOpenInfo->nHeaderBytes < 200 
     145                 :         || !EQUAL(CPLGetExtension(poOpenInfo->pszFilename),"TIL") )
     146            9020 :         return FALSE;
     147                 : 
     148               0 :     if( strstr((const char *) poOpenInfo->pabyHeader,"numTiles") == NULL )
     149               0 :         return FALSE;
     150                 :     else
     151               0 :         return TRUE;
     152                 : }
     153                 : 
     154                 : /************************************************************************/
     155                 : /*                                Open()                                */
     156                 : /************************************************************************/
     157                 : 
     158            1291 : GDALDataset *TILDataset::Open( GDALOpenInfo * poOpenInfo )
     159                 : 
     160                 : {
     161            1291 :     if( !Identify( poOpenInfo ) )
     162            1291 :         return NULL;
     163                 : 
     164                 : /* -------------------------------------------------------------------- */
     165                 : /*      Confirm the requested access is supported.                      */
     166                 : /* -------------------------------------------------------------------- */
     167               0 :     if( poOpenInfo->eAccess == GA_Update )
     168                 :     {
     169                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     170                 :                   "The TIL driver does not support update access to existing"
     171               0 :                   " datasets.\n" );
     172               0 :         return NULL;
     173                 :     }
     174                 :     
     175               0 :     CPLString osDirname = CPLGetDirname(poOpenInfo->pszFilename);
     176                 : 
     177                 : /* -------------------------------------------------------------------- */
     178                 : /*      Try to find the corresponding .IMD file.                        */
     179                 : /* -------------------------------------------------------------------- */
     180                 :     char **papszIMD = GDALLoadIMDFile( poOpenInfo->pszFilename, 
     181               0 :                                        poOpenInfo->papszSiblingFiles );
     182                 : 
     183               0 :     if( papszIMD == NULL )
     184                 :     {
     185                 :         CPLError( CE_Failure, CPLE_OpenFailed,
     186               0 :                   "Unable to open .TIL dataset due to missing .IMD file." );
     187               0 :         return NULL;
     188                 :     }
     189                 : 
     190               0 :     if( CSLFetchNameValue( papszIMD, "numRows" ) == NULL
     191                 :         || CSLFetchNameValue( papszIMD, "numColumns" ) == NULL
     192                 :         || CSLFetchNameValue( papszIMD, "bitsPerPixel" ) == NULL )
     193                 :     {
     194                 :         CPLError( CE_Failure, CPLE_OpenFailed,
     195               0 :                   "Missing a required field in the .IMD file." );
     196               0 :         CSLDestroy( papszIMD );
     197               0 :         return NULL;
     198                 :     }
     199                 : 
     200                 : /* -------------------------------------------------------------------- */
     201                 : /*      Try to load and parse the .TIL file.                            */
     202                 : /* -------------------------------------------------------------------- */
     203               0 :     FILE *fp = VSIFOpenL( poOpenInfo->pszFilename, "r" );
     204                 :     
     205               0 :     if( fp == NULL )
     206                 :     {
     207               0 :         CSLDestroy( papszIMD );
     208               0 :         return NULL;
     209                 :     }
     210                 : 
     211               0 :     CPLKeywordParser oParser;
     212                 : 
     213               0 :     if( !oParser.Ingest( fp ) )
     214                 :     {
     215               0 :         VSIFCloseL( fp );
     216               0 :         CSLDestroy( papszIMD );
     217               0 :         return NULL;
     218                 :     }
     219                 : 
     220               0 :     VSIFCloseL( fp );
     221                 : 
     222               0 :     char **papszTIL = oParser.GetAllKeywords();
     223                 : 
     224                 : /* -------------------------------------------------------------------- */
     225                 : /*      Create a corresponding GDALDataset.                             */
     226                 : /* -------------------------------------------------------------------- */
     227                 :     TILDataset  *poDS;
     228                 : 
     229               0 :     poDS = new TILDataset();
     230                 : 
     231               0 :     poDS->nRasterXSize = atoi(CSLFetchNameValueDef(papszIMD,"numColumns","0"));
     232               0 :     poDS->nRasterYSize = atoi(CSLFetchNameValueDef(papszIMD,"numRows","0"));
     233               0 :     if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize))
     234                 :     {
     235               0 :         delete poDS;
     236               0 :         CSLDestroy( papszIMD );
     237               0 :         return NULL;
     238                 :     }
     239                 : 
     240                 : /* -------------------------------------------------------------------- */
     241                 : /*      We need to open one of the images in order to establish         */
     242                 : /*      details like the band count and types.                          */
     243                 : /* -------------------------------------------------------------------- */
     244                 :     GDALDataset *poTemplateDS;
     245               0 :     const char *pszFilename = CSLFetchNameValue( papszTIL, "TILE_1.filename" );
     246               0 :     if( pszFilename == NULL )
     247                 :     {
     248                 :         CPLError( CE_Failure, CPLE_AppDefined,
     249               0 :                   "Missing TILE_1.filename in .TIL file." );
     250               0 :         delete poDS;
     251               0 :         CSLDestroy( papszIMD );
     252               0 :         return NULL;
     253                 :     }
     254                 : 
     255                 :     // trim double quotes. 
     256               0 :     if( pszFilename[0] == '"' )
     257               0 :         pszFilename++;
     258               0 :     if( pszFilename[strlen(pszFilename)-1] == '"' )
     259               0 :         ((char *) pszFilename)[strlen(pszFilename)-1] = '\0';
     260                 : 
     261               0 :     CPLString osFilename = CPLFormFilename(osDirname, pszFilename, NULL);
     262               0 :     poTemplateDS = (GDALDataset *) GDALOpen( osFilename, GA_ReadOnly );
     263               0 :     if( poTemplateDS == NULL || poTemplateDS->GetRasterCount() == 0)
     264                 :     {
     265               0 :         delete poDS;
     266               0 :         CSLDestroy( papszIMD );
     267               0 :         if (poTemplateDS != NULL)
     268               0 :             GDALClose( poTemplateDS );
     269               0 :         return NULL;
     270                 :     }
     271                 : 
     272               0 :     GDALRasterBand *poTemplateBand = poTemplateDS->GetRasterBand(1);
     273               0 :     GDALDataType eDT = poTemplateBand->GetRasterDataType();
     274               0 :     int          nBandCount = poTemplateDS->GetRasterCount();
     275                 : 
     276               0 :     poTemplateBand = NULL;
     277               0 :     GDALClose( poTemplateDS );
     278                 : 
     279                 : /* -------------------------------------------------------------------- */
     280                 : /*      Create and initialize the corresponding VRT dataset used to     */
     281                 : /*      manage the tiled data access.                                   */
     282                 : /* -------------------------------------------------------------------- */
     283                 :     int iBand;
     284                 :      
     285               0 :     poDS->poVRTDS = new VRTDataset(poDS->nRasterXSize,poDS->nRasterYSize);
     286                 : 
     287               0 :     for( iBand = 0; iBand < nBandCount; iBand++ )
     288               0 :         poDS->poVRTDS->AddBand( eDT, NULL );
     289                 : 
     290                 :     /* Don't try to write a VRT file */
     291               0 :     poDS->poVRTDS->SetWritable(FALSE);
     292                 : 
     293                 : /* -------------------------------------------------------------------- */
     294                 : /*      Create band information objects.                                */
     295                 : /* -------------------------------------------------------------------- */
     296               0 :     for( iBand = 1; iBand <= nBandCount; iBand++ )
     297                 :         poDS->SetBand( iBand, 
     298                 :                        new TILRasterBand( poDS, iBand, 
     299               0 :                 (VRTRasterBand *) poDS->poVRTDS->GetRasterBand(iBand)));
     300                 : 
     301                 : /* -------------------------------------------------------------------- */
     302                 : /*      Add tiles as sources for each band.                             */
     303                 : /* -------------------------------------------------------------------- */
     304               0 :     int nTileCount = atoi(CSLFetchNameValueDef(papszTIL,"numTiles","0"));
     305               0 :     int iTile = 0;
     306                 : 
     307               0 :     for( iTile = 1; iTile <= nTileCount; iTile++ )
     308                 :     {
     309               0 :         CPLString osKey;
     310                 : 
     311               0 :         osKey.Printf( "TILE_%d.filename", iTile );
     312               0 :         pszFilename = CSLFetchNameValue( papszTIL, osKey );
     313               0 :         if( pszFilename == NULL )
     314                 :         {
     315                 :             CPLError( CE_Failure, CPLE_AppDefined,
     316               0 :                       "Missing TILE_%d.filename in .TIL file.", iTile );
     317               0 :             delete poDS;
     318               0 :             CSLDestroy( papszIMD );
     319               0 :             return NULL;
     320                 :         }
     321                 :         
     322                 :         // trim double quotes. 
     323               0 :         if( pszFilename[0] == '"' )
     324               0 :             pszFilename++;
     325               0 :         if( pszFilename[strlen(pszFilename)-1] == '"' )
     326               0 :             ((char *) pszFilename)[strlen(pszFilename)-1] = '\0';
     327               0 :         osFilename = CPLFormFilename(osDirname, pszFilename, NULL);
     328                 : 
     329               0 :         osKey.Printf( "TILE_%d.ULColOffset", iTile );
     330               0 :         int nULX = atoi(CSLFetchNameValueDef(papszTIL, osKey, "0"));
     331                 :         
     332               0 :         osKey.Printf( "TILE_%d.ULRowOffset", iTile );
     333               0 :         int nULY = atoi(CSLFetchNameValueDef(papszTIL, osKey, "0"));
     334                 : 
     335               0 :         osKey.Printf( "TILE_%d.LRColOffset", iTile );
     336               0 :         int nLRX = atoi(CSLFetchNameValueDef(papszTIL, osKey, "0"));
     337                 :         
     338               0 :         osKey.Printf( "TILE_%d.LRRowOffset", iTile );
     339               0 :         int nLRY = atoi(CSLFetchNameValueDef(papszTIL, osKey, "0"));
     340                 : 
     341                 : #ifdef notdef
     342                 :         GDALDataset *poTileDS = (GDALDataset *) 
     343                 :             GDALOpen(osFilename,GA_ReadOnly);
     344                 : #else
     345                 :         GDALDataset *poTileDS = 
     346                 :             new GDALProxyPoolDataset( osFilename, 
     347               0 :                                       nLRX - nULX + 1, nLRY - nULY + 1 );
     348                 : #endif
     349               0 :         if( poTileDS == NULL )
     350               0 :             continue;
     351                 : 
     352               0 :         poDS->apoTileDS.push_back( poTileDS );
     353                 : 
     354               0 :         for( iBand = 1; iBand <= nBandCount; iBand++ )
     355                 :         {
     356                 : #ifndef notdef
     357                 :             ((GDALProxyPoolDataset *) poTileDS)->
     358               0 :                 AddSrcBandDescription( eDT, nLRX - nULX + 1, 1 );
     359                 : #endif            
     360               0 :             GDALRasterBand *poSrcBand = poTileDS->GetRasterBand(iBand);
     361                 : 
     362                 :             VRTSourcedRasterBand *poVRTBand = 
     363               0 :                 (VRTSourcedRasterBand *) poDS->poVRTDS->GetRasterBand(iBand);
     364                 :             
     365                 :             poVRTBand->AddSimpleSource( poSrcBand,
     366                 :                                         0, 0, 
     367                 :                                         nLRX - nULX + 1, nLRY - nULY + 1, 
     368                 :                                         nULX, nULY, 
     369               0 :                                         nLRX - nULX + 1, nLRY - nULY + 1 );
     370                 :         }
     371                 :     }
     372                 : 
     373                 : /* -------------------------------------------------------------------- */
     374                 : /*      Set RPC and IMD metadata.                                       */
     375                 : /* -------------------------------------------------------------------- */
     376                 :     char **papszRPCMD = GDALLoadRPBFile( poOpenInfo->pszFilename,
     377               0 :                                          poOpenInfo->papszSiblingFiles );
     378                 :         
     379               0 :     if( papszRPCMD != NULL )
     380                 :     {
     381               0 :         poDS->SetMetadata( papszRPCMD, "RPC" );
     382               0 :         CSLDestroy( papszRPCMD );
     383                 :     }
     384                 : 
     385               0 :     if( papszIMD != NULL )
     386               0 :         poDS->SetMetadata( papszIMD, "IMD" );
     387                 : 
     388                 : /* -------------------------------------------------------------------- */
     389                 : /*      Cleanup                                                         */
     390                 : /* -------------------------------------------------------------------- */
     391               0 :     CSLDestroy( papszIMD );
     392                 : 
     393                 : /* -------------------------------------------------------------------- */
     394                 : /*      Initialize any PAM information.                                 */
     395                 : /* -------------------------------------------------------------------- */
     396               0 :     poDS->SetDescription( poOpenInfo->pszFilename );
     397               0 :     poDS->TryLoadXML();
     398                 : 
     399                 : /* -------------------------------------------------------------------- */
     400                 : /*      Check for overviews.                                            */
     401                 : /* -------------------------------------------------------------------- */
     402               0 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     403                 : 
     404               0 :     return( poDS );
     405                 : }
     406                 : 
     407                 : /************************************************************************/
     408                 : /*                          GDALRegister_TIL()                          */
     409                 : /************************************************************************/
     410                 : 
     411             338 : void GDALRegister_TIL()
     412                 : 
     413                 : {
     414                 :     GDALDriver  *poDriver;
     415                 : 
     416             338 :     if( GDALGetDriverByName( "TIL" ) == NULL )
     417                 :     {
     418             336 :         poDriver = new GDALDriver();
     419                 :         
     420             336 :         poDriver->SetDescription( "TIL" );
     421                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     422             336 :                                    "EarthWatch .TIL" );
     423                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     424             336 :                                    "frmt_til.html" );
     425                 :         
     426             336 :         poDriver->pfnOpen = TILDataset::Open;
     427             336 :         poDriver->pfnIdentify = TILDataset::Identify;
     428                 : 
     429             336 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     430                 :     }
     431             338 : }
     432                 : 
     433                 : 

Generated by: LCOV version 1.7