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

Generated by: LCOV version 1.14