LCOV - code coverage report
Current view: directory - frmts/pds - isis3dataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 306 219 71.6 %
Date: 2010-01-09 Functions: 15 13 86.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: isis3dataset.cpp 10646 2007-01-18 02:38:10Z warmerdam $
       3                 :  *
       4                 :  * Project:  ISIS Version 3 Driver
       5                 :  * Purpose:  Implementation of ISIS3Dataset
       6                 :  * Author:   Trent Hare (thare@usgs.gov)
       7                 :  *           Frank Warmerdam (warmerdam@pobox.com)
       8                 :  *
       9                 :  * NOTE: Original code authored by Trent and placed in the public domain as 
      10                 :  * per US government policy.  I have (within my rights) appropriated it and 
      11                 :  * placed it under the following license.  This is not intended to diminish 
      12                 :  * Trents contribution. 
      13                 :  ******************************************************************************
      14                 :  * Copyright (c) 2007, Frank Warmerdam <warmerdam@pobox.com>
      15                 :  * 
      16                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      17                 :  * copy of this software and associated documentation files (the "Software"),
      18                 :  * to deal in the Software without restriction, including without limitation
      19                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      20                 :  * and/or sell copies of the Software, and to permit persons to whom the
      21                 :  * Software is furnished to do so, subject to the following conditions:
      22                 :  *
      23                 :  * The above copyright notice and this permission notice shall be included
      24                 :  * in all copies or substantial portions of the Software.
      25                 :  *
      26                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      27                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      28                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      29                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      30                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      31                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      32                 :  * DEALINGS IN THE SOFTWARE.
      33                 :  ****************************************************************************/
      34                 : 
      35                 : #define NULL1 0
      36                 : #define NULL2 -32768
      37                 : //#define NULL3 0xFF7FFFFB //in hex
      38                 : //Same as ESRI_GRID_FLOAT_NO_DATA
      39                 : //#define NULL3 -340282346638528859811704183484516925440.0
      40                 : #define NULL3 -3.4028226550889044521e+38
      41                 : 
      42                 : #ifndef PI
      43                 : #  define PI 3.1415926535897932384626433832795
      44                 : #endif
      45                 : 
      46                 : #include "rawdataset.h"
      47                 : #include "ogr_spatialref.h"
      48                 : #include "cpl_string.h" 
      49                 : #include "nasakeywordhandler.h"
      50                 : 
      51                 : CPL_CVSID("$Id: isis3dataset.cpp 10646 2007-09-18 02:38:10Z xxxx $");
      52                 : 
      53                 : CPL_C_START
      54                 : void GDALRegister_ISIS3(void);
      55                 : CPL_C_END
      56                 : 
      57                 : class ISIS3Dataset;
      58                 : 
      59                 : /************************************************************************/
      60                 : /* ==================================================================== */
      61                 : /*             ISISTiledBand                    */
      62                 : /* ==================================================================== */
      63                 : /************************************************************************/
      64                 : 
      65                 : class ISISTiledBand : public GDALPamRasterBand
      66                 : {
      67                 :     FILE      *fpVSIL;
      68                 :     GIntBig   nFirstTileOffset;
      69                 :     GIntBig   nXTileOffset;
      70                 :     GIntBig   nYTileOffset;
      71                 :     int       bNativeOrder;
      72                 : 
      73                 :   public:
      74                 : 
      75                 :                 ISISTiledBand( GDALDataset *poDS, FILE *fpVSIL, 
      76                 :                                int nBand, GDALDataType eDT,
      77                 :                                int nTileXSize, int nTileYSize, 
      78                 :                                GIntBig nFirstTileOffset, 
      79                 :                                GIntBig nXTileOffset,
      80                 :                                GIntBig nYTileOffset,
      81                 :                                int bNativeOrder );
      82               2 :     virtual     ~ISISTiledBand() {}
      83                 : 
      84                 :     virtual CPLErr          IReadBlock( int, int, void * );
      85                 : };
      86                 : 
      87                 : /************************************************************************/
      88                 : /*                           ISISTiledBand()                            */
      89                 : /************************************************************************/
      90                 : 
      91               1 : ISISTiledBand::ISISTiledBand( GDALDataset *poDS, FILE *fpVSIL, 
      92                 :                               int nBand, GDALDataType eDT,
      93                 :                               int nTileXSize, int nTileYSize, 
      94                 :                               GIntBig nFirstTileOffset, 
      95                 :                               GIntBig nXTileOffset,
      96                 :                               GIntBig nYTileOffset,
      97               1 :                               int bNativeOrder )
      98                 : 
      99                 : {
     100               1 :     this->poDS = poDS;
     101               1 :     this->nBand = nBand;
     102               1 :     this->fpVSIL = fpVSIL;
     103               1 :     this->bNativeOrder = bNativeOrder;
     104               1 :     eDataType = eDT;
     105               1 :     nBlockXSize = nTileXSize;
     106               1 :     nBlockYSize = nTileYSize;
     107                 : 
     108                 :     int nBlocksPerRow = 
     109               1 :             (poDS->GetRasterXSize() + nTileXSize - 1) / nTileXSize;
     110                 :     int nBlocksPerColumn = 
     111               1 :             (poDS->GetRasterYSize() + nTileYSize - 1) / nTileYSize;
     112                 : 
     113               1 :     if( nXTileOffset == 0 && nYTileOffset == 0 )
     114                 :     {
     115               1 :         nXTileOffset = (GDALGetDataTypeSize(eDT)/8) * nTileXSize * nTileYSize;
     116               1 :         nYTileOffset = nXTileOffset * nBlocksPerRow;
     117                 :     }
     118                 : 
     119                 :     this->nFirstTileOffset = nFirstTileOffset
     120               1 :         + (nBand-1) * nYTileOffset * nBlocksPerColumn;
     121                 : 
     122               1 :     this->nXTileOffset = nXTileOffset;
     123               1 :     this->nYTileOffset = nYTileOffset;
     124               1 : }
     125                 : 
     126                 : /************************************************************************/
     127                 : /*                             IReadBlock()                             */
     128                 : /************************************************************************/
     129                 : 
     130               2 : CPLErr ISISTiledBand::IReadBlock( int nXBlock, int nYBlock, void *pImage )
     131                 : 
     132                 : {
     133                 :     GIntBig  nOffset = nFirstTileOffset + 
     134               2 :         nXBlock * nXTileOffset + nYBlock * nYTileOffset;
     135                 :     size_t nBlockSize = 
     136               2 :         (GDALGetDataTypeSize(eDataType)/8) * nBlockXSize * nBlockYSize;
     137                 : 
     138               2 :     if( VSIFSeekL( fpVSIL, nOffset, SEEK_SET ) != 0 )
     139                 :     {
     140                 :         CPLError( CE_Failure, CPLE_FileIO, 
     141                 :                   "Failed to seek to offset %d to read tile %d,%d.",
     142               0 :                   (int) nOffset, nXBlock, nYBlock );
     143               0 :         return CE_Failure;
     144                 :     }
     145                 : 
     146               2 :     if( VSIFReadL( pImage, 1, nBlockSize, fpVSIL ) != nBlockSize )
     147                 :     {
     148                 :         CPLError( CE_Failure, CPLE_FileIO, 
     149                 :                   "Failed to read %d bytes for tile %d,%d.",
     150               0 :                   (int) nBlockSize, nXBlock, nYBlock );
     151               0 :         return CE_Failure;
     152                 :     }
     153                 : 
     154               2 :     if( !bNativeOrder )
     155                 :         GDALSwapWords( pImage, GDALGetDataTypeSize(eDataType)/8, 
     156                 :                        nBlockXSize*nBlockYSize, 
     157               0 :                        GDALGetDataTypeSize(eDataType)/8 );
     158                 : 
     159               2 :     return CE_None;
     160                 : }
     161                 : 
     162                 : /************************************************************************/
     163                 : /* ==================================================================== */
     164                 : /*             ISISDataset                    */
     165                 : /* ==================================================================== */
     166                 : /************************************************************************/
     167                 : 
     168                 : class ISIS3Dataset : public RawDataset
     169                 : {
     170                 :     FILE  *fpImage; // image data file.
     171                 : 
     172                 :     CPLString   osExternalCube;
     173                 :     
     174                 :     NASAKeywordHandler  oKeywords;
     175                 :   
     176                 :     int         bGotTransform;
     177                 :     double      adfGeoTransform[6];
     178                 :   
     179                 :     CPLString   osProjection;
     180                 : 
     181                 :     int parse_label(const char *file, char *keyword, char *value);
     182                 :     int strstrip(char instr[], char outstr[], int position);
     183                 : 
     184                 :     CPLString   oTempResult;
     185                 : 
     186                 :     const char *GetKeyword( const char *pszPath, 
     187                 :                             const char *pszDefault = "");
     188                 :     const char *GetKeywordSub( const char *pszPath, 
     189                 :                                int iSubscript, 
     190                 :                                const char *pszDefault = "");
     191                 :     
     192                 : public:
     193                 :     ISIS3Dataset();
     194                 :     ~ISIS3Dataset();
     195                 :   
     196                 :     virtual CPLErr GetGeoTransform( double * padfTransform );
     197                 :     virtual const char *GetProjectionRef(void);
     198                 :   
     199                 :     virtual char **GetFileList();
     200                 : 
     201                 :     static int          Identify( GDALOpenInfo * );
     202                 :     static GDALDataset *Open( GDALOpenInfo * );
     203                 :     static GDALDataset *Create( const char * pszFilename,
     204                 :                                 int nXSize, int nYSize, int nBands,
     205                 :                                 GDALDataType eType, char ** papszParmList );
     206                 : };
     207                 : 
     208                 : 
     209                 : 
     210                 : /************************************************************************/
     211                 : /*                            ISIS3Dataset()                            */
     212                 : /************************************************************************/
     213                 : 
     214               2 : ISIS3Dataset::ISIS3Dataset()
     215                 : {
     216               2 :     fpImage = NULL;
     217               2 :     bGotTransform = FALSE;
     218               2 :     adfGeoTransform[0] = 0.0;
     219               2 :     adfGeoTransform[1] = 1.0;
     220               2 :     adfGeoTransform[2] = 0.0;
     221               2 :     adfGeoTransform[3] = 0.0;
     222               2 :     adfGeoTransform[4] = 0.0;
     223               2 :     adfGeoTransform[5] = 1.0;
     224               2 : }
     225                 : 
     226                 : /************************************************************************/
     227                 : /*                            ~ISIS3Dataset()                            */
     228                 : /************************************************************************/
     229                 : 
     230               4 : ISIS3Dataset::~ISIS3Dataset()
     231                 : 
     232                 : {
     233               2 :     FlushCache();
     234               2 :     if( fpImage != NULL )
     235               2 :         VSIFCloseL( fpImage );
     236               4 : }
     237                 : 
     238                 : /************************************************************************/
     239                 : /*                            GetFileList()                             */
     240                 : /************************************************************************/
     241                 : 
     242               0 : char **ISIS3Dataset::GetFileList()
     243                 : 
     244                 : {
     245               0 :     char **papszFileList = NULL;
     246                 : 
     247               0 :     papszFileList = GDALPamDataset::GetFileList();
     248                 : 
     249               0 :     if( strlen(osExternalCube) > 0 )
     250               0 :         papszFileList = CSLAddString( papszFileList, osExternalCube );
     251                 : 
     252               0 :     return papszFileList;
     253                 : }
     254                 : 
     255                 : /************************************************************************/
     256                 : /*                          GetProjectionRef()                          */
     257                 : /************************************************************************/
     258                 : 
     259               2 : const char *ISIS3Dataset::GetProjectionRef()
     260                 : 
     261                 : {
     262               2 :     if( strlen(osProjection) > 0 )
     263               2 :         return osProjection;
     264                 :     else
     265               0 :         return GDALPamDataset::GetProjectionRef();
     266                 : }
     267                 : 
     268                 : /************************************************************************/
     269                 : /*                          GetGeoTransform()                           */
     270                 : /************************************************************************/
     271                 : 
     272               2 : CPLErr ISIS3Dataset::GetGeoTransform( double * padfTransform )
     273                 : 
     274                 : {
     275               2 :     if( bGotTransform )
     276                 :     {
     277               2 :         memcpy( padfTransform, adfGeoTransform, sizeof(double) * 6 );
     278               2 :         return CE_None;
     279                 :     }
     280                 :     else
     281                 :     {
     282               0 :         return GDALPamDataset::GetGeoTransform( padfTransform );
     283                 :     }
     284                 : }
     285                 : 
     286                 : /************************************************************************/
     287                 : /*                              Identify()                              */
     288                 : /************************************************************************/
     289            9031 : int ISIS3Dataset::Identify( GDALOpenInfo * poOpenInfo )
     290                 :     
     291                 : {
     292            9031 :     if( poOpenInfo->pabyHeader != NULL
     293                 :         && strstr((const char *)poOpenInfo->pabyHeader,"IsisCube") != NULL )
     294               2 :         return TRUE;
     295                 :     else
     296            9029 :         return FALSE;
     297                 : }
     298                 : 
     299                 : /************************************************************************/
     300                 : /*                                Open()                                */
     301                 : /************************************************************************/
     302                 : 
     303            1302 : GDALDataset *ISIS3Dataset::Open( GDALOpenInfo * poOpenInfo )
     304                 : {
     305                 : /* -------------------------------------------------------------------- */
     306                 : /*      Does this look like a CUBE dataset?                             */
     307                 : /* -------------------------------------------------------------------- */
     308            1302 :     if( !Identify( poOpenInfo ) )
     309            1300 :         return NULL;
     310                 : 
     311                 : /* -------------------------------------------------------------------- */
     312                 : /*      Open the file using the large file API.                         */
     313                 : /* -------------------------------------------------------------------- */
     314               2 :     FILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
     315                 : 
     316               2 :     if( fpQube == NULL )
     317               0 :         return NULL;
     318                 : 
     319                 :     ISIS3Dataset  *poDS;
     320                 : 
     321               2 :     poDS = new ISIS3Dataset();
     322                 : 
     323               2 :     if( ! poDS->oKeywords.Ingest( fpQube, 0 ) )
     324                 :     {
     325               0 :         VSIFCloseL( fpQube );
     326               0 :         delete poDS;
     327               0 :         return NULL;
     328                 :     }
     329                 :     
     330               2 :     VSIFCloseL( fpQube );
     331                 : 
     332                 : /* -------------------------------------------------------------------- */
     333                 : /*  Assume user is pointing to label (ie .lbl) file for detached option */
     334                 : /* -------------------------------------------------------------------- */
     335                 :     //  Image can be inline or detached and point to an image name
     336                 :     //  the Format can be Tiled or Raw
     337                 :     //  Object = Core
     338                 :     //      StartByte   = 65537
     339                 :     //      Format      = Tile
     340                 :     //      TileSamples = 128
     341                 :     //      TileLines   = 128
     342                 :     //OR-----
     343                 :     //  Object = Core
     344                 :     //      StartByte = 1
     345                 :     //      ^Core     = r0200357_detatched.cub
     346                 :     //      Format    = BandSequential
     347                 :     //OR-----
     348                 :     //  Object = Core
     349                 :     //      StartByte = 1
     350                 :     //      ^Core     = r0200357_detached_tiled.cub
     351                 :     //      Format      = Tile
     352                 :     //      TileSamples = 128
     353                 :     //      TileLines   = 128
     354                 :     
     355                 : /* -------------------------------------------------------------------- */
     356                 : /*      What file contains the actual data?                             */
     357                 : /* -------------------------------------------------------------------- */
     358               2 :     const char *pszCore = poDS->GetKeyword( "IsisCube.Core.^Core" );
     359               2 :     CPLString osQubeFile;
     360                 : 
     361               2 :     if( EQUAL(pszCore,"") )
     362               1 :         osQubeFile = poOpenInfo->pszFilename;
     363                 :     else
     364                 :     {
     365               1 :         CPLString osPath = CPLGetPath( poOpenInfo->pszFilename );
     366               1 :         osQubeFile = CPLFormFilename( osPath, pszCore, NULL );
     367               1 :         poDS->osExternalCube = osQubeFile;
     368                 :     }
     369                 : 
     370                 : /* -------------------------------------------------------------------- */
     371                 : /*      Check if file an ISIS3 header file?  Read a few lines of text   */
     372                 : /*      searching for something starting with nrows or ncols.           */
     373                 : /* -------------------------------------------------------------------- */
     374               2 :     GDALDataType eDataType = GDT_Byte;
     375               2 :     OGRSpatialReference oSRS;
     376                 : 
     377               2 :     int nRows = -1;
     378               2 :     int nCols = -1;
     379               2 :     int nBands = 1;
     380               2 :     int nSkipBytes = 0;
     381               2 :     int tileSizeX = 0;
     382               2 :     int tileSizeY = 0;
     383               2 :     double dfULXMap=0.5;
     384               2 :     double dfULYMap = 0.5;
     385               2 :     double dfXDim = 1.0;
     386               2 :     double dfYDim = 1.0;
     387               2 :     double scaleFactor = 1.0;
     388               2 :     double dfNoData = 0.0;
     389               2 :     int bNoDataSet = FALSE;
     390               2 :     char chByteOrder = 'M';  //default to MSB
     391               2 :     char szLayout[32] = "BandSequential"; //default to band seq.
     392                 :     const char *target_name; //planet name
     393                 :     //projection parameters
     394                 :     const char *map_proj_name;
     395               2 :     int bProjectionSet = TRUE;
     396                 :     char proj_target_name[200]; 
     397                 :     char geog_name[60];  
     398                 :     char datum_name[60];  
     399                 :     char sphere_name[60];
     400               2 :     char bIsGeographic = TRUE;
     401               2 :     double semi_major = 0.0;
     402               2 :     double semi_minor = 0.0;
     403               2 :     double iflattening = 0.0;
     404               2 :     float center_lat = 0.0;
     405               2 :     float center_lon = 0.0;
     406               2 :     float first_std_parallel = 0.0;
     407               2 :     float second_std_parallel = 0.0;
     408                 :     double radLat, localRadius;
     409                 :     FILE  *fp;
     410                 : 
     411                 :     /*************   Skipbytes     *****************************/
     412               2 :     nSkipBytes = atoi(poDS->GetKeyword("IsisCube.Core.StartByte","")) - 1;
     413                 : 
     414                 :     /*******   Grab format type (BandSequential, Tiled)  *******/
     415                 :     const char *value;
     416                 : 
     417               2 :     value = poDS->GetKeyword( "IsisCube.Core.Format", "" );
     418               2 :     if (EQUAL(value,"Tile") )  { //Todo
     419               1 :         strcpy(szLayout,"Tiled");
     420                 :        /******* Get Tile Sizes *********/
     421               1 :        tileSizeX = atoi(poDS->GetKeyword("IsisCube.Core.TileSamples",""));
     422               1 :        tileSizeY = atoi(poDS->GetKeyword("IsisCube.Core.TileLines",""));
     423               1 :        if (tileSizeX <= 0 || tileSizeY <= 0)
     424                 :        {
     425                 :            CPLError( CE_Failure, CPLE_OpenFailed, "Wrong tile dimensions : %d x %d",
     426               0 :                      tileSizeX, tileSizeY);
     427               0 :            delete poDS;
     428               0 :            return NULL;
     429                 :        }
     430                 :     }
     431               1 :     else if (EQUAL(value,"BandSequential") )
     432               1 :         strcpy(szLayout,"BSQ");
     433                 :     else {
     434                 :         CPLError( CE_Failure, CPLE_OpenFailed, 
     435               0 :                   "%s layout not supported. Abort\n\n", value);
     436               0 :         delete poDS;
     437               0 :         return NULL;
     438                 :     }
     439                 : 
     440                 :     /***********   Grab samples lines band ************/
     441               2 :     nCols = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Samples",""));
     442               2 :     nRows = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Lines",""));
     443               2 :     nBands = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Bands",""));
     444                 :      
     445                 :     /****** Grab format type - ISIS3 only supports 8,U16,S16,32 *****/
     446                 :     const char *itype;
     447                 : 
     448               2 :     itype = poDS->GetKeyword( "IsisCube.Core.Pixels.Type" );
     449               2 :     if (EQUAL(itype,"UnsignedByte") ) {
     450               1 :         eDataType = GDT_Byte;
     451               1 :         dfNoData = NULL1;
     452               1 :         bNoDataSet = TRUE;
     453                 :     }
     454               1 :     else if (EQUAL(itype,"UnsignedWord") ) {
     455               0 :         eDataType = GDT_UInt16;
     456               0 :         dfNoData = NULL1;
     457               0 :         bNoDataSet = TRUE;
     458                 :     }
     459               1 :     else if (EQUAL(itype,"SignedWord") ) {
     460               1 :         eDataType = GDT_Int16;
     461               1 :         dfNoData = NULL2;
     462               1 :         bNoDataSet = TRUE;
     463                 :     }
     464               0 :     else if (EQUAL(itype,"Real") || EQUAL(value,"") ) {
     465               0 :         eDataType = GDT_Float32;
     466               0 :         dfNoData = NULL3;
     467               0 :         bNoDataSet = TRUE;
     468                 :     }
     469                 :     else {
     470                 :         CPLError( CE_Failure, CPLE_OpenFailed, 
     471               0 :                   "%s layout type not supported. Abort\n\n", itype);
     472               0 :         delete poDS;
     473               0 :         return NULL;
     474                 :     }
     475                 : 
     476                 :     /***********   Grab samples lines band ************/
     477               2 :     value = poDS->GetKeyword( "IsisCube.Core.Pixels.ByteOrder");
     478               2 :     if (EQUAL(value,"Lsb"))
     479               2 :         chByteOrder = 'I';
     480                 :     
     481                 :     /***********   Grab Cellsize ************/
     482               2 :     value = poDS->GetKeyword("IsisCube.Mapping.PixelResolution");
     483               2 :     if (strlen(value) > 0 ) {
     484               2 :         dfXDim = atof(value); /* values are in meters */
     485               2 :         dfYDim = -atof(value);
     486                 :     }
     487                 :     
     488                 :     /***********   Grab UpperLeftCornerY ************/
     489               2 :     value = poDS->GetKeyword("IsisCube.Mapping.UpperLeftCornerY");
     490               2 :     if (strlen(value) > 0) {
     491               2 :         dfULYMap = atof(value);
     492                 :     }
     493                 :      
     494                 :     /***********   Grab UpperLeftCornerX ************/
     495               2 :     value = poDS->GetKeyword("IsisCube.Mapping.UpperLeftCornerX");
     496               2 :     if( strlen(value) > 0 ) {
     497               2 :         dfULXMap = atof(value);
     498                 :     }
     499                 :      
     500                 :     /***********  Grab TARGET_NAME  ************/
     501                 :     /**** This is the planets name i.e. Mars ***/
     502               2 :     target_name = poDS->GetKeyword("IsisCube.Mapping.TargetName");
     503                 :      
     504                 :     /***********   Grab MAP_PROJECTION_TYPE ************/
     505                 :     map_proj_name = 
     506               2 :         poDS->GetKeyword( "IsisCube.Mapping.ProjectionName");
     507                 : 
     508                 :     /***********   Grab SEMI-MAJOR ************/
     509                 :     semi_major = 
     510               2 :         atof(poDS->GetKeyword( "IsisCube.Mapping.EquatorialRadius"));
     511                 : 
     512                 :     /***********   Grab semi-minor ************/
     513                 :     semi_minor = 
     514               2 :         atof(poDS->GetKeyword( "IsisCube.Mapping.PolarRadius"));
     515                 : 
     516                 :     /***********   Grab CENTER_LAT ************/
     517                 :     center_lat = 
     518               2 :         atof(poDS->GetKeyword( "IsisCube.Mapping.CenterLatitude"));
     519                 : 
     520                 :     /***********   Grab CENTER_LON ************/
     521                 :     center_lon = 
     522               2 :         atof(poDS->GetKeyword( "IsisCube.Mapping.CenterLongitude"));
     523                 : 
     524                 :     /***********   Grab 1st std parallel ************/
     525                 :     first_std_parallel = 
     526               2 :         atof(poDS->GetKeyword( "IsisCube.Mapping.FirstStandardParallel"));
     527                 : 
     528                 :     /***********   Grab 2nd std parallel ************/
     529                 :     second_std_parallel = 
     530               2 :         atof(poDS->GetKeyword( "IsisCube.Mapping.SecondStandardParallel"));
     531                 :      
     532                 :     /***********   Grab scaleFactor ************/
     533                 :     scaleFactor = 
     534               2 :         atof(poDS->GetKeyword( "IsisCube.Mapping.scaleFactor"));
     535                 :      
     536                 :     /*** grab      LatitudeType = Planetographic ****/
     537                 :     // Need to further study how ocentric/ographic will effect the gdal library
     538                 :     // So far we will use this fact to define a sphere or ellipse for some 
     539                 :     // projections
     540                 : 
     541                 :     // Frank - may need to talk this over
     542               2 :     value = poDS->GetKeyword("IsisCube.Mapping.LatitudeType");
     543               2 :     if (EQUAL( value, "\"Planetocentric\"" ))
     544               0 :         bIsGeographic = FALSE; 
     545                 :      
     546                 :     //Set oSRS projection and parameters
     547                 :     //############################################################
     548                 :     //ISIS3 Projection types
     549                 :     //  Equirectangular 
     550                 :     //  LambertConformal 
     551                 :     //  Mercator 
     552                 :     //  ObliqueCylindrical //Todo
     553                 :     //  Orthographic 
     554                 :     //  PolarStereographic 
     555                 :     //  SimpleCylindrical 
     556                 :     //  Sinusoidal 
     557                 :     //  TransverseMercator
     558                 :     
     559                 : #ifdef DEBUG
     560                 :     CPLDebug( "ISIS3", "using projection %s", map_proj_name);
     561                 : #endif
     562                 : 
     563               4 :     if ((EQUAL( map_proj_name, "Equirectangular" )) ||
     564                 :         (EQUAL( map_proj_name, "SimpleCylindrical" )) )  {
     565               2 :         oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 );
     566               0 :     } else if (EQUAL( map_proj_name, "Orthographic" )) {
     567               0 :         oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 );
     568               0 :     } else if (EQUAL( map_proj_name, "Sinusoidal" )) {
     569               0 :         oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 );
     570               0 :     } else if (EQUAL( map_proj_name, "Mercator" )) {
     571               0 :         oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, scaleFactor, 0, 0 );
     572               0 :     } else if (EQUAL( map_proj_name, "PolarStereographic" )) {
     573               0 :         oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, scaleFactor, 0, 0 );
     574               0 :     } else if (EQUAL( map_proj_name, "TransverseMercator" )) {
     575               0 :         oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, scaleFactor, 0, 0 );
     576               0 :     } else if (EQUAL( map_proj_name, "LambertConformal" )) {
     577               0 :         oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 );
     578                 :     } else {
     579                 :         CPLDebug( "ISIS3",
     580                 :                   "Dataset projection %s is not supported. Continuing...",
     581               0 :                   map_proj_name );
     582               0 :         bProjectionSet = FALSE;
     583                 :     }
     584                 : 
     585               2 :     if (bProjectionSet) {
     586                 :         //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword
     587               2 :         strcpy(proj_target_name, map_proj_name);
     588               2 :         strcat(proj_target_name, " ");
     589               2 :         strcat(proj_target_name, target_name);
     590               2 :         oSRS.SetProjCS(proj_target_name); //set ProjCS keyword
     591                 :      
     592                 :         //The geographic/geocentric name will be the same basic name as the body name
     593                 :         //'GCS' = Geographic/Geocentric Coordinate System
     594               2 :         strcpy(geog_name, "GCS_");
     595               2 :         strcat(geog_name, target_name);
     596                 :         
     597                 :         //The datum name will be the same basic name as the planet
     598               2 :         strcpy(datum_name, "D_");
     599               2 :         strcat(datum_name, target_name);
     600                 :      
     601               2 :         strcpy(sphere_name, target_name);
     602                 :         //strcat(sphere_name, "_IAU_IAG");  //Might not be IAU defined so don't add
     603                 :           
     604                 :         //calculate inverse flattening from major and minor axis: 1/f = a/(a-b)
     605               2 :         if ((semi_major - semi_minor) < 0.0000001) 
     606               0 :            iflattening = 0;
     607                 :         else
     608               2 :            iflattening = semi_major / (semi_major - semi_minor);
     609                 :      
     610                 :         //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility
     611                 :         //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally
     612               2 :         if ( ( (EQUAL( map_proj_name, "Stereographic" ) && (fabs(center_lat) == 90)) ) || 
     613                 :              (EQUAL( map_proj_name, "PolarStereographic" )) )  
     614                 :          {
     615               0 :             if (bIsGeographic) { 
     616                 :                 //Geograpraphic, so set an ellipse
     617                 :                 oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
     618                 :                                 semi_major, iflattening, 
     619               0 :                                "Reference_Meridian", 0.0 );
     620                 :             } else {
     621                 :               //Geocentric, so force a sphere using the semi-minor axis. I hope... 
     622               0 :               strcat(sphere_name, "_polarRadius");
     623                 :               oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
     624                 :                               semi_minor, 0.0, 
     625               0 :                               "Reference_Meridian", 0.0 );
     626                 :             }
     627                 :         }
     628               2 :         else if ( (EQUAL( map_proj_name, "SimpleCylindrical" )) || 
     629                 :                    (EQUAL( map_proj_name, "Orthographic" )) || 
     630                 :                  (EQUAL( map_proj_name, "Stereographic" )) || 
     631                 :                  (EQUAL( map_proj_name, "Sinusoidal" )) ) {
     632                 :             //isis uses the sphereical equation for these projections so force a sphere
     633                 :             oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
     634                 :                             semi_major, 0.0, 
     635               0 :                             "Reference_Meridian", 0.0 );
     636                 :         } 
     637               2 :         else if  (EQUAL( map_proj_name, "Equirectangular" )) { 
     638                 :             //Calculate localRadius using ISIS3 simple elliptical method 
     639                 :             //  not the more standard Radius of Curvature method
     640                 :             //PI = 4 * atan(1);
     641               2 :             radLat = center_lat * PI / 180;  // in radians
     642                 :             localRadius = semi_major * semi_minor / sqrt(pow(semi_minor*cos(radLat),2) 
     643               2 :                           + pow(semi_major*sin(radLat),2) );
     644               2 :             strcat(sphere_name, "_localRadius");
     645                 :             oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
     646                 :                             localRadius, 0.0, 
     647               2 :                             "Reference_Meridian", 0.0 );
     648                 :         } 
     649                 :         else { 
     650                 :             //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc.
     651                 :             //Geographic, so set an ellipse
     652               0 :             if (bIsGeographic) {
     653                 :                 oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
     654                 :                                 semi_major, iflattening, 
     655               0 :                                 "Reference_Meridian", 0.0 );
     656                 :             } else { 
     657                 :                 //Geocentric, so force a sphere. I hope... 
     658                 :                 oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
     659                 :                                 semi_major, 0.0, 
     660               0 :                                 "Reference_Meridian", 0.0 );
     661                 :             }
     662                 :         }
     663                 : 
     664                 :         // translate back into a projection string.
     665               2 :         char *pszResult = NULL;
     666               2 :         oSRS.exportToWkt( &pszResult );
     667               2 :         poDS->osProjection = pszResult;
     668               2 :         CPLFree( pszResult );
     669                 :     }
     670                 : 
     671                 : /* END ISIS3 Label Read */
     672                 : /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     673                 :     
     674                 : /* -------------------------------------------------------------------- */
     675                 : /*     Is the CUB detached - if so, reset name to binary file?          */
     676                 : /* -------------------------------------------------------------------- */
     677                 : #ifdef notdef
     678                 :     // Frank - is this correct?
     679                 :     //The extension already added on so don't add another. But is this needed?
     680                 :     char *pszPath = CPLStrdup( CPLGetPath( poOpenInfo->pszFilename ) );
     681                 :     char *pszName = CPLStrdup( CPLGetBasename( poOpenInfo->pszFilename ) );
     682                 :     if (bIsDetached)
     683                 :         pszCUBFilename = CPLFormCIFilename( pszPath, detachedCub, "" );
     684                 : #endif
     685                 : 
     686                 : /* -------------------------------------------------------------------- */
     687                 : /*      Did we get the required keywords?  If not we return with        */
     688                 : /*      this never having been considered to be a match. This isn't     */
     689                 : /*      an error!                                                       */
     690                 : /* -------------------------------------------------------------------- */
     691               2 :     if( nRows < 1 || nCols < 1 || nBands < 1 )
     692                 :     {
     693               0 :         delete poDS;
     694               0 :         return NULL;
     695                 :     }
     696                 : 
     697                 : /* -------------------------------------------------------------------- */
     698                 : /*      Capture some information from the file that is of interest.     */
     699                 : /* -------------------------------------------------------------------- */
     700               2 :     poDS->nRasterXSize = nCols;
     701               2 :     poDS->nRasterYSize = nRows;
     702                 : 
     703                 : /* -------------------------------------------------------------------- */
     704                 : /*      Open target binary file.                                        */
     705                 : /* -------------------------------------------------------------------- */
     706               2 :     if( poOpenInfo->eAccess == GA_ReadOnly )
     707               2 :         poDS->fpImage = VSIFOpenL( osQubeFile, "r" );
     708                 :     else
     709               0 :         poDS->fpImage = VSIFOpenL( osQubeFile, "r+" );
     710                 : 
     711               2 :     if( poDS->fpImage == NULL )
     712                 :     {
     713                 :         CPLError( CE_Failure, CPLE_OpenFailed, 
     714                 :                   "Failed to open %s with write permission.\n%s", 
     715                 :                   osQubeFile.c_str(),
     716               0 :                   VSIStrerror( errno ) );
     717               0 :         delete poDS;
     718               0 :         return NULL;
     719                 :     }
     720                 : 
     721               2 :     poDS->eAccess = poOpenInfo->eAccess;
     722                 : 
     723                 : /* -------------------------------------------------------------------- */
     724                 : /*      Compute the line offset.                                        */
     725                 : /* -------------------------------------------------------------------- */
     726               2 :     int     nItemSize = GDALGetDataTypeSize(eDataType)/8;
     727               2 :     int     nLineOffset=0, nPixelOffset=0, nBandOffset=0;
     728                 :     
     729               2 :     if( EQUAL(szLayout,"BSQ") )
     730                 :     {
     731               1 :         nPixelOffset = nItemSize;
     732               1 :         nLineOffset = nPixelOffset * nCols;
     733               1 :         nBandOffset = nLineOffset * nRows;
     734                 :     }
     735                 :     else /* Tiled */
     736                 :     {
     737                 :     }
     738                 :     
     739                 : /* -------------------------------------------------------------------- */
     740                 : /*      Create band information objects.                                */
     741                 : /* -------------------------------------------------------------------- */
     742                 :     int i;
     743                 : 
     744                 : #ifdef CPL_LSB                               
     745               2 :     int bNativeOrder = !(chByteOrder == 'M');
     746                 : #else
     747                 :     int bNativeOrder = (chByteOrder == 'M');
     748                 : #endif        
     749                 : 
     750                 : 
     751               4 :     for( i = 0; i < nBands; i++ )
     752                 :     {
     753                 :         GDALRasterBand  *poBand;
     754                 : 
     755               2 :         if( EQUAL(szLayout,"Tiled") )
     756                 :         {
     757                 :             poBand = new ISISTiledBand( poDS, poDS->fpImage, i+1, eDataType,
     758                 :                                         tileSizeX, tileSizeY, 
     759                 :                                         nSkipBytes, 0, 0, 
     760               1 :                                         bNativeOrder );
     761                 :         }
     762                 :         else
     763                 :         {
     764                 :             poBand = 
     765                 :                 new RawRasterBand( poDS, i+1, poDS->fpImage,
     766                 :                                    nSkipBytes + nBandOffset * i, 
     767                 :                                    nPixelOffset, nLineOffset, eDataType,
     768                 : #ifdef CPL_LSB                               
     769                 :                                    chByteOrder == 'I' || chByteOrder == 'L',
     770                 : #else
     771                 :                                    chByteOrder == 'M',
     772                 : #endif        
     773               1 :                                    TRUE );
     774                 :         }
     775                 : 
     776               2 :         poDS->SetBand( i+1, poBand );
     777                 : 
     778               2 :         if( bNoDataSet )
     779               2 :             ((GDALPamRasterBand *) poBand)->SetNoDataValue( dfNoData );
     780                 : 
     781                 :         // Set offset/scale values at the PAM level.
     782                 :         poBand->SetOffset( 
     783               2 :             CPLAtofM(poDS->GetKeyword("IsisCube.Core.Pixels.Base","0.0")));
     784                 :         poBand->SetScale( 
     785               2 :           CPLAtofM(poDS->GetKeyword("IsisCube.Core.Pixels.Multiplier","1.0")));
     786                 :     }
     787                 : 
     788                 : /* -------------------------------------------------------------------- */
     789                 : /*      Check for a .prj file. For ISIS3 I would like to keep this in   */
     790                 : /* -------------------------------------------------------------------- */
     791               2 :     CPLString osPath, osName;
     792                 : 
     793               2 :     osPath = CPLGetPath( poOpenInfo->pszFilename );
     794               2 :     osName = CPLGetBasename(poOpenInfo->pszFilename);
     795               2 :     const char  *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" );
     796                 : 
     797               2 :     fp = VSIFOpen( pszPrjFile, "r" );
     798               2 :     if( fp != NULL )
     799                 :     {
     800                 :         char  **papszLines;
     801               0 :         OGRSpatialReference oSRS;
     802                 : 
     803               0 :         VSIFClose( fp );
     804                 :         
     805               0 :         papszLines = CSLLoad( pszPrjFile );
     806                 : 
     807               0 :         if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE )
     808                 :         {
     809               0 :             char *pszResult = NULL;
     810               0 :             oSRS.exportToWkt( &pszResult );
     811               0 :             poDS->osProjection = pszResult;
     812               0 :             CPLFree( pszResult );
     813                 :         }
     814                 : 
     815               0 :         CSLDestroy( papszLines );
     816                 :     }
     817                 : 
     818                 :     
     819               2 :     if( dfULYMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 )
     820                 :     {
     821               2 :         poDS->bGotTransform = TRUE;
     822               2 :         poDS->adfGeoTransform[0] = dfULXMap;
     823               2 :         poDS->adfGeoTransform[1] = dfXDim;
     824               2 :         poDS->adfGeoTransform[2] = 0.0;
     825               2 :         poDS->adfGeoTransform[3] = dfULYMap;
     826               2 :         poDS->adfGeoTransform[4] = 0.0;
     827               2 :         poDS->adfGeoTransform[5] = dfYDim;
     828                 :     }
     829                 :     
     830               2 :     if( !poDS->bGotTransform )
     831                 :         poDS->bGotTransform = 
     832                 :             GDALReadWorldFile( poOpenInfo->pszFilename, "cbw", 
     833               0 :                                poDS->adfGeoTransform );
     834                 : 
     835               2 :     if( !poDS->bGotTransform )
     836                 :         poDS->bGotTransform = 
     837                 :             GDALReadWorldFile( poOpenInfo->pszFilename, "wld", 
     838               0 :                                poDS->adfGeoTransform );
     839                 : 
     840                 : /* -------------------------------------------------------------------- */
     841                 : /*      Initialize any PAM information.                                 */
     842                 : /* -------------------------------------------------------------------- */
     843               2 :     poDS->SetDescription( poOpenInfo->pszFilename );
     844               2 :     poDS->TryLoadXML();
     845                 : 
     846                 : /* -------------------------------------------------------------------- */
     847                 : /*      Check for overviews.                                            */
     848                 : /* -------------------------------------------------------------------- */
     849               2 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     850                 : 
     851               2 :     return( poDS );
     852                 : }
     853                 : 
     854                 : /************************************************************************/
     855                 : /*                             GetKeyword()                             */
     856                 : /************************************************************************/
     857                 : 
     858              48 : const char *ISIS3Dataset::GetKeyword( const char *pszPath, 
     859                 :                                       const char *pszDefault )
     860                 : 
     861                 : {
     862              48 :     return oKeywords.GetKeyword( pszPath, pszDefault );
     863                 : }
     864                 : 
     865                 : /************************************************************************/
     866                 : /*                            GetKeywordSub()                           */
     867                 : /************************************************************************/
     868                 : 
     869               0 : const char *ISIS3Dataset::GetKeywordSub( const char *pszPath, 
     870                 :                                          int iSubscript,
     871                 :                                          const char *pszDefault )
     872                 : 
     873                 : {
     874               0 :     const char *pszResult = oKeywords.GetKeyword( pszPath, NULL );
     875                 :     
     876               0 :     if( pszResult == NULL )
     877               0 :         return pszDefault;
     878                 : 
     879               0 :     if( pszResult[0] != '(' )
     880               0 :         return pszDefault;
     881                 : 
     882                 :     char **papszTokens = CSLTokenizeString2( pszResult, "(,)", 
     883               0 :                                              CSLT_HONOURSTRINGS );
     884                 : 
     885               0 :     if( iSubscript <= CSLCount(papszTokens) )
     886                 :     {
     887               0 :         oTempResult = papszTokens[iSubscript-1];
     888               0 :         CSLDestroy( papszTokens );
     889               0 :         return oTempResult.c_str();
     890                 :     }
     891                 :     else
     892                 :     {
     893               0 :         CSLDestroy( papszTokens );
     894               0 :         return pszDefault;
     895                 :     }
     896                 : }
     897                 : 
     898                 : 
     899                 : /************************************************************************/
     900                 : /*                         GDALRegister_ISIS3()                         */
     901                 : /************************************************************************/
     902                 : 
     903             338 : void GDALRegister_ISIS3()
     904                 : 
     905                 : {
     906                 :     GDALDriver  *poDriver;
     907                 : 
     908             338 :     if( GDALGetDriverByName( "ISIS3" ) == NULL )
     909                 :     {
     910             336 :         poDriver = new GDALDriver();
     911                 :         
     912             336 :         poDriver->SetDescription( "ISIS3" );
     913                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     914             336 :                                    "USGS Astrogeology ISIS cube (Version 3)" );
     915                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     916             336 :                                    "frmt_various.html#ISIS3" );
     917                 : 
     918             336 :         poDriver->pfnOpen = ISIS3Dataset::Open;
     919             336 :         poDriver->pfnIdentify = ISIS3Dataset::Identify;
     920                 : 
     921             336 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     922                 :     }
     923             338 : }
     924                 : 

Generated by: LCOV version 1.7