LCOV - code coverage report
Current view: top level - frmts/pcidsk/sdk/segment - cpcidskgeoref.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 290 617 47.0 %
Date: 2025-07-02 23:05:47 Functions: 13 16 81.2 %

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

Generated by: LCOV version 1.14