LCOV - code coverage report
Current view: directory - frmts/pds - isis2dataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 277 184 66.4 %
Date: 2010-01-09 Functions: 10 10 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: isis2dataset.cpp 17786 2009-10-09 19:35:19Z warmerdam $
       3                 :  *
       4                 :  * Project:  ISIS Version 2 Driver
       5                 :  * Purpose:  Implementation of ISIS2Dataset
       6                 :  * Author:   Trent Hare (thare@usgs.gov),
       7                 :  *           Robert Soricone (rsoricone@usgs.gov)
       8                 :  *
       9                 :  * NOTE: Original code authored by Trent and Robert and placed in the public 
      10                 :  * domain as per US government policy.  I have (within my rights) appropriated 
      11                 :  * it and placed it under the following license.  This is not intended to 
      12                 :  * diminish Trent and Roberts contribution. 
      13                 :  ******************************************************************************
      14                 :  * Copyright (c) 2006, 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: isis2dataset.cpp 17786 2009-10-09 19:35:19Z warmerdam $");
      52                 : 
      53                 : CPL_C_START
      54                 : void  GDALRegister_ISIS2(void);
      55                 : CPL_C_END
      56                 : 
      57                 : /************************************************************************/
      58                 : /* ==================================================================== */
      59                 : /*      ISISDataset version2                  */
      60                 : /* ==================================================================== */
      61                 : /************************************************************************/
      62                 : 
      63                 : class ISIS2Dataset : public RawDataset
      64                 : {
      65                 :     FILE  *fpImage; // image data file.
      66                 : 
      67                 :     NASAKeywordHandler  oKeywords;
      68                 :   
      69                 :     int         bGotTransform;
      70                 :     double      adfGeoTransform[6];
      71                 :   
      72                 :     CPLString   osProjection;
      73                 : 
      74                 :     int parse_label(const char *file, char *keyword, char *value);
      75                 :     int strstrip(char instr[], char outstr[], int position);
      76                 : 
      77                 :     CPLString   oTempResult;
      78                 : 
      79                 :     void        CleanString( CPLString &osInput );
      80                 : 
      81                 :     const char *GetKeyword( const char *pszPath, 
      82                 :                             const char *pszDefault = "");
      83                 :     const char *GetKeywordSub( const char *pszPath, 
      84                 :                                int iSubscript, 
      85                 :                                const char *pszDefault = "");
      86                 : 
      87                 : public:
      88                 :     ISIS2Dataset();
      89                 :     ~ISIS2Dataset();
      90                 :   
      91                 :     virtual CPLErr GetGeoTransform( double * padfTransform );
      92                 :     virtual const char *GetProjectionRef(void);
      93                 :   
      94                 :     static GDALDataset *Open( GDALOpenInfo * );
      95                 :     static GDALDataset *Create( const char * pszFilename,
      96                 :                                 int nXSize, int nYSize, int nBands,
      97                 :                                 GDALDataType eType, char ** papszParmList );
      98                 : };
      99                 : 
     100                 : /************************************************************************/
     101                 : /*                            ISIS2Dataset()                            */
     102                 : /************************************************************************/
     103                 : 
     104               1 : ISIS2Dataset::ISIS2Dataset()
     105                 : {
     106               1 :     fpImage = NULL;
     107               1 :     bGotTransform = FALSE;
     108               1 :     adfGeoTransform[0] = 0.0;
     109               1 :     adfGeoTransform[1] = 1.0;
     110               1 :     adfGeoTransform[2] = 0.0;
     111               1 :     adfGeoTransform[3] = 0.0;
     112               1 :     adfGeoTransform[4] = 0.0;
     113               1 :     adfGeoTransform[5] = 1.0;
     114               1 : }
     115                 : 
     116                 : /************************************************************************/
     117                 : /*                            ~ISIS2Dataset()                            */
     118                 : /************************************************************************/
     119                 : 
     120               2 : ISIS2Dataset::~ISIS2Dataset()
     121                 : 
     122                 : {
     123               1 :     FlushCache();
     124               1 :     if( fpImage != NULL )
     125               1 :         VSIFCloseL( fpImage );
     126               2 : }
     127                 : 
     128                 : /************************************************************************/
     129                 : /*                          GetProjectionRef()                          */
     130                 : /************************************************************************/
     131                 : 
     132               1 : const char *ISIS2Dataset::GetProjectionRef()
     133                 : 
     134                 : {
     135               1 :     if( strlen(osProjection) > 0 )
     136               1 :         return osProjection;
     137                 :     else
     138               0 :         return GDALPamDataset::GetProjectionRef();
     139                 : }
     140                 : 
     141                 : /************************************************************************/
     142                 : /*                          GetGeoTransform()                           */
     143                 : /************************************************************************/
     144                 : 
     145               1 : CPLErr ISIS2Dataset::GetGeoTransform( double * padfTransform )
     146                 : 
     147                 : {
     148               1 :     if( bGotTransform )
     149                 :     {
     150               1 :         memcpy( padfTransform, adfGeoTransform, sizeof(double) * 6 );
     151               1 :         return CE_None;
     152                 :     }
     153                 :     else
     154                 :     {
     155               0 :         return GDALPamDataset::GetGeoTransform( padfTransform );
     156                 :     }
     157                 : }
     158                 : 
     159                 : /************************************************************************/
     160                 : /*                                Open()                                */
     161                 : /************************************************************************/
     162                 : 
     163            9029 : GDALDataset *ISIS2Dataset::Open( GDALOpenInfo * poOpenInfo )
     164                 : {
     165                 : /* -------------------------------------------------------------------- */
     166                 : /*      Does this look like a CUBE dataset?                             */
     167                 : /* -------------------------------------------------------------------- */
     168            9029 :     if( poOpenInfo->pabyHeader == NULL
     169                 :         || strstr((const char *)poOpenInfo->pabyHeader,"^QUBE") == NULL )
     170            9028 :         return NULL;
     171                 : 
     172                 : /* -------------------------------------------------------------------- */
     173                 : /*      Open the file using the large file API.                         */
     174                 : /* -------------------------------------------------------------------- */
     175               1 :     FILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
     176                 : 
     177               1 :     if( fpQube == NULL )
     178               0 :         return NULL;
     179                 : 
     180                 :     ISIS2Dataset  *poDS;
     181                 : 
     182               1 :     poDS = new ISIS2Dataset();
     183                 : 
     184               1 :     if( ! poDS->oKeywords.Ingest( fpQube, 0 ) )
     185                 :     {
     186               0 :         VSIFCloseL( fpQube );
     187               0 :         delete poDS;
     188               0 :         return NULL;
     189                 :     }
     190                 :     
     191               1 :     VSIFCloseL( fpQube );
     192                 : 
     193                 : /* -------------------------------------------------------------------- */
     194                 : /*  We assume the user is pointing to the label (ie. .lab) file.    */
     195                 : /* -------------------------------------------------------------------- */
     196                 :     // QUBE can be inline or detached and point to an image name
     197                 :     // ^QUBE = 76
     198                 :     // ^QUBE = ("ui31s015.img",6441<BYTES>) - has another label on the image
     199                 :     // ^QUBE = "ui31s015.img" - which implies no label or skip value
     200                 : 
     201               1 :     const char *pszQube = poDS->GetKeyword( "^QUBE" );
     202               1 :     int nQube = atoi(pszQube);
     203                 : 
     204               1 :     if( pszQube[0] == '"' || pszQube[0] == '(' )
     205                 :     {
     206                 :         CPLError( CE_Failure, CPLE_AppDefined,
     207               0 :                   "ISIS2 driver does not support detached images." );
     208               0 :         return NULL;
     209                 :     }
     210                 : 
     211                 : /* -------------------------------------------------------------------- */
     212                 : /*      Check if file an ISIS2 header file?  Read a few lines of text   */
     213                 : /*      searching for something starting with nrows or ncols.           */
     214                 : /* -------------------------------------------------------------------- */
     215               1 :     GDALDataType eDataType = GDT_Byte;
     216               1 :     OGRSpatialReference oSRS;
     217                 : 
     218                 :     //image parameters
     219               1 :     int nRows, nCols, nBands = 1;
     220               1 :     int nSkipBytes = 0;
     221                 :     int itype;
     222                 :     int  s_ix, s_iy, s_iz; // check SUFFIX_ITEMS params.
     223                 :     int record_bytes;
     224               1 :     int bNoDataSet = FALSE;
     225               1 :     char chByteOrder = 'M';  //default to MSB
     226                 :  
     227                 :     //Georef parameters
     228               1 :     double dfULXMap=0.5;
     229               1 :     double dfULYMap = 0.5;
     230               1 :     double dfXDim = 1.0;
     231               1 :     double dfYDim = 1.0;
     232               1 :     double dfNoData = 0.0;
     233               1 :     double xulcenter = 0.0;
     234               1 :     double yulcenter = 0.0;
     235                 : 
     236                 :     //projection parameters
     237               1 :     int bProjectionSet = TRUE;
     238               1 :     double semi_major = 0.0;
     239               1 :     double semi_minor = 0.0;
     240               1 :     double iflattening = 0.0;
     241               1 :     float center_lat = 0.0;
     242               1 :     float center_lon = 0.0;
     243               1 :     float first_std_parallel = 0.0;
     244               1 :     float second_std_parallel = 0.0;
     245                 :     FILE  *fp;
     246                 : 
     247                 :     /* -------------------------------------------------------------------- */
     248                 :     /*      Checks to see if this is valid ISIS2 cube                       */
     249                 :     /*      SUFFIX_ITEM tag in .cub file should be (0,0,0); no side-planes  */
     250                 :     /* -------------------------------------------------------------------- */
     251               1 :     s_ix = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 1 ));
     252               1 :     s_iy = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 2 ));
     253               1 :     s_iz = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 3 ));
     254                 :      
     255               1 :     if( s_ix != 0 || s_iy != 0 || s_iz != 0 ) 
     256                 :     {
     257                 :         CPLError( CE_Failure, CPLE_OpenFailed, 
     258                 :                   "*** ISIS 2 cube file has invalid SUFFIX_ITEMS parameters:\n"
     259                 :                   "*** gdal isis2 driver requires (0, 0, 0), thus no sideplanes or backplanes\n"
     260               0 :                   "found: (%i, %i, %i)\n\n", s_ix, s_iy, s_iz );
     261               0 :         return NULL;
     262                 :     } 
     263                 : 
     264                 :     /**************** end SUFFIX_ITEM check ***********************/
     265                 :     
     266                 :     
     267                 :     /***********   Grab layout type (BSQ, BIP, BIL) ************/
     268                 :     //  AXIS_NAME = (SAMPLE,LINE,BAND)
     269                 :     /***********************************************************/
     270                 :     const char *value;
     271                 : 
     272               1 :     char szLayout[10] = "BSQ"; //default to band seq.
     273               1 :     value = poDS->GetKeyword( "QUBE.AXIS_NAME", "" );
     274               1 :     if (EQUAL(value,"(SAMPLE,LINE,BAND)") )
     275               1 :         strcpy(szLayout,"BSQ");
     276               0 :     else if (EQUAL(value,"(BAND,LINE,SAMPLE)") )
     277               0 :         strcpy(szLayout,"BIP");
     278               0 :     else if (EQUAL(value,"(SAMPLE,BAND,LINE)") || EQUAL(value,"") )
     279               0 :         strcpy(szLayout,"BSQ");
     280                 :     else {
     281                 :         CPLError( CE_Failure, CPLE_OpenFailed, 
     282               0 :                   "%s layout not supported. Abort\n\n", value);
     283               0 :         return NULL;
     284                 :     }
     285                 : 
     286                 :     /***********   Grab samples lines band ************/
     287               1 :     nCols = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",1));
     288               1 :     nRows = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",2));
     289               1 :     nBands = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",3));
     290                 :     
     291                 :     /***********   Grab Qube record bytes  **********/
     292               1 :     record_bytes = atoi(poDS->GetKeyword("RECORD_BYTES"));
     293                 : 
     294               1 :     if (nQube > 0)
     295               1 :         nSkipBytes = (nQube - 1) * record_bytes;     
     296                 :     else
     297               0 :         nSkipBytes = 0;     
     298                 :      
     299                 :     /********   Grab format type - isis2 only supports 8,16,32 *******/
     300               1 :     itype = atoi(poDS->GetKeyword("QUBE.CORE_ITEM_BYTES",""));
     301               1 :     switch(itype) {
     302                 :       case 1 :
     303               0 :         eDataType = GDT_Byte;
     304               0 :         dfNoData = NULL1;
     305               0 :         bNoDataSet = TRUE;
     306               0 :         break;
     307                 :       case 2 :
     308               0 :         eDataType = GDT_Int16;
     309               0 :         dfNoData = NULL2;
     310               0 :         bNoDataSet = TRUE;
     311               0 :         break;
     312                 :       case 4 :
     313               1 :         eDataType = GDT_Float32;
     314               1 :         dfNoData = NULL3;
     315               1 :         bNoDataSet = TRUE;
     316               1 :         break;
     317                 :       default :
     318                 :         CPLError( CE_Failure, CPLE_AppDefined,
     319                 :                   "Itype of %d is not supported in ISIS 2.",
     320               0 :                   itype); 
     321               0 :         delete poDS;
     322               0 :         return NULL;
     323                 :     }
     324                 : 
     325                 :     /***********   Grab samples lines band ************/
     326               1 :     value = poDS->GetKeyword( "QUBE.CORE_ITEM_TYPE" );
     327               1 :     if( (EQUAL(value,"PC_INTEGER")) || 
     328                 :         (EQUAL(value,"PC_UNSIGNED_INTEGER")) || 
     329                 :         (EQUAL(value,"PC_REAL")) ) {
     330               0 :         chByteOrder = 'I';
     331                 :     }
     332                 :     
     333                 :     /***********   Grab Cellsize ************/
     334               1 :     value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.MAP_SCALE");
     335               1 :     if (strlen(value) > 0 ) {
     336               1 :         dfXDim = (float) atof(value) * 1000.0; /* convert from km to m */
     337               1 :         dfYDim = (float) atof(value) * 1000.0 * -1;
     338                 :     }
     339                 :     
     340                 :     /***********   Grab LINE_PROJECTION_OFFSET ************/
     341               1 :     value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.LINE_PROJECTION_OFFSET");
     342               1 :     if (strlen(value) > 0) {
     343               1 :         yulcenter = (float) atof(value);
     344               1 :         yulcenter = ((yulcenter) * dfYDim);
     345               1 :         dfULYMap = yulcenter - (dfYDim/2);
     346                 :     }
     347                 :      
     348                 :     /***********   Grab SAMPLE_PROJECTION_OFFSET ************/
     349               1 :     value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.SAMPLE_PROJECTION_OFFSET");
     350               1 :     if( strlen(value) > 0 ) {
     351               1 :         xulcenter = (float) atof(value);
     352               1 :         xulcenter = ((xulcenter) * dfXDim);
     353               1 :         dfULXMap = xulcenter - (dfXDim/2);
     354                 :     }
     355                 :      
     356                 :     /***********  Grab TARGET_NAME  ************/
     357                 :     /**** This is the planets name i.e. MARS ***/
     358               1 :     CPLString target_name = poDS->GetKeyword("QUBE.TARGET_NAME");
     359                 :      
     360                 :     /***********   Grab MAP_PROJECTION_TYPE ************/
     361                 :     CPLString map_proj_name = 
     362               1 :         poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.MAP_PROJECTION_TYPE");
     363               1 :     poDS->CleanString( map_proj_name );
     364                 : 
     365                 :     /***********   Grab SEMI-MAJOR ************/
     366                 :     semi_major = 
     367               1 :         atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.A_AXIS_RADIUS")) * 1000.0;
     368                 : 
     369                 :     /***********   Grab semi-minor ************/
     370                 :     semi_minor = 
     371               1 :         atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.C_AXIS_RADIUS")) * 1000.0;
     372                 : 
     373                 :     /***********   Grab CENTER_LAT ************/
     374                 :     center_lat = 
     375               1 :         atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LATITUDE"));
     376                 : 
     377                 :     /***********   Grab CENTER_LON ************/
     378                 :     center_lon = 
     379               1 :         atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LONGITUDE"));
     380                 : 
     381                 :     /***********   Grab 1st std parallel ************/
     382                 :     first_std_parallel = 
     383               1 :         atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.FIRST_STANDARD_PARALLEL"));
     384                 : 
     385                 :     /***********   Grab 2nd std parallel ************/
     386                 :     second_std_parallel = 
     387               1 :         atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.SECOND_STANDARD_PARALLEL"));
     388                 :      
     389                 :     /*** grab  PROJECTION_LATITUDE_TYPE = "PLANETOCENTRIC" ****/
     390                 :     // Need to further study how ocentric/ographic will effect the gdal library.
     391                 :     // So far we will use this fact to define a sphere or ellipse for some projections
     392                 :     // Frank - may need to talk this over
     393               1 :     char bIsGeographic = TRUE;
     394               1 :     value = poDS->GetKeyword("CUBE.IMAGE_MAP_PROJECTION.PROJECTION_LATITUDE_TYPE");
     395               1 :     if (EQUAL( value, "\"PLANETOCENTRIC\"" ))
     396               0 :         bIsGeographic = FALSE; 
     397                 :      
     398               1 :     CPLDebug("ISIS2","using projection %s", map_proj_name.c_str() );
     399                 : 
     400                 :     //Set oSRS projection and parameters
     401               1 :     if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) ||
     402                 :         (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ||
     403                 :         (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) ) {
     404               1 :         oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 );
     405               0 :     } else if (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) { 
     406               0 :         oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 );
     407               0 :     } else if ((EQUAL( map_proj_name, "SINUSOIDAL" )) ||
     408                 :                (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" ))) {
     409               0 :         oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 );
     410               0 :     } else if (EQUAL( map_proj_name, "MERCATOR" )) {
     411               0 :         oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, 1, 0, 0 );
     412               0 :     } else if (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )) {
     413               0 :         oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, 1, 0, 0 );
     414               0 :     } else if (EQUAL( map_proj_name, "TRANSVERSE_MERCATOR" )) {
     415               0 :         oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, 1, 0, 0 );
     416               0 :     } else if (EQUAL( map_proj_name, "LAMBERT_CONFORMAL_CONIC" )) {
     417               0 :         oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 );
     418                 :     } else {
     419                 :         CPLDebug( "ISIS2",
     420                 :                   "Dataset projection %s is not supported. Continuing...",
     421               0 :                   map_proj_name.c_str() );
     422               0 :         bProjectionSet = FALSE;
     423                 :     }
     424                 : 
     425               1 :     if (bProjectionSet) {
     426                 :         //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword
     427               1 :         CPLString proj_target_name = map_proj_name + " " + target_name;
     428               1 :         oSRS.SetProjCS(proj_target_name); //set ProjCS keyword
     429                 :      
     430                 :         //The geographic/geocentric name will be the same basic name as the body name
     431                 :         //'GCS' = Geographic/Geocentric Coordinate System
     432               1 :         CPLString geog_name = "GCS_" + target_name;
     433                 :         
     434                 :         //The datum and sphere names will be the same basic name aas the planet
     435               1 :         CPLString datum_name = "D_" + target_name;
     436               1 :         CPLString sphere_name = target_name; // + "_IAU_IAG");  //Might not be IAU defined so don't add
     437                 :           
     438                 :         //calculate inverse flattening from major and minor axis: 1/f = a/(a-b)
     439               1 :         if ((semi_major - semi_minor) < 0.0000001) 
     440               1 :             iflattening = 0;
     441                 :         else
     442               0 :             iflattening = semi_major / (semi_major - semi_minor);
     443                 :      
     444                 :         //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility
     445                 :         //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally
     446               1 :         if ( ( (EQUAL( map_proj_name, "STEREOGRAPHIC" ) && (fabs(center_lat) == 90)) ) || 
     447                 :              (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )))  
     448                 :         {
     449               0 :             if (bIsGeographic) { 
     450                 :                 //Geograpraphic, so set an ellipse
     451                 :                 oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
     452                 :                                 semi_major, iflattening, 
     453               0 :                                 "Reference_Meridian", 0.0 );
     454                 :             } else {
     455                 :                 //Geocentric, so force a sphere using the semi-minor axis. I hope... 
     456               0 :                 sphere_name += "_polarRadius";
     457                 :                 oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
     458                 :                                 semi_minor, 0.0, 
     459               0 :                                 "Reference_Meridian", 0.0 );
     460                 :             }
     461                 :         }
     462               1 :         else if ( (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) || 
     463                 :                   (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) ||
     464                 :                   (EQUAL( map_proj_name, "STEREOGRAPHIC" )) ||
     465                 :                   (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" )) ||
     466                 :                   (EQUAL( map_proj_name, "SINUSOIDAL" ))  ) {
     467                 :             //isis uses the sphereical equation for these projections so force a sphere
     468                 :             oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
     469                 :                             semi_major, 0.0, 
     470               1 :                             "Reference_Meridian", 0.0 );
     471                 :         } 
     472               0 :         else if  ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) || 
     473                 :                   (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ) {
     474                 :             //Calculate localRadius using ISIS3 simple elliptical method 
     475                 :             //  not the more standard Radius of Curvature method
     476                 :             //PI = 4 * atan(1);
     477                 :             double radLat, localRadius;
     478               0 :             if (center_lon == 0) { //No need to calculate local radius
     479                 :                 oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
     480                 :                                 semi_major, 0.0, 
     481               0 :                                 "Reference_Meridian", 0.0 );
     482                 :             } else {  
     483               0 :                 radLat = center_lat * PI / 180;  // in radians
     484                 :                 localRadius = semi_major * semi_minor / sqrt(pow(semi_minor*cos(radLat),2)
     485               0 :                                                              + pow(semi_major*sin(radLat),2) );
     486               0 :                 sphere_name += "_localRadius";
     487                 :                 oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
     488                 :                                 localRadius, 0.0, 
     489               0 :                                 "Reference_Meridian", 0.0 );
     490               0 :                 CPLDebug( "ISIS2", "local radius: %f", localRadius);
     491                 :             }
     492                 :         } 
     493                 :         else { 
     494                 :             //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc.
     495                 :             //Geographic, so set an ellipse
     496               0 :             if (bIsGeographic) {
     497                 :                 oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
     498                 :                                 semi_major, iflattening, 
     499               0 :                                 "Reference_Meridian", 0.0 );
     500                 :             } else { 
     501                 :                 //Geocentric, so force a sphere. I hope... 
     502                 :                 oSRS.SetGeogCS( geog_name, datum_name, sphere_name,
     503                 :                                 semi_major, 0.0, 
     504               0 :                                 "Reference_Meridian", 0.0 );
     505                 :             }
     506                 :         }
     507                 :         
     508                 : 
     509                 :         // translate back into a projection string.
     510               1 :         char *pszResult = NULL;
     511               1 :         oSRS.exportToWkt( &pszResult );
     512               1 :         poDS->osProjection = pszResult;
     513               1 :         CPLFree( pszResult );
     514                 :     }
     515                 : 
     516                 : /* END ISIS2 Label Read */
     517                 : /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     518                 :     
     519                 : /* -------------------------------------------------------------------- */
     520                 : /*      Did we get the required keywords?  If not we return with        */
     521                 : /*      this never having been considered to be a match. This isn't     */
     522                 : /*      an error!                                                       */
     523                 : /* -------------------------------------------------------------------- */
     524               1 :     if( nRows < 1 || nCols < 1 || nBands < 1 )
     525                 :     {
     526               0 :         return NULL;
     527                 :     }
     528                 : 
     529                 : /* -------------------------------------------------------------------- */
     530                 : /*      Capture some information from the file that is of interest.     */
     531                 : /* -------------------------------------------------------------------- */
     532               1 :     poDS->nRasterXSize = nCols;
     533               1 :     poDS->nRasterYSize = nRows;
     534                 : 
     535                 : /* -------------------------------------------------------------------- */
     536                 : /*      Open target binary file.                                        */
     537                 : /* -------------------------------------------------------------------- */
     538                 :     
     539               1 :     if( poOpenInfo->eAccess == GA_ReadOnly )
     540               1 :         poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" );
     541                 :     else
     542               0 :         poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "r+b" );
     543                 : 
     544               1 :     if( poDS->fpImage == NULL )
     545                 :     {
     546                 :         CPLError( CE_Failure, CPLE_OpenFailed, 
     547                 :                   "Failed to open %s with write permission.\n%s", 
     548               0 :                   poOpenInfo->pszFilename, VSIStrerror( errno ) );
     549               0 :         delete poDS;
     550               0 :         return NULL;
     551                 :     }
     552                 : 
     553               1 :     poDS->eAccess = poOpenInfo->eAccess;
     554                 : 
     555                 : /* -------------------------------------------------------------------- */
     556                 : /*      Compute the line offset.                                        */
     557                 : /* -------------------------------------------------------------------- */
     558               1 :     int     nItemSize = GDALGetDataTypeSize(eDataType)/8;
     559                 :     int   nLineOffset, nPixelOffset, nBandOffset;
     560                 :     
     561               1 :     if( EQUAL(szLayout,"BIP") )
     562                 :     {
     563               0 :         nPixelOffset = nItemSize * nBands;
     564               0 :         nLineOffset = nPixelOffset * nCols;
     565               0 :         nBandOffset = nItemSize;
     566                 :     }
     567               1 :     else if( EQUAL(szLayout,"BSQ") )
     568                 :     {
     569               1 :         nPixelOffset = nItemSize;
     570               1 :         nLineOffset = nPixelOffset * nCols;
     571               1 :         nBandOffset = nLineOffset * nRows;
     572                 :     }
     573                 :     else /* assume BIL */
     574                 :     {
     575               0 :         nPixelOffset = nItemSize;
     576               0 :         nLineOffset = nItemSize * nBands * nCols;
     577               0 :         nBandOffset = nItemSize * nCols;
     578                 :     }
     579                 :     
     580                 : /* -------------------------------------------------------------------- */
     581                 : /*      Create band information objects.                                */
     582                 : /* -------------------------------------------------------------------- */
     583                 :     int i;
     584                 : 
     585               1 :     poDS->nBands = nBands;;
     586               2 :     for( i = 0; i < poDS->nBands; i++ )
     587                 :     {
     588                 :         RawRasterBand *poBand;
     589                 : 
     590                 :         poBand = 
     591                 :             new RawRasterBand( poDS, i+1, poDS->fpImage,
     592                 :                                nSkipBytes + nBandOffset * i, 
     593                 :                                nPixelOffset, nLineOffset, eDataType,
     594                 : #ifdef CPL_LSB                               
     595                 :                                chByteOrder == 'I' || chByteOrder == 'L',
     596                 : #else
     597                 :                                chByteOrder == 'M',
     598                 : #endif        
     599               1 :                                TRUE );
     600                 : 
     601               1 :         if( bNoDataSet )
     602               1 :             poBand->SetNoDataValue( dfNoData );
     603                 : 
     604               1 :         poDS->SetBand( i+1, poBand );
     605                 : 
     606                 :         // Set offset/scale values at the PAM level.
     607                 :         poBand->SetOffset( 
     608               1 :             CPLAtofM(poDS->GetKeyword("QUBE.CORE_BASE","0.0")));
     609                 :         poBand->SetScale( 
     610               1 :             CPLAtofM(poDS->GetKeyword("QUBE.CORE_MULTIPLIER","1.0")));
     611                 :     }
     612                 : 
     613                 : /* -------------------------------------------------------------------- */
     614                 : /*      Check for a .prj file. For isis2 I would like to keep this in   */
     615                 : /* -------------------------------------------------------------------- */
     616               1 :     CPLString osPath, osName;
     617                 : 
     618               1 :     osPath = CPLGetPath( poOpenInfo->pszFilename );
     619               1 :     osName = CPLGetBasename(poOpenInfo->pszFilename);
     620               1 :     const char  *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" );
     621                 : 
     622               1 :     fp = VSIFOpen( pszPrjFile, "r" );
     623               1 :     if( fp != NULL )
     624                 :     {
     625                 :         char  **papszLines;
     626               0 :         OGRSpatialReference oSRS;
     627                 : 
     628               0 :         VSIFClose( fp );
     629                 :         
     630               0 :         papszLines = CSLLoad( pszPrjFile );
     631                 : 
     632               0 :         if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE )
     633                 :         {
     634               0 :             char *pszResult = NULL;
     635               0 :             oSRS.exportToWkt( &pszResult );
     636               0 :             poDS->osProjection = pszResult;
     637               0 :             CPLFree( pszResult );
     638                 :         }
     639                 : 
     640               0 :         CSLDestroy( papszLines );
     641                 :     }
     642                 : 
     643                 :     
     644               1 :     if( dfULYMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 )
     645                 :     {
     646               1 :         poDS->bGotTransform = TRUE;
     647               1 :         poDS->adfGeoTransform[0] = dfULXMap;
     648               1 :         poDS->adfGeoTransform[1] = dfXDim;
     649               1 :         poDS->adfGeoTransform[2] = 0.0;
     650               1 :         poDS->adfGeoTransform[3] = dfULYMap;
     651               1 :         poDS->adfGeoTransform[4] = 0.0;
     652               1 :         poDS->adfGeoTransform[5] = dfYDim;
     653                 :     }
     654                 :     
     655               1 :     if( !poDS->bGotTransform )
     656                 :         poDS->bGotTransform = 
     657                 :             GDALReadWorldFile( poOpenInfo->pszFilename, "cbw", 
     658               0 :                                poDS->adfGeoTransform );
     659                 : 
     660               1 :     if( !poDS->bGotTransform )
     661                 :         poDS->bGotTransform = 
     662                 :             GDALReadWorldFile( poOpenInfo->pszFilename, "wld", 
     663               0 :                                poDS->adfGeoTransform );
     664                 : 
     665                 : /* -------------------------------------------------------------------- */ 
     666                 : /*      Initialize any PAM information.                                 */ 
     667                 : /* -------------------------------------------------------------------- */ 
     668               1 :     poDS->SetDescription( poOpenInfo->pszFilename ); 
     669               1 :     poDS->TryLoadXML(); 
     670                 : 
     671                 : /* -------------------------------------------------------------------- */
     672                 : /*      Check for overviews.                                            */
     673                 : /* -------------------------------------------------------------------- */
     674               1 :     poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );
     675                 : 
     676               1 :     return( poDS );
     677                 : }
     678                 : 
     679                 : /************************************************************************/
     680                 : /*                             GetKeyword()                             */
     681                 : /************************************************************************/
     682                 : 
     683              19 : const char *ISIS2Dataset::GetKeyword( const char *pszPath, 
     684                 :                                       const char *pszDefault )
     685                 : 
     686                 : {
     687              19 :     return oKeywords.GetKeyword( pszPath, pszDefault );
     688                 : }
     689                 : 
     690                 : /************************************************************************/
     691                 : /*                            GetKeywordSub()                           */
     692                 : /************************************************************************/
     693                 : 
     694               6 : const char *ISIS2Dataset::GetKeywordSub( const char *pszPath, 
     695                 :                                          int iSubscript,
     696                 :                                          const char *pszDefault )
     697                 : 
     698                 : {
     699               6 :     const char *pszResult = oKeywords.GetKeyword( pszPath, NULL );
     700                 :     
     701               6 :     if( pszResult == NULL )
     702               0 :         return pszDefault;
     703                 : 
     704               6 :     if( pszResult[0] != '(' )
     705               0 :         return pszDefault;
     706                 : 
     707                 :     char **papszTokens = CSLTokenizeString2( pszResult, "(,)", 
     708               6 :                                              CSLT_HONOURSTRINGS );
     709                 : 
     710               6 :     if( iSubscript <= CSLCount(papszTokens) )
     711                 :     {
     712               6 :         oTempResult = papszTokens[iSubscript-1];
     713               6 :         CSLDestroy( papszTokens );
     714               6 :         return oTempResult.c_str();
     715                 :     }
     716                 :     else
     717                 :     {
     718               0 :         CSLDestroy( papszTokens );
     719               0 :         return pszDefault;
     720                 :     }
     721                 : }
     722                 : 
     723                 : /************************************************************************/
     724                 : /*                            CleanString()                             */
     725                 : /*                                                                      */
     726                 : /* Removes single or double quotes, and converts spaces to underscores. */
     727                 : /* The change is made in-place to CPLString.                            */
     728                 : /************************************************************************/
     729                 : 
     730               1 : void ISIS2Dataset::CleanString( CPLString &osInput )
     731                 : 
     732                 : {
     733               1 :    if(  ( osInput.size() < 2 ) ||
     734                 :         ((osInput.at(0) != '"'   || osInput.at(osInput.size()-1) != '"' ) &&
     735                 :         ( osInput.at(0) != '\'' || osInput.at(osInput.size()-1) != '\'')) )
     736               1 :         return;
     737                 : 
     738               0 :     char *pszWrk = CPLStrdup(osInput.c_str() + 1);
     739                 :     int i;
     740                 : 
     741               0 :     pszWrk[strlen(pszWrk)-1] = '\0';
     742                 :     
     743               0 :     for( i = 0; pszWrk[i] != '\0'; i++ )
     744                 :     {
     745               0 :         if( pszWrk[i] == ' ' )
     746               0 :             pszWrk[i] = '_';
     747                 :     }
     748                 : 
     749               0 :     osInput = pszWrk;
     750               0 :     CPLFree( pszWrk );
     751                 : }
     752                 : 
     753                 : /************************************************************************/
     754                 : /*                         GDALRegister_ISIS2()                         */
     755                 : /************************************************************************/
     756                 : 
     757             338 : void GDALRegister_ISIS2()
     758                 : 
     759                 : {
     760                 :     GDALDriver  *poDriver;
     761                 : 
     762             338 :     if( GDALGetDriverByName( "ISIS2" ) == NULL )
     763                 :     {
     764             336 :         poDriver = new GDALDriver();
     765                 :         
     766             336 :         poDriver->SetDescription( "ISIS2" );
     767                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     768             336 :                                    "USGS Astrogeology ISIS cube (Version 2)" );
     769                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
     770             336 :                                    "frmt_various.html#ISIS2" );
     771                 : 
     772             336 :         poDriver->pfnOpen = ISIS2Dataset::Open;
     773                 : 
     774             336 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     775                 :     }
     776             338 : }

Generated by: LCOV version 1.7