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

Generated by: LCOV version 1.14