LTP GCOV extension - code coverage report
Current view: directory - frmts/pcidsk/sdk/segment - cpcidskgeoref.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 568
Code covered: 42.3 % Executed lines: 240

       1                 : /******************************************************************************
       2                 :  *
       3                 :  * Purpose:  Implementation of the CPCIDSKGeoref class.
       4                 :  * 
       5                 :  ******************************************************************************
       6                 :  * Copyright (c) 2009
       7                 :  * PCI Geomatics, 50 West Wilmot Street, Richmond Hill, Ont, Canada
       8                 :  *
       9                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      10                 :  * copy of this software and associated documentation files (the "Software"),
      11                 :  * to deal in the Software without restriction, including without limitation
      12                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      13                 :  * and/or sell copies of the Software, and to permit persons to whom the
      14                 :  * Software is furnished to do so, subject to the following conditions:
      15                 :  *
      16                 :  * The above copyright notice and this permission notice shall be included
      17                 :  * in all copies or substantial portions of the Software.
      18                 :  *
      19                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      20                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      21                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      22                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      23                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      24                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      25                 :  * DEALINGS IN THE SOFTWARE.
      26                 :  ****************************************************************************/
      27                 : 
      28                 : #include "pcidsk_exception.h"
      29                 : #include "segment/cpcidskgeoref.h"
      30                 : #include "core/pcidsk_utils.h"
      31                 : #include <cassert>
      32                 : #include <cstring>
      33                 : #include <cstdlib>
      34                 : #include <cstdio>
      35                 : #include <cctype>
      36                 : 
      37                 : using namespace PCIDSK;
      38                 : 
      39                 : static double PAK2PCI( double deg, int function );
      40                 : 
      41                 : #ifndef ABS
      42                 : #  define ABS(x)        ((x<0) ? (-1*(x)) : x)
      43                 : #endif
      44                 : 
      45                 : /************************************************************************/
      46                 : /*                           CPCIDSKGeoref()                            */
      47                 : /************************************************************************/
      48                 : 
      49                 : CPCIDSKGeoref::CPCIDSKGeoref( PCIDSKFile *file, int segment,
      50              88 :                               const char *segment_pointer )
      51              88 :         : CPCIDSKSegment( file, segment, segment_pointer )
      52                 : 
      53                 : {
      54              88 :     loaded = false;
      55              88 : }
      56                 : 
      57                 : /************************************************************************/
      58                 : /*                           ~CPCIDSKGeoref()                           */
      59                 : /************************************************************************/
      60                 : 
      61              88 : CPCIDSKGeoref::~CPCIDSKGeoref()
      62                 : 
      63                 : {
      64              88 : }
      65                 : 
      66                 : /************************************************************************/
      67                 : /*                             Initialize()                             */
      68                 : /************************************************************************/
      69                 : 
      70              44 : void CPCIDSKGeoref::Initialize()
      71                 : 
      72                 : {
      73                 :     // Note: we depend on Load() reacting gracefully to an uninitialized
      74                 :     // georeferencing segment.
      75                 : 
      76              44 :     WriteSimple( "PIXEL", 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 );
      77              44 : }
      78                 : 
      79                 : /************************************************************************/
      80                 : /*                                Load()                                */
      81                 : /************************************************************************/
      82                 : 
      83             261 : void CPCIDSKGeoref::Load()
      84                 : 
      85                 : {
      86             261 :     if( loaded )
      87               0 :         return;
      88                 : 
      89                 :     // TODO: this should likely be protected by a mutex. 
      90                 : 
      91                 : /* -------------------------------------------------------------------- */
      92                 : /*      Load the segment contents into a buffer.                        */
      93                 : /* -------------------------------------------------------------------- */
      94             261 :     seg_data.SetSize( (int) (data_size - 1024) );
      95                 : 
      96             261 :     ReadFromFile( seg_data.buffer, 0, data_size - 1024 );
      97                 : 
      98                 : /* -------------------------------------------------------------------- */
      99                 : /*      Handle simple case of a POLYNOMIAL.                             */
     100                 : /* -------------------------------------------------------------------- */
     101             261 :     if( strncmp(seg_data.buffer,"POLYNOMIAL",10) == 0 )
     102                 :     {
     103               4 :         seg_data.Get(32,16,geosys);
     104                 :         
     105               4 :         if( seg_data.GetInt(48,8) != 3 || seg_data.GetInt(56,8) != 3 )
     106               0 :             ThrowPCIDSKException( "Unexpected number of coefficients in POLYNOMIAL GEO segment." );
     107                 : 
     108               4 :         a1   = seg_data.GetDouble(212+26*0,26);
     109               4 :         a2   = seg_data.GetDouble(212+26*1,26);
     110               4 :         xrot = seg_data.GetDouble(212+26*2,26);
     111                 : 
     112               4 :         b1   = seg_data.GetDouble(1642+26*0,26);
     113               4 :         yrot = seg_data.GetDouble(1642+26*1,26);
     114               4 :         b3   = seg_data.GetDouble(1642+26*2,26);
     115                 :     }
     116                 : 
     117                 : /* -------------------------------------------------------------------- */
     118                 : /*      Handle the case of a PROJECTION segment - for now we ignore     */
     119                 : /*      the actual projection parameters.                               */
     120                 : /* -------------------------------------------------------------------- */
     121             257 :     else if( strncmp(seg_data.buffer,"PROJECTION",10) == 0 )
     122                 :     {
     123             213 :         seg_data.Get(32,16,geosys);
     124                 :         
     125             213 :         if( seg_data.GetInt(48,8) != 3 || seg_data.GetInt(56,8) != 3 )
     126               0 :             ThrowPCIDSKException( "Unexpected number of coefficients in POLYNOMIAL GEO segment." );
     127                 : 
     128             213 :         a1   = seg_data.GetDouble(1980+26*0,26);
     129             213 :         a2   = seg_data.GetDouble(1980+26*1,26);
     130             213 :         xrot = seg_data.GetDouble(1980+26*2,26);
     131                 : 
     132             213 :         b1   = seg_data.GetDouble(2526+26*0,26);
     133             213 :         yrot = seg_data.GetDouble(2526+26*1,26);
     134             213 :         b3   = seg_data.GetDouble(2526+26*2,26);
     135                 :     }
     136                 : 
     137                 : /* -------------------------------------------------------------------- */
     138                 : /*      Blank segment, just created and we just initialize things a bit.*/
     139                 : /* -------------------------------------------------------------------- */
     140              44 :     else if( memcmp(seg_data.buffer,
     141                 :                     "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",16) == 0 )
     142                 :     {
     143              44 :         geosys = "";
     144                 :         
     145              44 :         a1 = 0.0;
     146              44 :         a2 = 1.0;
     147              44 :         xrot = 0.0;
     148              44 :         b1 = 0.0;
     149              44 :         yrot = 0.0;
     150              44 :         b3 = 1.0;
     151                 :     }
     152                 : 
     153                 :     else
     154                 :     {
     155                 :         ThrowPCIDSKException( "Unexpected GEO segment type: %s", 
     156               0 :                               seg_data.Get(0,16) );
     157                 :     }
     158                 : }
     159                 : 
     160                 : /************************************************************************/
     161                 : /*                             GetGeosys()                              */
     162                 : /************************************************************************/
     163                 : 
     164              44 : std::string CPCIDSKGeoref::GetGeosys()
     165                 : 
     166                 : {
     167              44 :     Load();
     168              44 :     return geosys;
     169                 : }
     170                 : 
     171                 : /************************************************************************/
     172                 : /*                            GetTransform()                            */
     173                 : /************************************************************************/
     174                 : 
     175                 : void CPCIDSKGeoref::GetTransform( double &a1, double &a2, double &xrot, 
     176              45 :                                   double &b1, double &yrot, double &b3 )
     177                 : 
     178                 : {
     179              45 :     Load();
     180                 : 
     181              45 :     a1   = this->a1;
     182              45 :     a2   = this->a2;
     183              45 :     xrot = this->xrot;
     184              45 :     b1   = this->b1;
     185              45 :     yrot = this->yrot;
     186              45 :     b3   = this->b3;
     187              45 : }
     188                 : 
     189                 : /************************************************************************/
     190                 : /*                           GetParameters()                            */
     191                 : /************************************************************************/
     192                 : 
     193               2 : std::vector<double> CPCIDSKGeoref::GetParameters()
     194                 : 
     195                 : {
     196                 :     unsigned int  i;
     197               2 :     std::vector<double> parms;
     198                 : 
     199               2 :     Load();
     200                 : 
     201               2 :     parms.resize(18);
     202                 : 
     203               2 :     if( strncmp(seg_data.buffer,"PROJECTION",10) != 0 )
     204                 :     {
     205              18 :         for( i = 0; i < 17; i++ )
     206              17 :             parms[i] = 0.0;
     207               1 :         parms[17] = -1.0;
     208                 :     }
     209                 :     else
     210                 :     {
     211              18 :         for( i = 0; i < 17; i++ )
     212              17 :             parms[i] = seg_data.GetDouble(80+26*i,26);
     213                 : 
     214               1 :         std::string grid_units;
     215               1 :         seg_data.Get(64,16,grid_units);
     216                 : 
     217               1 :         if( EQUALN(grid_units.c_str(),"DEGREE",3) )
     218               0 :             parms[17] = (double) (int) UNIT_DEGREE;
     219               1 :         else if( EQUALN(grid_units.c_str(),"MET",3) )
     220               1 :             parms[17] = (double) (int) UNIT_METER;
     221               0 :         else if( EQUALN(grid_units.c_str(),"FOOT",4) )
     222               0 :             parms[17] = (double) (int) UNIT_US_FOOT;
     223               0 :         else if( EQUALN(grid_units.c_str(),"FEET",4) )
     224               0 :             parms[17] = (double) (int) UNIT_US_FOOT;
     225               0 :         else if( EQUALN(grid_units.c_str(),"INTL FOOT",5) )
     226               0 :             parms[17] = (double) (int) UNIT_INTL_FOOT;
     227                 :         else
     228               0 :             parms[17] = -1.0; /* unknown */
     229                 :     }
     230                 : 
     231               0 :     return parms;
     232                 : }
     233                 : 
     234                 : /************************************************************************/
     235                 : /*                            WriteSimple()                             */
     236                 : /************************************************************************/
     237                 : 
     238                 : void CPCIDSKGeoref::WriteSimple( std::string const& geosys, 
     239                 :                                  double a1, double a2, double xrot, 
     240             128 :                                  double b1, double yrot, double b3 )
     241                 : 
     242                 : {
     243             128 :     Load();
     244                 : 
     245             128 :     std::string geosys_clean(ReformatGeosys( geosys ));
     246                 : 
     247                 : /* -------------------------------------------------------------------- */
     248                 : /*      Establish the appropriate units code when possible.             */
     249                 : /* -------------------------------------------------------------------- */
     250             128 :     std::string units_code = "METER";
     251                 : 
     252             256 :     if( EQUALN(geosys_clean.c_str(),"FOOT",4) )
     253               0 :         units_code = "FOOT";
     254             128 :     else if( EQUALN(geosys_clean.c_str(),"SPAF",4) )
     255               0 :         units_code = "FOOT";
     256             128 :     else if( EQUALN(geosys_clean.c_str(),"SPIF",4) )
     257               0 :         units_code = "INTL FOOT";
     258             128 :     else if( EQUALN(geosys_clean.c_str(),"LONG",4) )
     259              41 :         units_code = "DEEGREE";
     260                 :         
     261                 : /* -------------------------------------------------------------------- */
     262                 : /*      Write a fairly simple PROJECTION segment.                       */
     263                 : /* -------------------------------------------------------------------- */
     264             128 :     seg_data.SetSize( 6 * 512 );
     265                 : 
     266             128 :     seg_data.Put( " ", 0, seg_data.buffer_size );
     267                 : 
     268                 :     // SD.PRO.P1
     269             128 :     seg_data.Put( "PROJECTION", 0, 16 );
     270                 :     
     271                 :     // SD.PRO.P2
     272             128 :     seg_data.Put( "PIXEL", 16, 16 );
     273                 :     
     274                 :     // SD.PRO.P3
     275             128 :     seg_data.Put( geosys_clean.c_str(), 32, 16 );
     276                 : 
     277                 :     // SD.PRO.P4
     278             128 :     seg_data.Put( 3, 48, 8 );
     279                 :     
     280                 :     // SD.PRO.P5
     281             128 :     seg_data.Put( 3, 56, 8 );
     282                 : 
     283                 :     // SD.PRO.P6 
     284             128 :     seg_data.Put( units_code.c_str(), 64, 16 );
     285                 : 
     286                 :     // SD.PRO.P7 - P22
     287            2304 :     for( int i = 0; i < 17; i++ )
     288            2176 :         seg_data.Put( 0.0,   80 + i*26, 26, "%26.18E" );
     289                 :     
     290                 :     // SD.PRO.P24
     291             128 :     PrepareGCTPFields();
     292                 : 
     293                 :     // SD.PRO.P26
     294             128 :     seg_data.Put( a1,  1980 + 0*26, 26, "%26.18E" );
     295             128 :     seg_data.Put( a2,  1980 + 1*26, 26, "%26.18E" );
     296             128 :     seg_data.Put( xrot,1980 + 2*26, 26, "%26.18E" );
     297                 : 
     298                 :     // SD.PRO.P27
     299             128 :     seg_data.Put( b1,   2526 + 0*26, 26, "%26.18E" );
     300             128 :     seg_data.Put( yrot, 2526 + 1*26, 26, "%26.18E" );
     301             128 :     seg_data.Put( b3,   2526 + 2*26, 26, "%26.18E" );
     302                 : 
     303             128 :     WriteToFile( seg_data.buffer, 0, seg_data.buffer_size );
     304                 : 
     305             128 :     loaded = false;
     306             128 : }
     307                 : 
     308                 : /************************************************************************/
     309                 : /*                          WriteParameters()                           */
     310                 : /************************************************************************/
     311                 : 
     312              42 : void CPCIDSKGeoref::WriteParameters( std::vector<double> const& parms )
     313                 : 
     314                 : {
     315              42 :     Load();
     316                 : 
     317              42 :     if( parms.size() < 17 )
     318               0 :         ThrowPCIDSKException( "Did not get expected number of paramters in WriteParameters()" );
     319                 : 
     320                 :     unsigned int i;
     321                 : 
     322             756 :     for( i = 0; i < 17; i++ )
     323             714 :         seg_data.Put(parms[i],80+26*i,26,"%26.16f");
     324                 : 
     325              42 :     if( parms.size() >= 18 )
     326                 :     {
     327              42 :         switch( (UnitCode) (int) parms[17] ) 
     328                 :         {
     329                 :           case UNIT_DEGREE:
     330              41 :             seg_data.Put( "DEGREE", 64, 16 );
     331              41 :             break;
     332                 : 
     333                 :           case UNIT_METER:
     334               1 :             seg_data.Put( "METER", 64, 16 );
     335               1 :             break;
     336                 : 
     337                 :           case UNIT_US_FOOT:
     338               0 :             seg_data.Put( "FOOT", 64, 16 );
     339               0 :             break;
     340                 : 
     341                 :           case UNIT_INTL_FOOT:
     342               0 :             seg_data.Put( "INTL FOOT", 64, 16 );
     343                 :             break;
     344                 :         }
     345                 :     }
     346                 : 
     347              42 :     PrepareGCTPFields();
     348                 : 
     349              42 :     WriteToFile( seg_data.buffer, 0, seg_data.buffer_size );
     350                 : 
     351                 :     // no need to mark loaded false, since we don't cache these parameters.
     352              42 : }
     353                 : 
     354                 : /************************************************************************/
     355                 : /*                         GetUSGSParameters()                          */
     356                 : /************************************************************************/
     357                 : 
     358               0 : std::vector<double> CPCIDSKGeoref::GetUSGSParameters()
     359                 : 
     360                 : {
     361                 :     unsigned int  i;
     362               0 :     std::vector<double> parms;
     363                 : 
     364               0 :     Load();
     365                 : 
     366               0 :     parms.resize(19);
     367               0 :     if( strncmp(seg_data.buffer,"PROJECTION",10) != 0 )
     368                 :     {
     369               0 :         for( i = 0; i < 19; i++ )
     370               0 :             parms[i] = 0.0;
     371                 :     }
     372                 :     else
     373                 :     {
     374               0 :         for( i = 0; i < 19; i++ )
     375               0 :             parms[i] = seg_data.GetDouble(1458+26*i,26);
     376                 :     }
     377                 : 
     378               0 :     return parms;
     379                 : }
     380                 : 
     381                 : /************************************************************************/
     382                 : /*                           ReformatGeosys()                           */
     383                 : /*                                                                      */
     384                 : /*      Put a geosys string into standard form.  Similar to what the    */
     385                 : /*      DecodeGeosys() function in the PCI SDK does.                    */
     386                 : /************************************************************************/
     387                 : 
     388             298 : std::string CPCIDSKGeoref::ReformatGeosys( std::string const& geosys )
     389                 : 
     390                 : {
     391                 : /* -------------------------------------------------------------------- */
     392                 : /*      Put into a local buffer and pad out to 16 characters with       */
     393                 : /*      spaces.                                                         */
     394                 : /* -------------------------------------------------------------------- */
     395                 :     char local_buf[33];
     396                 : 
     397             298 :     strncpy( local_buf, geosys.c_str(), 16 );
     398             298 :     local_buf[16] = '\0';
     399             298 :     strcat( local_buf, "                " );
     400             298 :     local_buf[16] = '\0';
     401                 :     
     402                 : /* -------------------------------------------------------------------- */
     403                 : /*      Extract the earth model from the geosys string.                 */
     404                 : /* -------------------------------------------------------------------- */
     405                 :     char earthmodel[5];
     406                 :     const char  *cp;
     407                 :     int   i;
     408                 :     char  last;
     409                 : 
     410             298 :     cp = local_buf;
     411            5066 :     while( cp < local_buf + 16 && cp[1] != '\0' )
     412            4470 :         cp++;
     413                 : 
     414            2488 :     while( cp > local_buf && isspace(*cp) )
     415            1892 :         cp--;
     416                 : 
     417             298 :     last = '\0';
     418             974 :     while( cp > local_buf 
     419                 :            && (isdigit((unsigned char)*cp)
     420                 :                || *cp == '-' || *cp == '+' ) )
     421                 :     {
     422             378 :         if( last == '\0' )  last = *cp;
     423             378 :         cp--;
     424                 :     }
     425                 : 
     426             424 :     if( isdigit( (unsigned char)last ) &&
     427                 :         ( *cp == 'D' || *cp == 'd' ||
     428                 :           *cp == 'E' || *cp == 'e'    ) )
     429                 :     {
     430             126 :         i = atoi( cp+1 );
     431             252 :         if(    i > -100 && i < 1000 
     432                 :                && (cp == local_buf
     433                 :                    || ( cp >  local_buf && isspace( *(cp-1) ) )
     434                 :                    )
     435                 :                )
     436                 :         {
     437             249 :             if( *cp == 'D' || *cp == 'd' )
     438             123 :                 sprintf( earthmodel, "D%03d", i );
     439                 :             else
     440               3 :                 sprintf( earthmodel, "E%03d", i );
     441                 :         }
     442                 :         else
     443                 :         {
     444               0 :             sprintf( earthmodel, "    " );
     445                 :         }
     446                 :     }
     447                 :     else
     448                 :     {
     449             172 :         sprintf( earthmodel, "    " );
     450                 :     }
     451                 : 
     452                 : /* -------------------------------------------------------------------- */
     453                 : /*      Identify by geosys string.                                      */
     454                 : /* -------------------------------------------------------------------- */
     455                 :     const char *ptr;
     456                 :     int zone, ups_zone;
     457             298 :     char zone_code = ' ';
     458                 : 
     459             298 :     if( EQUALN(local_buf,"PIX",3) )
     460                 :     {
     461             172 :         strcpy( local_buf, "PIXEL           " );
     462                 :     }
     463             126 :     else if( EQUALN(local_buf,"UTM",3) )
     464                 :     {
     465                 :         /* Attempt to find a zone and ellipsoid */
     466               3 :         for( ptr=local_buf+3; isspace(*ptr); ptr++ ) {}
     467               6 :         if( isdigit( (unsigned char)*ptr ) || *ptr == '-' )
     468                 :         {
     469               3 :             zone = atoi(ptr);
     470               3 :             for( ; isdigit((unsigned char)*ptr) || *ptr == '-'; ptr++ ) {}
     471               3 :             for( ; isspace(*ptr); ptr++ ) {}
     472               3 :             if( isalpha(*ptr) && !isdigit((unsigned char)*(ptr+1)) )
     473               0 :                 zone_code = *(ptr++);
     474                 :         }
     475                 :         else
     476               0 :             zone = -100;
     477                 : 
     478               6 :         if( zone >= -60 && zone <= 60 && zone != 0 )
     479                 :         {
     480               3 :             if( zone_code >= 'a' && zone_code <= 'z' )
     481               0 :                 zone_code = zone_code - 'a' + 'A';
     482                 : 
     483               3 :             if( zone_code == ' ' && zone < 0 )
     484               0 :                 zone_code = 'C';
     485                 : 
     486               3 :             zone = ABS(zone);
     487                 : 
     488                 :             sprintf( local_buf,
     489                 :                      "UTM   %3d %c %4s", 
     490               3 :                      zone, zone_code, earthmodel );
     491                 :         }
     492                 :         else
     493                 :         { 
     494                 :             sprintf( local_buf, 
     495                 :                      "UTM         %4s", 
     496               0 :                      earthmodel );
     497                 :         }
     498               3 :         if( local_buf[14] == ' ' )
     499               0 :             local_buf[14] = '0';
     500               3 :         if( local_buf[13] == ' ' )
     501               0 :             local_buf[13] = '0';
     502                 :     }
     503             123 :     else if( EQUALN(local_buf,"MET",3) )
     504                 :     {
     505               0 :         sprintf( local_buf, "METRE       %4s", earthmodel );
     506                 :     }
     507             123 :     else if( EQUALN(local_buf,"FEET",4) || EQUALN(local_buf,"FOOT",4))
     508                 :     {
     509               0 :         sprintf( local_buf, "FOOT        %4s", earthmodel );
     510                 :     }
     511             123 :     else if( EQUALN(local_buf,"LAT",3) ||
     512                 :              EQUALN(local_buf,"LON",3) )
     513                 :     {
     514                 :         sprintf( local_buf, 
     515                 :                  "LONG/LAT    %4s",
     516             123 :                  earthmodel );
     517                 :     }
     518               0 :     else if( EQUALN(local_buf,"SPCS ",5) ||
     519                 :              EQUALN(local_buf,"SPAF ",5) ||
     520                 :              EQUALN(local_buf,"SPIF ",5) )
     521                 :     {
     522               0 :         int nSPZone = 0;
     523                 : 
     524               0 :         for( ptr=local_buf+4; isspace(*ptr); ptr++ ) {}
     525               0 :         nSPZone = atoi(ptr);
     526                 : 
     527               0 :         if      ( EQUALN(local_buf,"SPCS ",5) ) 
     528               0 :             strcpy( local_buf, "SPCS " );
     529               0 :         else if ( EQUALN(local_buf,"SPAF ",5) ) 
     530               0 :             strcpy( local_buf, "SPAF " );
     531                 :         else
     532               0 :             strcpy( local_buf, "SPIF " );
     533                 : 
     534               0 :         if( nSPZone != 0 )
     535               0 :             sprintf( local_buf + 5, "%4d   %4s",nSPZone,earthmodel);
     536                 :         else
     537               0 :             sprintf( local_buf + 5, "       %4s",earthmodel);
     538                 : 
     539                 :     }
     540               0 :     else if( EQUALN(local_buf,"ACEA ",5) )
     541                 :     {
     542                 :         sprintf( local_buf, 
     543                 :                  "ACEA        %4s",
     544               0 :                  earthmodel );
     545                 :     }
     546               0 :     else if( EQUALN(local_buf,"AE ",3) )
     547                 :     {
     548                 :         sprintf( local_buf, 
     549                 :                  "AE          %4s",
     550               0 :                  earthmodel );
     551                 :     }
     552               0 :     else if( EQUALN(local_buf,"EC ",3) )
     553                 :     {
     554                 :         sprintf( local_buf, 
     555                 :                  "EC          %4s",
     556               0 :                  earthmodel );
     557                 :     }
     558               0 :     else if( EQUALN(local_buf,"ER ",3) )
     559                 :     {
     560                 :         sprintf( local_buf, 
     561                 :                  "ER          %4s",
     562               0 :                  earthmodel );
     563                 :     }
     564               0 :     else if( EQUALN(local_buf,"GNO ",4) )
     565                 :     {
     566                 :         sprintf( local_buf, 
     567                 :                  "GNO         %4s",
     568               0 :                  earthmodel );
     569                 :     }
     570               0 :     else if( EQUALN(local_buf,"GVNP",4) )
     571                 :     {
     572                 :         sprintf( local_buf, 
     573                 :                  "GVNP        %4s",
     574               0 :                  earthmodel );
     575                 :     }
     576               0 :     else if( EQUALN(local_buf,"LAEA_ELL",8) )
     577                 :     {
     578                 :         sprintf( local_buf, 
     579                 :                  "LAEA_ELL    %4s",
     580               0 :                  earthmodel );
     581                 :     }
     582               0 :     else if( EQUALN(local_buf,"LAEA",4) )
     583                 :     {
     584                 :         sprintf( local_buf, 
     585                 :                  "LAEA        %4s",
     586               0 :                  earthmodel );
     587                 :     }
     588               0 :     else if( EQUALN(local_buf,"LCC_1SP",7) )
     589                 :     {
     590                 :         sprintf( local_buf, 
     591                 :                  "LCC_1SP     %4s",
     592               0 :                  earthmodel );
     593                 :     }
     594               0 :     else if( EQUALN(local_buf,"LCC ",4) )
     595                 :     {
     596                 :         sprintf( local_buf, 
     597                 :                  "LCC         %4s",
     598               0 :                  earthmodel );
     599                 :     }
     600               0 :     else if( EQUALN(local_buf,"MC ",3) )
     601                 :     {
     602                 :         sprintf( local_buf, 
     603                 :                  "MC          %4s",
     604               0 :                  earthmodel );
     605                 :     }
     606               0 :     else if( EQUALN(local_buf,"MER ",4) )
     607                 :     {
     608                 :         sprintf( local_buf, 
     609                 :                  "MER         %4s",
     610               0 :                  earthmodel );
     611                 :     }
     612               0 :     else if( EQUALN(local_buf,"MSC ",4) )
     613                 :     {
     614                 :         sprintf( local_buf, 
     615                 :                  "MSC         %4s",
     616               0 :                  earthmodel );
     617                 :     }
     618               0 :     else if( EQUALN(local_buf,"OG ",3) )
     619                 :     {
     620                 :         sprintf( local_buf, 
     621                 :                  "OG          %4s",
     622               0 :                  earthmodel );
     623                 :     }
     624               0 :     else if( EQUALN(local_buf,"OM ",3) )
     625                 :     {
     626                 :         sprintf( local_buf, 
     627                 :                  "OM          %4s",
     628               0 :                  earthmodel );
     629                 :     }
     630               0 :     else if( EQUALN(local_buf,"PC ",3) )
     631                 :     {
     632                 :         sprintf( local_buf, 
     633                 :                  "PC          %4s",
     634               0 :                  earthmodel );
     635                 :     }
     636               0 :     else if( EQUALN(local_buf,"PS ",3) )
     637                 :     {
     638                 :         sprintf( local_buf, 
     639                 :                  "PS          %4s",
     640               0 :                  earthmodel );
     641                 :     }
     642               0 :     else if( EQUALN(local_buf,"ROB ",4) )
     643                 :     {
     644                 :         sprintf( local_buf, 
     645                 :                  "ROB         %4s",
     646               0 :                  earthmodel );
     647                 :     }
     648               0 :     else if( EQUALN(local_buf,"SG ",3) )
     649                 :     {
     650                 :         sprintf( local_buf, 
     651                 :                  "SG          %4s",
     652               0 :                  earthmodel );
     653                 :     }
     654               0 :     else if( EQUALN(local_buf,"SIN ",4) )
     655                 :     {
     656                 :         sprintf( local_buf, 
     657                 :                  "SIN         %4s",
     658               0 :                  earthmodel );
     659                 :     }
     660               0 :     else if( EQUALN(local_buf,"SOM ",4) )
     661                 :     {
     662                 :         sprintf( local_buf, 
     663                 :                  "SOM         %4s",
     664               0 :                  earthmodel );
     665                 :     }
     666               0 :     else if( EQUALN(local_buf,"TM ",3) )
     667                 :     {
     668                 :         sprintf( local_buf, 
     669                 :                  "TM          %4s",
     670               0 :                  earthmodel );
     671                 :     }
     672               0 :     else if( EQUALN(local_buf,"VDG ",4) )
     673                 :     {
     674                 :         sprintf( local_buf, 
     675                 :                  "VDG         %4s",
     676               0 :                  earthmodel );
     677                 :     }
     678               0 :     else if( EQUALN(local_buf,"UPSA",4) )
     679                 :     {
     680                 :         sprintf( local_buf, 
     681                 :                  "UPSA        %4s",
     682               0 :                  earthmodel );
     683                 :     }
     684               0 :     else if( EQUALN(local_buf,"UPS ",4) )
     685                 :     {
     686                 :         /* Attempt to find UPS zone */
     687               0 :         for( ptr=local_buf+3; isspace(*ptr); ptr++ ) {}
     688               0 :         if( *ptr == 'A' || *ptr == 'B' || *ptr == 'Y' || *ptr == 'Z' )
     689               0 :             ups_zone = *ptr;
     690               0 :         else if( *ptr == 'a' || *ptr == 'b' || *ptr == 'y' || *ptr == 'z' )
     691               0 :             ups_zone = toupper( *ptr );
     692                 :         else
     693               0 :             ups_zone = ' ';
     694                 : 
     695                 :         sprintf( local_buf, 
     696                 :                  "UPS       %c %4s",
     697               0 :                  ups_zone, earthmodel );
     698                 :     }
     699               0 :     else if( EQUALN(local_buf,"GOOD",4) )
     700                 :     {
     701                 :         sprintf( local_buf, 
     702                 :                  "GOOD        %4s",
     703               0 :                  earthmodel );
     704                 :     }
     705               0 :     else if( EQUALN(local_buf,"NZMG",4) )
     706                 :     {
     707                 :         sprintf( local_buf, 
     708                 :                  "NZMG        %4s",
     709               0 :                  earthmodel );
     710                 :     }
     711               0 :     else if( EQUALN(local_buf,"CASS",4) )
     712                 :     {
     713               0 :         if( EQUALN( earthmodel, "D000", 4 ) )
     714               0 :             sprintf( local_buf,  "CASS        %4s", "E010" );
     715                 :         else
     716               0 :             sprintf( local_buf,  "CASS        %4s", earthmodel );
     717                 :     }
     718               0 :     else if( EQUALN(local_buf,"RSO ",4) )
     719                 :     {
     720               0 :         if( EQUALN( earthmodel, "D000", 4 ) )
     721               0 :             sprintf( local_buf,  "RSO         %4s", "E010" );
     722                 :         else
     723               0 :             sprintf( local_buf,  "RSO         %4s", earthmodel );
     724                 :     }
     725               0 :     else if( EQUALN(local_buf,"KROV",4) )
     726                 :     {
     727               0 :         if( EQUALN( earthmodel, "D000", 4 ) )
     728               0 :             sprintf( local_buf,  "KROV        %4s", "E002" );
     729                 :         else
     730               0 :             sprintf( local_buf,  "KROV        %4s", earthmodel );
     731                 :     }
     732               0 :     else if( EQUALN(local_buf,"KRON",4) )
     733                 :     {
     734               0 :         if( EQUALN( earthmodel, "D000", 4 ) )
     735               0 :             sprintf( local_buf,  "KRON        %4s", "E002" );
     736                 :         else
     737               0 :             sprintf( local_buf,  "KRON        %4s", earthmodel );
     738                 :     }
     739               0 :     else if( EQUALN(local_buf,"SGDO",4) )
     740                 :     {
     741               0 :         if( EQUALN( earthmodel, "D000", 4 ) )
     742               0 :             sprintf( local_buf,  "SGDO        %4s", "E910" );
     743                 :         else
     744               0 :             sprintf( local_buf,  "SGDO        %4s", earthmodel );
     745                 :     }
     746               0 :     else if( EQUALN(local_buf,"LBSG",4) )
     747                 :     {
     748               0 :         if( EQUALN( earthmodel, "D000", 4 ) )
     749               0 :             sprintf( local_buf,  "LBSG        %4s", "E202" );
     750                 :         else
     751               0 :             sprintf( local_buf,  "LBSG        %4s", earthmodel );
     752                 :     }
     753               0 :     else if( EQUALN(local_buf,"ISIN",4) )
     754                 :     {
     755               0 :         if( EQUALN( earthmodel, "D000", 4 ) )
     756               0 :             sprintf( local_buf,  "ISIN        %4s", "E700" );
     757                 :         else
     758               0 :             sprintf( local_buf,  "ISIN        %4s", earthmodel );
     759                 :     }
     760                 : /* -------------------------------------------------------------------- */
     761                 : /*      This may be a user projection. Just reformat the earth model    */
     762                 : /*      portion.                                                        */
     763                 : /* -------------------------------------------------------------------- */
     764                 :     else
     765                 :     {
     766               0 :         sprintf( local_buf, "%-11.11s %4s", geosys.c_str(), earthmodel );
     767                 :     }
     768                 : 
     769             298 :     return local_buf;
     770                 : }
     771                 : 
     772                 : /*
     773                 : C       PAK2PCI converts a Latitude or Longitude value held in decimal
     774                 : C       form to or from the standard packed DMS format DDDMMMSSS.SSS.
     775                 : C       The standard packed DMS format is the required format for any
     776                 : C       Latitude or Longitude value in the projection parameter array
     777                 : C       (TPARIN and/or TPARIO) in calling the U.S.G.S. GCTP package,
     778                 : C       but is not required for the actual coordinates to be converted.
     779                 : C This routine has been coverted from the PAKPCI fortran routine.
     780                 : C
     781                 : C       When function is 1, the value returned is made up as follows:
     782                 : C
     783                 : C       PACK2PCI = (DDD * 1000000) + (MMM * 1000) + SSS.SSS
     784                 : C
     785                 : C       When function is 0, the value returned is made up as follows:
     786                 : C
     787                 : C       PACK2PCI = DDD + MMM/60 + SSS/3600
     788                 : C
     789                 : C       where:   DDD     are the degrees
     790                 : C                MMM     are the minutes
     791                 : C                SSS.SSS are the seconds
     792                 : C
     793                 : C       The sign of the input value is retained and will denote the
     794                 : C       hemisphere (For longitude, (-) is West and (+) is East of
     795                 : C       Greenwich;  For latitude, (-) is South and (+) is North of
     796                 : C       the equator).
     797                 : C
     798                 : C
     799                 : C       CALL SEQUENCE
     800                 : C
     801                 : C       double = PACK2PCI (degrees, function)
     802                 : C
     803                 : C       degrees  - (double) Latitude or Longitude value in decimal 
     804                 : C                     degrees.
     805                 : C
     806                 : C       function - (Int)    Function to perform                            
     807                 : C                           1, convert decimal degrees to DDDMMMSSS.SSS
     808                 : C                           0, convert DDDMMMSSS.SSS to decimal degrees
     809                 : C
     810                 : C
     811                 : C       EXAMPLE
     812                 : C
     813                 : C       double    degrees, packed, unpack 
     814                 : C
     815                 : C       degrees = -125.425              ! Same as 125d 25' 30" W
     816                 : C       packed = PACK2PCI (degrees, 1)  ! PACKED will equal -125025030.000
     817                 : C       unpack = PACK2PCI (degrees, 0)  ! UNPACK will equal -125.425
     818                 : */
     819                 : 
     820                 : /************************************************************************/
     821                 : /*                              PAK2PCI()                               */
     822                 : /************************************************************************/
     823                 : 
     824               4 : static double PAK2PCI( double deg, int function )
     825                 : {
     826                 :         double    new_deg;
     827                 :         int       sign;
     828                 :         double    result;
     829                 : 
     830                 :   double    degrees;
     831                 :         double    temp1, temp2, temp3;
     832                 :         int       dd, mm;
     833                 :         double    ss;
     834                 : 
     835               4 :         sign = (int)(1.0);
     836               4 :   degrees = deg;
     837                 : 
     838               4 :         if ( degrees < 0 )
     839                 :         {
     840               2 :            sign = (int)(-1.0);
     841               2 :            degrees = degrees * sign;
     842                 :         }
     843                 : 
     844                 : /* -------------------------------------------------------------------- */
     845                 : /*  Unpack the value.           */
     846                 : /* -------------------------------------------------------------------- */
     847               4 :         if ( function == 0 )
     848                 :         {
     849               0 :            new_deg = (double) ABS( degrees );
     850                 : 
     851               0 :            dd =  (int)( new_deg / 1000000.0);
     852                 : 
     853               0 :            new_deg = ( new_deg - (dd * 1000000) );
     854               0 :            mm = (int)(new_deg/(1000));
     855                 : 
     856               0 :            new_deg = ( new_deg - (mm * 1000) );
     857                 : 
     858               0 :            ss = new_deg;
     859                 : 
     860               0 :            result = (double) sign * ( dd + mm/60.0 + ss/3600.0 );
     861                 :         }
     862                 :         else
     863                 :         {
     864                 : /* -------------------------------------------------------------------- */
     865                 : /*  Procduce DDDMMMSSS.SSS from decimal degrees.      */
     866                 : /* -------------------------------------------------------------------- */
     867               4 :            new_deg = (double) ((int)degrees % 360);
     868               4 :            temp1 =  degrees - new_deg;
     869                 : 
     870               4 :            temp2 = temp1 * 60;
     871                 : 
     872               4 :            mm = (int)((temp2 * 60) / 60);
     873                 : 
     874               4 :            temp3 = temp2 - mm;
     875               4 :            ss = temp3 * 60;
     876                 : 
     877                 :            result = (double) sign *
     878               4 :                 ( (new_deg * 1000000) + (mm * 1000) + ss);
     879                 :         }
     880               4 :   return result;
     881                 : }
     882                 : 
     883                 : /************************************************************************/
     884                 : /*                         PrepareGCTPFields()                          */
     885                 : /*                                                                      */
     886                 : /*      Fill the GCTP fields in the seg_data image based on the         */
     887                 : /*      non-GCTP values.                                                */
     888                 : /************************************************************************/
     889                 : 
     890             170 : void CPCIDSKGeoref::PrepareGCTPFields()
     891                 : 
     892                 : {
     893                 :     enum GCTP_UNIT_CODES {
     894                 :         GCTP_UNIT_UNKNOWN = -1, /*    Default, NOT a valid code     */
     895                 :         GCTP_UNIT_RADIAN  =  0, /* 0, NOT used at present           */
     896                 :         GCTP_UNIT_US_FOOT,      /* 1, Used for GEO_SPAF             */
     897                 :         GCTP_UNIT_METRE,        /* 2, Used for most map projections */
     898                 :         GCTP_UNIT_SECOND,       /* 3, NOT used at present           */
     899                 :         GCTP_UNIT_DEGREE,       /* 4, Used for GEO_LONG             */
     900                 :         GCTP_UNIT_INTL_FOOT,    /* 5, Used for GEO_SPIF             */
     901                 :         GCTP_UNIT_TABLE         /* 6, NOT used at present           */
     902                 :     };
     903                 : 
     904             170 :     seg_data.Get(32,16,geosys);
     905             170 :     std::string geosys_clean(ReformatGeosys( geosys ));
     906                 : 
     907                 : /* -------------------------------------------------------------------- */
     908                 : /*      Establish the GCTP units code.                                  */
     909                 : /* -------------------------------------------------------------------- */
     910             170 :     double IOmultiply = 1.0;
     911             170 :     int UnitsCode = GCTP_UNIT_METRE;
     912                 : 
     913             170 :     std::string grid_units;
     914             170 :     seg_data.Get(64,16,grid_units);
     915                 : 
     916             170 :     if( EQUALN(grid_units.c_str(),"MET",3) )
     917              88 :         UnitsCode = GCTP_UNIT_METRE;
     918              82 :     else if( EQUALN( grid_units.c_str(), "FOOT", 4 ) )
     919                 :     {
     920               0 :         UnitsCode = GCTP_UNIT_US_FOOT;
     921               0 :         IOmultiply = 1.0 / 0.3048006096012192;
     922                 :     }
     923              82 :     else if( EQUALN( grid_units.c_str(), "INTL FOOT", 9 ) )
     924                 :     {
     925               0 :         UnitsCode = GCTP_UNIT_INTL_FOOT;
     926               0 :         IOmultiply = 1.0 / 0.3048;
     927                 :     }
     928              82 :     else if( EQUALN( grid_units.c_str(), "DEGREE", 6 ) )
     929              41 :         UnitsCode = GCTP_UNIT_DEGREE;
     930                 :     
     931                 : /* -------------------------------------------------------------------- */
     932                 : /*      Extract the non-GCTP style parameters.                          */
     933                 : /* -------------------------------------------------------------------- */
     934                 :     double pci_parms[17];
     935                 :     int i;
     936                 : 
     937            3060 :     for( i = 0; i < 17; i++ )
     938            2890 :         pci_parms[i] = seg_data.GetDouble(80+26*i,26);
     939                 : 
     940                 : #define Dearth0                 pci_parms[0]
     941                 : #define Dearth1                 pci_parms[1]
     942                 : #define RefLong                 pci_parms[2]
     943                 : #define RefLat                  pci_parms[3]
     944                 : #define StdParallel1            pci_parms[4]
     945                 : #define StdParallel2            pci_parms[5]
     946                 : #define FalseEasting            pci_parms[6]
     947                 : #define FalseNorthing           pci_parms[7]
     948                 : #define Scale                   pci_parms[8]
     949                 : #define Height                  pci_parms[9]
     950                 : #define Long1                   pci_parms[10]
     951                 : #define Lat1                    pci_parms[11]
     952                 : #define Long2                   pci_parms[12]
     953                 : #define Lat2                    pci_parms[13]
     954                 : #define Azimuth                 pci_parms[14]
     955                 : #define LandsatNum              pci_parms[15]
     956                 : #define LandsatPath             pci_parms[16]
     957                 : 
     958                 : /* -------------------------------------------------------------------- */
     959                 : /*      Get the zone code.                                              */
     960                 : /* -------------------------------------------------------------------- */
     961             170 :     int ProjectionZone = 0;
     962                 : 
     963             170 :     if( strncmp(geosys_clean.c_str(),"UTM ",4) == 0 
     964                 :         || strncmp(geosys_clean.c_str(),"SPCS ",5) == 0 
     965                 :         || strncmp(geosys_clean.c_str(),"SPAF ",5) == 0 
     966                 :         || strncmp(geosys_clean.c_str(),"SPIF ",5) == 0 )
     967                 :     {
     968               2 :         ProjectionZone = atoi(geosys_clean.c_str() + 5);
     969                 :     }
     970                 : 
     971                 : /* -------------------------------------------------------------------- */
     972                 : /*      Handle the ellipsoid.  We depend on applications properly       */
     973                 : /*      setting proj_parms[0], and proj_parms[1] with the semi-major    */
     974                 : /*      and semi-minor axes in all other cases.                         */
     975                 : /*                                                                      */
     976                 : /*      I wish we could lookup datum codes to find their GCTP           */
     977                 : /*      ellipsoid values here!                                          */
     978                 : /* -------------------------------------------------------------------- */
     979             170 :     int Spheroid = -1;
     980             170 :     if( geosys_clean[12] == 'E' )
     981               2 :         Spheroid = atoi(geosys_clean.c_str() + 13);
     982                 :     
     983             170 :     if( Spheroid < 0 || Spheroid > 19 )
     984             168 :         Spheroid = -1;
     985                 : 
     986                 : /* -------------------------------------------------------------------- */
     987                 : /*      Initialize the USGS Parameters.                                 */
     988                 : /* -------------------------------------------------------------------- */
     989                 :     double USGSParms[15];
     990                 :     int gsys; 
     991                 : 
     992            2720 :     for ( i = 0; i < 15; i++ )
     993            2550 :         USGSParms[i] = 0;
     994                 :   
     995                 : /* -------------------------------------------------------------------- */
     996                 : /*  Projection 0: Geographic (no projection)      */
     997                 : /* -------------------------------------------------------------------- */
     998             170 :     if( strncmp(geosys_clean.c_str(),"LONG ",5) == 0 )
     999                 :     {
    1000               0 :         gsys = 0;
    1001               0 :         UnitsCode = GCTP_UNIT_DEGREE;
    1002                 :     }
    1003                 : 
    1004                 : /* -------------------------------------------------------------------- */
    1005                 : /*  Projection 1: Universal Transverse Mercator     */
    1006                 : /* -------------------------------------------------------------------- */
    1007             170 :     else if( strncmp(geosys_clean.c_str(),"UTM ",4) == 0 )
    1008                 :     {
    1009               2 :         char row_char = geosys_clean[10];
    1010               2 :         gsys = 1;
    1011                 : 
    1012                 :         // Southern hemisphere?
    1013               2 :         if( (row_char >= 'C') && (row_char <= 'M') && ProjectionZone > 0 )
    1014                 :         {
    1015               0 :             ProjectionZone *= -1;
    1016                 :         }
    1017                 : 
    1018                 : /* -------------------------------------------------------------------- */
    1019                 : /*  Process UTM as TM.  The reason for this is the GCTP software  */
    1020                 : /*  does not provide for input of an Earth Model for UTM, but does  */
    1021                 : /*  for TM.               */
    1022                 : /* -------------------------------------------------------------------- */
    1023               2 :         gsys = 9;
    1024               2 :         USGSParms[0] = Dearth0;
    1025               2 :         USGSParms[1] = Dearth1;
    1026               2 :         USGSParms[2] = 0.9996;
    1027                 : 
    1028                 :         USGSParms[4] = PAK2PCI(
    1029               2 :             ( ABS(ProjectionZone) * 6.0 - 183.0 ), 1 );
    1030               2 :         USGSParms[5] = PAK2PCI( 0.0, 1 );
    1031               2 :         USGSParms[6] =   500000.0;
    1032               2 :         USGSParms[7] = ( ProjectionZone < 0 ) ? 10000000.0 : 0.0;
    1033                 :     }
    1034                 : 
    1035                 : /* -------------------------------------------------------------------- */
    1036                 : /*  Projection 2: State Plane Coordinate System     */
    1037                 : /* -------------------------------------------------------------------- */
    1038             168 :     else if( strncmp(geosys_clean.c_str(),"SPCS ",5) == 0 )
    1039                 :     {
    1040               0 :         gsys = 2;
    1041               0 :         if(    UnitsCode != GCTP_UNIT_METRE
    1042                 :                && UnitsCode != GCTP_UNIT_US_FOOT
    1043                 :                && UnitsCode != GCTP_UNIT_INTL_FOOT )
    1044               0 :             UnitsCode = GCTP_UNIT_METRE;
    1045                 :     }
    1046                 : 
    1047             168 :     else if( strncmp(geosys_clean.c_str(),"SPAF ",5) == 0 )
    1048                 :     {
    1049               0 :         gsys = 2;
    1050               0 :         if(    UnitsCode != GCTP_UNIT_METRE
    1051                 :                && UnitsCode != GCTP_UNIT_US_FOOT
    1052                 :                && UnitsCode != GCTP_UNIT_INTL_FOOT )
    1053               0 :             UnitsCode = GCTP_UNIT_US_FOOT;
    1054                 :     }
    1055                 : 
    1056             168 :     else if( strncmp(geosys_clean.c_str(),"SPIF ",5) == 0 )
    1057                 :     {
    1058               0 :         gsys = 2;
    1059               0 :         if(    UnitsCode != GCTP_UNIT_METRE
    1060                 :                && UnitsCode != GCTP_UNIT_US_FOOT
    1061                 :                && UnitsCode != GCTP_UNIT_INTL_FOOT )
    1062               0 :             UnitsCode = GCTP_UNIT_INTL_FOOT;
    1063                 :     }
    1064                 : 
    1065                 : /* -------------------------------------------------------------------- */
    1066                 : /*  Projection 3: Albers Conical Equal-Area       */
    1067                 : /* -------------------------------------------------------------------- */
    1068             168 :     else if( strncmp(geosys_clean.c_str(),"ACEA ",5) == 0 )
    1069                 :     {
    1070               0 :         gsys = 3;
    1071               0 :         USGSParms[0] = Dearth0;
    1072               0 :         USGSParms[1] = Dearth1;
    1073               0 :         USGSParms[2] = PAK2PCI(StdParallel1, 1);
    1074               0 :         USGSParms[3] = PAK2PCI(StdParallel2, 1);
    1075               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1076               0 :         USGSParms[5] = PAK2PCI(RefLat, 1);
    1077               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1078               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1079                 :     } 
    1080                 : 
    1081                 : /* -------------------------------------------------------------------- */
    1082                 : /*  Projection 4: Lambert Conformal Conic       */ 
    1083                 : /* -------------------------------------------------------------------- */
    1084             168 :     else if( strncmp(geosys_clean.c_str(),"LCC  ",5) == 0 )
    1085                 :     {
    1086               0 :         gsys = 4;
    1087               0 :         USGSParms[0] = Dearth0;
    1088               0 :         USGSParms[1] = Dearth1;
    1089               0 :         USGSParms[2] = PAK2PCI(StdParallel1, 1);
    1090               0 :         USGSParms[3] = PAK2PCI(StdParallel2, 1);
    1091               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1092               0 :         USGSParms[5] = PAK2PCI(RefLat, 1);
    1093               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1094               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1095                 :     } 
    1096                 : 
    1097                 : /* -------------------------------------------------------------------- */
    1098                 : /*  Projection 5: Mercator            */ 
    1099                 : /* -------------------------------------------------------------------- */
    1100             168 :     else if( strncmp(geosys_clean.c_str(),"MER  ",5) == 0 )
    1101                 :     {
    1102               0 :         gsys = 5;
    1103               0 :         USGSParms[0] = Dearth0;
    1104               0 :         USGSParms[1] = Dearth1;
    1105                 :         
    1106               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1107               0 :         USGSParms[5] = PAK2PCI(RefLat, 1);
    1108               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1109               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1110                 :     } 
    1111                 : 
    1112                 : /* -------------------------------------------------------------------- */
    1113                 : /*  Projection 6: Polar Stereographic       */
    1114                 : /* -------------------------------------------------------------------- */
    1115             168 :     else if( strncmp(geosys_clean.c_str(),"PS   ",5) == 0 )
    1116                 :     {
    1117               0 :         gsys = 6;
    1118               0 :         USGSParms[0] = Dearth0;
    1119               0 :         USGSParms[1] = Dearth1;
    1120                 :         
    1121               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1122               0 :         USGSParms[5] = PAK2PCI(RefLat, 1);
    1123               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1124               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1125                 :     } 
    1126                 : 
    1127                 : /* -------------------------------------------------------------------- */
    1128                 : /*  Projection 7: Polyconic           */
    1129                 : /* -------------------------------------------------------------------- */
    1130             168 :     else if( strncmp(geosys_clean.c_str(),"PC   ",5) == 0 )
    1131                 :     {
    1132               0 :         gsys = 7;
    1133               0 :         USGSParms[0] = Dearth0;
    1134               0 :         USGSParms[1] = Dearth1;
    1135                 :         
    1136               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1137               0 :         USGSParms[5] = PAK2PCI(RefLat, 1);
    1138               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1139               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1140                 :     } 
    1141                 : 
    1142                 : /* -------------------------------------------------------------------- */
    1143                 : /*  Projection 8: Equidistant Conic                         */
    1144                 : /*  Format A, one standard parallel,  usgs_params[8] = 0    */
    1145                 : /*      Format B, two standard parallels, usgs_params[8] = not 0  */
    1146                 : /* -------------------------------------------------------------------- */
    1147             168 :     else if( strncmp(geosys_clean.c_str(),"EC   ",5) == 0 )
    1148                 :     {
    1149               0 :         gsys = 8;
    1150               0 :         USGSParms[0] = Dearth0;
    1151               0 :         USGSParms[1] = Dearth1;
    1152               0 :         USGSParms[2] = PAK2PCI(StdParallel1, 1);
    1153               0 :         USGSParms[3] = PAK2PCI(StdParallel2, 1);
    1154               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1155               0 :         USGSParms[5] = PAK2PCI(RefLat, 1);
    1156               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1157               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1158                 : 
    1159               0 :         if ( StdParallel2 != 0 )
    1160                 :         {
    1161               0 :             USGSParms[8] = 1;
    1162                 :         }
    1163                 :     } 
    1164                 : 
    1165                 : /* -------------------------------------------------------------------- */
    1166                 : /*  Projection 9: Transverse Mercator       */ 
    1167                 : /* -------------------------------------------------------------------- */
    1168             168 :     else if( strncmp(geosys_clean.c_str(),"TM   ",5) == 0 )
    1169                 :     {
    1170               0 :         gsys = 9;
    1171               0 :         USGSParms[0] = Dearth0;
    1172               0 :         USGSParms[1] = Dearth1;
    1173               0 :         USGSParms[2] = Scale;
    1174                 :         
    1175               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1176               0 :         USGSParms[5] = PAK2PCI(RefLat, 1);
    1177               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1178               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1179                 :     } 
    1180                 : 
    1181                 : /* -------------------------------------------------------------------- */
    1182                 : /*  Projection 10: Stereographic          */
    1183                 : /* -------------------------------------------------------------------- */
    1184             168 :     else if( strncmp(geosys_clean.c_str(),"SG   ",5) == 0 )
    1185                 :     {
    1186               0 :         gsys = 10;
    1187               0 :         USGSParms[0] = Dearth0;
    1188                 :         
    1189               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1190               0 :         USGSParms[5] = PAK2PCI(RefLat, 1);
    1191               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1192               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1193                 :     } 
    1194                 :     
    1195                 : /* -------------------------------------------------------------------- */
    1196                 : /*  Projection 11: Lambert Azimuthal Equal-Area     */
    1197                 : /* -------------------------------------------------------------------- */
    1198             168 :     else if( strncmp(geosys_clean.c_str(),"LAEA ",5) == 0 )
    1199                 :     {
    1200               0 :         gsys = 11;
    1201                 :         
    1202               0 :         USGSParms[0] = Dearth0;
    1203                 :         
    1204               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1205               0 :         USGSParms[5] = PAK2PCI(RefLat, 1);
    1206               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1207               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1208                 :     } 
    1209                 : 
    1210                 : /* -------------------------------------------------------------------- */
    1211                 : /*  Projection 12: Azimuthal Equidistant        */
    1212                 : /* -------------------------------------------------------------------- */
    1213             168 :     else if( strncmp(geosys_clean.c_str(),"AE   ",5) == 0 )
    1214                 :     {
    1215               0 :         gsys = 12;
    1216               0 :         USGSParms[0] = Dearth0;
    1217                 :         
    1218               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1219               0 :         USGSParms[5] = PAK2PCI(RefLat, 1);
    1220               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1221               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1222                 :     } 
    1223                 : 
    1224                 : /* -------------------------------------------------------------------- */
    1225                 : /*  Projection 13: Gnomonic           */
    1226                 : /* -------------------------------------------------------------------- */
    1227             168 :     else if( strncmp(geosys_clean.c_str(),"GNO  ",5) == 0 )
    1228                 :     {
    1229               0 :         gsys = 13;
    1230               0 :         USGSParms[0] = Dearth0;
    1231                 :         
    1232               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1233               0 :         USGSParms[5] = PAK2PCI(RefLat, 1);
    1234               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1235               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1236                 :     } 
    1237                 : 
    1238                 : /* -------------------------------------------------------------------- */
    1239                 : /*  Projection 14: Orthographic         */ 
    1240                 : /* -------------------------------------------------------------------- */
    1241             168 :     else if( strncmp(geosys_clean.c_str(),"OG   ",5) == 0 )
    1242                 :     {
    1243               0 :         gsys = 14;
    1244               0 :         USGSParms[0] = Dearth0;
    1245                 :         
    1246               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1247               0 :         USGSParms[5] = PAK2PCI(RefLat, 1);
    1248               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1249               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1250                 :     } 
    1251                 : 
    1252                 : /* -------------------------------------------------------------------- */
    1253                 : /*  Projection  15: General Vertical Near-Side Perspective    */
    1254                 : /* -------------------------------------------------------------------- */
    1255             168 :     else if( strncmp(geosys_clean.c_str(),"GVNP ",5) == 0 )
    1256                 :     {
    1257               0 :         gsys = 15;
    1258               0 :         USGSParms[0] = Dearth0;
    1259                 :         
    1260               0 :         USGSParms[2] = Height;
    1261                 :         
    1262               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1263               0 :         USGSParms[5] = PAK2PCI(RefLat, 1);
    1264               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1265               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1266                 :       } 
    1267                 : 
    1268                 : /* -------------------------------------------------------------------- */
    1269                 : /*  Projection 16: Sinusoidal           */
    1270                 : /* -------------------------------------------------------------------- */
    1271             168 :     else if( strncmp(geosys_clean.c_str(),"SIN  ",5) == 0 )
    1272                 :     {
    1273               0 :         gsys = 16;
    1274               0 :         USGSParms[0] = Dearth0;
    1275               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1276               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1277               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1278                 :     } 
    1279                 : 
    1280                 : /* -------------------------------------------------------------------- */
    1281                 : /*  Projection 17: Equirectangular          */
    1282                 : /* -------------------------------------------------------------------- */
    1283             168 :     else if( strncmp(geosys_clean.c_str(),"ER   ",5) == 0 )
    1284                 :     {
    1285               0 :         gsys = 17;
    1286               0 :         USGSParms[0] = Dearth0;
    1287               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1288               0 :         USGSParms[5] = PAK2PCI(RefLat, 1);
    1289               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1290               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1291                 :     } 
    1292                 : /* -------------------------------------------------------------------- */
    1293                 : /*  Projection 18: Miller Cylindrical       */
    1294                 : /* -------------------------------------------------------------------- */
    1295             168 :     else if( strncmp(geosys_clean.c_str(),"MC   ",5) == 0 )
    1296                 :     {
    1297               0 :         gsys = 18;
    1298               0 :         USGSParms[0] = Dearth0;
    1299                 :         
    1300               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1301                 :         
    1302               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1303               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1304                 :     } 
    1305                 : 
    1306                 : /* -------------------------------------------------------------------- */
    1307                 : /*  Projection 19: Van der Grinten          */
    1308                 : /* -------------------------------------------------------------------- */
    1309             168 :     else if( strncmp(geosys_clean.c_str(),"VDG  ",5) == 0 )
    1310                 :     {
    1311               0 :         gsys = 19;
    1312               0 :         USGSParms[0] = Dearth0;
    1313                 :         
    1314               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1315                 :         
    1316               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1317               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1318                 :     } 
    1319                 : 
    1320                 : /* -------------------------------------------------------------------- */
    1321                 : /*  Projection 20:  Oblique Mercator (Hotine)     */
    1322                 : /*    Format A, Azimuth and RefLong defined (Long1, Lat1,       */
    1323                 : /*       Long2, Lat2 not defined), usgs_params[12] = 0        */
    1324                 : /*    Format B, Long1, Lat1, Long2, Lat2 defined (Azimuth   */
    1325                 : /*       and RefLong not defined), usgs_params[12] = not 0        */
    1326                 : /* -------------------------------------------------------------------- */
    1327             168 :     else if( strncmp(geosys_clean.c_str(),"OM   ",5) == 0 )
    1328                 :     {
    1329               0 :         gsys = 20;
    1330               0 :         USGSParms[0] = Dearth0;
    1331               0 :         USGSParms[1] = Dearth1;
    1332               0 :         USGSParms[2] = Scale;
    1333               0 :         USGSParms[3] = PAK2PCI(Azimuth ,1);
    1334                 :         
    1335               0 :         USGSParms[4] = PAK2PCI(RefLong, 1);
    1336               0 :         USGSParms[5] = PAK2PCI(RefLat, 1);
    1337               0 :         USGSParms[6] = FalseEasting * IOmultiply;
    1338               0 :         USGSParms[7] = FalseNorthing * IOmultiply;
    1339                 :         
    1340               0 :         USGSParms[8] = PAK2PCI(Long1, 1);
    1341               0 :         USGSParms[9] = PAK2PCI(Lat1, 1);
    1342               0 :         USGSParms[10] = PAK2PCI(Long2, 1);
    1343               0 :         USGSParms[11] = PAK2PCI(Lat2, 1);
    1344               0 :         if ( (Long1 != 0) || (Lat1 != 0) ||
    1345                 :              (Long2 != 0) || (Lat2 != 0)    )
    1346               0 :             USGSParms[12] = 0.0;
    1347                 :         else
    1348               0 :             USGSParms[12] = 1.0;
    1349                 :     } 
    1350                 : /* -------------------------------------------------------------------- */
    1351                 : /*  Projection 21: Robinson           */
    1352                 : /* -------------------------------------------------------------------- */
    1353             168 :     else if( strncmp(geosys_clean.c_str(),"ROB  ",5) == 0 )
    1354                 :     {
    1355               0 :           gsys = 21;
    1356               0 :           USGSParms[0] = Dearth0;
    1357                 : 
    1358               0 :           USGSParms[4] = PAK2PCI(RefLong, 1);
    1359                 :           USGSParms[6] = FalseEasting
    1360               0 :               * IOmultiply;
    1361                 :           USGSParms[7] = FalseNorthing
    1362               0 :               * IOmultiply;
    1363                 : 
    1364                 :       } 
    1365                 : /* -------------------------------------------------------------------- */
    1366                 : /*  Projection 22: Space Oblique Mercator       */
    1367                 : /* -------------------------------------------------------------------- */
    1368             168 :     else if( strncmp(geosys_clean.c_str(),"SOM  ",5) == 0 )
    1369                 :     {
    1370               0 :           gsys = 22;
    1371               0 :           USGSParms[0] = Dearth0;
    1372               0 :           USGSParms[1] = Dearth1;
    1373               0 :           USGSParms[2] = LandsatNum;
    1374               0 :           USGSParms[3] = LandsatPath;
    1375                 :           USGSParms[6] = FalseEasting
    1376               0 :               * IOmultiply;
    1377                 :           USGSParms[7] = FalseNorthing
    1378               0 :               * IOmultiply;
    1379                 :     } 
    1380                 : /* -------------------------------------------------------------------- */
    1381                 : /*  Projection 23: Modified Stereographic Conformal (Alaska)  */ 
    1382                 : /* -------------------------------------------------------------------- */
    1383             168 :     else if( strncmp(geosys_clean.c_str(),"MSC  ",5) == 0 )
    1384                 :     {
    1385               0 :           gsys = 23;
    1386               0 :           USGSParms[0] = Dearth0;
    1387               0 :           USGSParms[1] = Dearth1;
    1388                 :           USGSParms[6] = FalseEasting
    1389               0 :               * IOmultiply;
    1390                 :           USGSParms[7] = FalseNorthing
    1391               0 :               * IOmultiply;
    1392                 :     } 
    1393                 : 
    1394                 : /* -------------------------------------------------------------------- */
    1395                 : /*  Projection 6: Universal Polar Stereographic is just Polar */
    1396                 : /*  Stereographic with certain assumptions.       */
    1397                 : /* -------------------------------------------------------------------- */
    1398             168 :     else if( strncmp(geosys_clean.c_str(),"UPS  ",5) == 0 )
    1399                 :     {
    1400               0 :           gsys = 6;
    1401                 : 
    1402               0 :           USGSParms[0] = Dearth0;
    1403               0 :           USGSParms[1] = Dearth1;
    1404                 : 
    1405               0 :           USGSParms[4] = PAK2PCI(0.0, 1);
    1406                 : 
    1407               0 :           USGSParms[6] = 2000000.0;
    1408               0 :           USGSParms[7] = 2000000.0;
    1409                 : 
    1410               0 :           double dwork = 81.0 + 6.0/60.0 + 52.3/3600.0;
    1411                 : 
    1412               0 :           if( geosys_clean[10] == 'A' || geosys_clean[10] == 'B' )
    1413                 :           {
    1414               0 :               USGSParms[5] = PAK2PCI(-dwork,1);
    1415                 :           }
    1416               0 :           else if( geosys_clean[10] == 'Y' || geosys_clean[10]=='Z')
    1417                 :           {
    1418               0 :               USGSParms[5] = PAK2PCI(dwork,1);
    1419                 :           }
    1420                 :           else
    1421                 :           {
    1422               0 :               USGSParms[4] = PAK2PCI(RefLong, 1);
    1423               0 :               USGSParms[5] = PAK2PCI(RefLat, 1);
    1424                 :               USGSParms[6] = FalseEasting
    1425               0 :                   * IOmultiply;
    1426                 :               USGSParms[7] = FalseNorthing
    1427               0 :                   * IOmultiply;
    1428                 :           }
    1429                 :       } 
    1430                 : 
    1431                 : /* -------------------------------------------------------------------- */
    1432                 : /*  Unknown code.             */
    1433                 : /* -------------------------------------------------------------------- */
    1434                 :     else
    1435                 :     {
    1436             168 :         gsys = -1;
    1437                 :     }
    1438                 : 
    1439             170 :     if( ProjectionZone == 0 )
    1440             168 :         ProjectionZone = 10000 + gsys;
    1441                 : 
    1442                 : /* -------------------------------------------------------------------- */
    1443                 : /*      Place USGS values in the formatted segment.                     */
    1444                 : /* -------------------------------------------------------------------- */
    1445             170 :     seg_data.Put( (double) gsys,           1458   , 26, "%26.18lE" );
    1446             170 :     seg_data.Put( (double) ProjectionZone, 1458+26, 26, "%26.18lE" );
    1447                 : 
    1448            2720 :     for( i = 0; i < 15; i++ )
    1449            2550 :         seg_data.Put( USGSParms[i], 1458+26*(2+i), 26, "%26.18lE" );
    1450                 : 
    1451             170 :     seg_data.Put( (double) UnitsCode, 1458+26*17, 26, "%26.18lE" );
    1452             170 :     seg_data.Put( (double) Spheroid,  1458+26*18, 26, "%26.18lE" );
    1453             170 : }
    1454                 : 
    1455                 : 

Generated by: LTP GCOV extension version 1.5