LCOV - code coverage report
Current view: directory - frmts/gtiff/libgeotiff - geotiff_proj4.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 254 0 0.0 %
Date: 2010-01-09 Functions: 8 0 0.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: geotiff_proj4.c 1670 2009-10-09 16:29:38Z hobu $
       3                 :  *
       4                 :  * Project:  libgeotiff
       5                 :  * Purpose:  Code to convert a normalized GeoTIFF definition into a PROJ.4
       6                 :  *           (OGDI) compatible projection string.
       7                 :  * Author:   Frank Warmerdam, warmerda@home.com
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 1999, Frank Warmerdam
      11                 :  *
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ******************************************************************************
      30                 :  */
      31                 : 
      32                 : #include "cpl_serv.h"
      33                 : #include "geotiff.h"
      34                 : #include "geo_normalize.h"
      35                 : #include "geovalues.h"
      36                 : 
      37                 : /************************************************************************/
      38                 : /*                          OSRProj4Tokenize()                          */
      39                 : /*                                                                      */
      40                 : /*      Custom tokenizing function for PROJ.4 strings.  The main        */
      41                 : /*      reason we can't just use CSLTokenizeString is to handle         */
      42                 : /*      strings with a + sign in the exponents of parameter values.     */
      43                 : /************************************************************************/
      44                 : 
      45               0 : static char **OSRProj4Tokenize( const char *pszFull )
      46                 : 
      47                 : {
      48               0 :     char *pszStart = NULL;
      49                 :     char *pszFullWrk;
      50                 :     char **papszTokens;
      51                 :     int  i;
      52               0 :     int  nTokens = 0;
      53                 :     static const int nMaxTokens = 200;
      54                 : 
      55               0 :     if( pszFull == NULL )
      56               0 :         return NULL;
      57                 : 
      58               0 :     papszTokens = (char **) calloc(sizeof(char*),nMaxTokens);
      59                 : 
      60               0 :     pszFullWrk = strdup( pszFull );
      61                 : 
      62               0 :     for( i=0; pszFullWrk[i] != '\0' && nTokens != nMaxTokens-1; i++ )
      63                 :     {
      64               0 :         switch( pszFullWrk[i] )
      65                 :         {
      66                 :           case '+':
      67               0 :             if( i == 0 || pszFullWrk[i-1] == '\0' )
      68                 :             {
      69               0 :                 if( pszStart != NULL )
      70                 :                 {
      71               0 :                     if( strstr(pszStart,"=") != NULL )
      72                 :                     {
      73               0 :                         papszTokens[nTokens++] = strdup(pszStart);
      74                 :                     }
      75                 :                     else
      76                 :                     {
      77                 :                         char szAsBoolean[100];
      78               0 :                         strncpy( szAsBoolean,pszStart, sizeof(szAsBoolean)-1-4);
      79               0 :                         szAsBoolean[sizeof(szAsBoolean)-1-4] = '\0';
      80               0 :                         strcat( szAsBoolean,"=yes" );
      81               0 :                         papszTokens[nTokens++] = strdup(szAsBoolean);
      82                 :                     }
      83                 :                 }
      84               0 :                 pszStart = pszFullWrk + i + 1;
      85                 :             }
      86               0 :             break;
      87                 : 
      88                 :           case ' ':
      89                 :           case '\t':
      90                 :           case '\n':
      91               0 :             pszFullWrk[i] = '\0';
      92                 :             break;
      93                 : 
      94                 :           default:
      95                 :             break;
      96                 :         }
      97                 :     }
      98                 : 
      99               0 :     if( pszStart != NULL && strlen(pszStart) > 0 )
     100                 :     {
     101               0 :         if (nTokens != 199)
     102               0 :             papszTokens[nTokens++] = strdup( pszStart );
     103                 :     }
     104                 : 
     105               0 :     free( pszFullWrk );
     106                 : 
     107               0 :     return papszTokens;
     108                 : }
     109                 : 
     110                 : 
     111                 : /************************************************************************/
     112                 : /*                              OSR_GSV()                               */
     113                 : /************************************************************************/
     114                 : 
     115               0 : static const char *OSR_GSV( char **papszNV, const char * pszField )
     116                 : 
     117                 : {
     118               0 :     int field_len = strlen(pszField);
     119                 :     int i;
     120                 :     
     121               0 :     if( !papszNV )
     122               0 :         return NULL;
     123                 : 
     124               0 :     for( i = 0; papszNV[i] != NULL; i++ )
     125                 :     {
     126               0 :         if( EQUALN(papszNV[i],pszField,field_len) )
     127                 :         {
     128               0 :             if( papszNV[i][field_len] == '=' )
     129               0 :                 return papszNV[i] + field_len + 1;
     130                 : 
     131               0 :             if( strlen(papszNV[i]) == field_len )
     132               0 :                 return "";
     133                 :         }
     134                 :     }
     135                 : 
     136               0 :     return NULL;
     137                 : }
     138                 : 
     139                 : /************************************************************************/
     140                 : /*                              OSR_GDV()                               */
     141                 : /*                                                                      */
     142                 : /*      Fetch a particular parameter out of the parameter list, or      */
     143                 : /*      the indicated default if it isn't available.  This is a         */
     144                 : /*      helper function for importFromProj4().                          */
     145                 : /************************************************************************/
     146                 : 
     147               0 : static double OSR_GDV( char **papszNV, const char * pszField, 
     148                 :                        double dfDefaultValue )
     149                 : 
     150                 : {
     151               0 :     const char *pszValue = OSR_GSV( papszNV, pszField );
     152                 : 
     153                 :     /* special hack to use k_0 if available. */
     154               0 :     if( pszValue == NULL && EQUAL(pszField,"k") )
     155               0 :         return OSR_GDV( papszNV, "k_0", dfDefaultValue );
     156                 : 
     157               0 :     if( pszValue == NULL )
     158               0 :         return dfDefaultValue;
     159                 :     else
     160               0 :         return atof(pszValue);
     161                 : }
     162                 : 
     163                 : /************************************************************************/
     164                 : /*                         OSRFreeStringList()                          */
     165                 : /************************************************************************/
     166                 : 
     167               0 : static void OSRFreeStringList( char ** list )
     168                 : 
     169                 : {
     170                 :     int i;
     171                 : 
     172               0 :     for( i = 0; list != NULL && list[i] != NULL; i++ )
     173               0 :         free( list[i] );
     174               0 :     free(list);
     175               0 : }
     176                 : 
     177                 : 
     178                 : /************************************************************************/
     179                 : /*                          GTIFSetFromProj4()                          */
     180                 : /************************************************************************/
     181                 : 
     182               0 : int GTIFSetFromProj4( GTIF *gtif, const char *proj4 )
     183                 : 
     184                 : {
     185               0 :     char **papszNV = OSRProj4Tokenize( proj4 );
     186               0 :     short nSpheroid = KvUserDefined;
     187               0 :     double dfSemiMajor=0.0, dfSemiMinor=0.0, dfInvFlattening=0.0;
     188               0 :     int    nDatum = KvUserDefined;
     189               0 :     int    nGCS = KvUserDefined;    
     190                 :     const char  *value;
     191                 : 
     192                 : /* -------------------------------------------------------------------- */
     193                 : /*      Get the ellipsoid definition.                                   */
     194                 : /* -------------------------------------------------------------------- */
     195               0 :     value = OSR_GSV( papszNV, "ellps" );
     196                 : 
     197               0 :     if( value == NULL )
     198                 :     {
     199                 :         /* nothing */;
     200                 :     }
     201               0 :     else if( EQUAL(value,"WGS84") )
     202               0 :         nSpheroid = Ellipse_WGS_84;
     203               0 :     else if( EQUAL(value,"clrk66") )
     204               0 :         nSpheroid = Ellipse_Clarke_1866;
     205               0 :     else if( EQUAL(value,"clrk80") )
     206               0 :         nSpheroid = Ellipse_Clarke_1880;
     207               0 :     else if( EQUAL(value,"GRS80") )
     208               0 :         nSpheroid = Ellipse_GRS_1980;
     209                 : 
     210               0 :     if( nSpheroid == KvUserDefined )
     211                 :     {
     212               0 :         dfSemiMajor = OSR_GDV(papszNV,"a",0.0);
     213               0 :         dfSemiMinor = OSR_GDV(papszNV,"b",0.0);
     214               0 :         dfInvFlattening = OSR_GDV(papszNV,"rf",0.0);
     215               0 :         if( dfSemiMinor != 0.0 && dfInvFlattening == 0.0 )
     216               0 :             dfInvFlattening = -1.0 / (dfSemiMinor/dfSemiMajor - 1.0);
     217                 :     }
     218                 :     
     219                 : /* -------------------------------------------------------------------- */
     220                 : /*      Get the GCS/Datum code.                                         */
     221                 : /* -------------------------------------------------------------------- */
     222               0 :     value = OSR_GSV( papszNV, "datum" );
     223                 : 
     224               0 :     if( value == NULL ) 
     225                 :     {
     226                 :     }
     227               0 :     else if( EQUAL(value,"WGS84") )
     228                 :     {
     229               0 :         nGCS = GCS_WGS_84;
     230               0 :         nDatum = Datum_WGS84;
     231                 :     }
     232               0 :     else if( EQUAL(value,"NAD83") )
     233                 :     {
     234               0 :         nGCS = GCS_NAD83;
     235               0 :         nDatum = Datum_North_American_Datum_1983;
     236                 :     }
     237               0 :     else if( EQUAL(value,"NAD27") )
     238                 :     {
     239               0 :         nGCS = GCS_NAD27;
     240               0 :         nDatum = Datum_North_American_Datum_1927;
     241                 :     }
     242                 : 
     243                 : /* -------------------------------------------------------------------- */
     244                 : /*      Operate on the basis of the projection name.                    */
     245                 : /* -------------------------------------------------------------------- */
     246               0 :     value = OSR_GSV(papszNV,"proj");
     247                 : 
     248               0 :     if( value == NULL )
     249                 :     {
     250               0 :         OSRFreeStringList( papszNV );
     251               0 :         return FALSE;
     252                 :     }
     253                 : 
     254               0 :     else if( EQUAL(value,"longlat") || EQUAL(value,"latlong") )
     255                 :     {
     256                 :     }
     257                 :     
     258               0 :     else if( EQUAL(value,"tmerc") )
     259                 :     {
     260               0 :   GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1,
     261                 :                    ModelTypeProjected);
     262               0 :   GTIFKeySet(gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
     263                 :                    KvUserDefined );
     264               0 :   GTIFKeySet(gtif, ProjectionGeoKey, TYPE_SHORT, 1,
     265                 :                    KvUserDefined );
     266                 : 
     267               0 :   GTIFKeySet(gtif, ProjCoordTransGeoKey, TYPE_SHORT, 1, 
     268                 :        CT_TransverseMercator );
     269                 : 
     270               0 :         GTIFKeySet(gtif, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1,
     271                 :                    OSR_GDV( papszNV, "lat_0", 0.0 ) );
     272                 : 
     273               0 :         GTIFKeySet(gtif, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1,
     274                 :                    OSR_GDV( papszNV, "lon_0", 0.0 ) );
     275                 :         
     276               0 :         GTIFKeySet(gtif, ProjScaleAtNatOriginGeoKey, TYPE_DOUBLE, 1,
     277                 :                    OSR_GDV( papszNV, "k", 1.0 ) );
     278                 :         
     279               0 :         GTIFKeySet(gtif, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
     280                 :                    OSR_GDV( papszNV, "x_0", 0.0 ) );
     281                 :         
     282               0 :         GTIFKeySet(gtif, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
     283                 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     284                 :     }
     285                 : 
     286               0 :     else if( EQUAL(value,"utm") )
     287                 :     {
     288               0 :         int nZone = (int) OSR_GDV(papszNV,"zone",0);
     289               0 :         const char *south = OSR_GSV(papszNV,"south");
     290                 :                          
     291               0 :   GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1,
     292                 :                    ModelTypeProjected);
     293               0 :   GTIFKeySet(gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
     294                 :                    KvUserDefined );
     295               0 :   GTIFKeySet(gtif, ProjectionGeoKey, TYPE_SHORT, 1,
     296                 :                    KvUserDefined );
     297                 : 
     298               0 :   GTIFKeySet(gtif, ProjCoordTransGeoKey, TYPE_SHORT, 1, 
     299                 :        CT_TransverseMercator );
     300                 : 
     301               0 :         GTIFKeySet(gtif, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1, 
     302                 :                    0.0 );
     303                 : 
     304               0 :         GTIFKeySet(gtif, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1,
     305               0 :                    nZone * 6 - 183.0 );
     306                 :         
     307               0 :         GTIFKeySet(gtif, ProjScaleAtNatOriginGeoKey, TYPE_DOUBLE, 1,
     308                 :                    0.9996 );
     309                 :         
     310               0 :         GTIFKeySet(gtif, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
     311                 :                    500000.0 );
     312                 : 
     313               0 :         if( south != NULL )
     314               0 :             GTIFKeySet(gtif, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
     315                 :                        10000000.0 );
     316                 :         else
     317               0 :             GTIFKeySet(gtif, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
     318                 :                        0.0 );
     319                 :     }
     320                 : 
     321               0 :     else if( EQUAL(value,"lcc") 
     322                 :              && OSR_GDV(papszNV, "lat_0", 0.0 ) 
     323               0 :              == OSR_GDV(papszNV, "lat_1", 0.0 ) )
     324                 :     {
     325               0 :   GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1,
     326                 :                    ModelTypeProjected);
     327               0 :   GTIFKeySet(gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
     328                 :                    KvUserDefined );
     329               0 :   GTIFKeySet(gtif, ProjectionGeoKey, TYPE_SHORT, 1,
     330                 :                    KvUserDefined );
     331                 : 
     332               0 :   GTIFKeySet(gtif, ProjCoordTransGeoKey, TYPE_SHORT, 1, 
     333                 :        CT_LambertConfConic_1SP );
     334                 : 
     335               0 :         GTIFKeySet(gtif, ProjNatOriginLatGeoKey, TYPE_DOUBLE, 1,
     336                 :                    OSR_GDV( papszNV, "lat_0", 0.0 ) );
     337                 : 
     338               0 :         GTIFKeySet(gtif, ProjNatOriginLongGeoKey, TYPE_DOUBLE, 1,
     339                 :                    OSR_GDV( papszNV, "lon_0", 0.0 ) );
     340                 :         
     341               0 :         GTIFKeySet(gtif, ProjScaleAtNatOriginGeoKey, TYPE_DOUBLE, 1,
     342                 :                    OSR_GDV( papszNV, "k", 1.0 ) );
     343                 :         
     344               0 :         GTIFKeySet(gtif, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1,
     345                 :                    OSR_GDV( papszNV, "x_0", 0.0 ) );
     346                 :         
     347               0 :         GTIFKeySet(gtif, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1,
     348                 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     349                 :     }
     350                 : 
     351               0 :     else if( EQUAL(value,"lcc") )
     352                 :     {
     353               0 :   GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1,
     354                 :                    ModelTypeProjected);
     355               0 :   GTIFKeySet(gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1,
     356                 :                    KvUserDefined );
     357               0 :   GTIFKeySet(gtif, ProjectionGeoKey, TYPE_SHORT, 1,
     358                 :                    KvUserDefined );
     359                 : 
     360               0 :   GTIFKeySet(gtif, ProjCoordTransGeoKey, TYPE_SHORT, 1, 
     361                 :        CT_LambertConfConic_2SP );
     362                 : 
     363               0 :         GTIFKeySet(gtif, ProjFalseOriginLatGeoKey, TYPE_DOUBLE, 1,
     364                 :                    OSR_GDV( papszNV, "lat_0", 0.0 ) );
     365                 : 
     366               0 :         GTIFKeySet(gtif, ProjFalseOriginLongGeoKey, TYPE_DOUBLE, 1,
     367                 :                    OSR_GDV( papszNV, "lon_0", 0.0 ) );
     368                 :         
     369               0 :         GTIFKeySet(gtif, ProjStdParallel1GeoKey, TYPE_DOUBLE, 1,
     370                 :                    OSR_GDV( papszNV, "lat_1", 0.0 ) );
     371                 :         
     372               0 :         GTIFKeySet(gtif, ProjStdParallel2GeoKey, TYPE_DOUBLE, 1,
     373                 :                    OSR_GDV( papszNV, "lat_2", 0.0 ) );
     374                 :         
     375               0 :         GTIFKeySet(gtif, ProjFalseOriginEastingGeoKey, TYPE_DOUBLE, 1,
     376                 :                    OSR_GDV( papszNV, "x_0", 0.0 ) );
     377                 :         
     378               0 :         GTIFKeySet(gtif, ProjFalseOriginNorthingGeoKey, TYPE_DOUBLE, 1,
     379                 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     380                 :     }
     381                 : 
     382                 : #ifdef notdef
     383                 :     else if( EQUAL(value,"bonne") )
     384                 :     {
     385                 :         SetBonne( OSR_GDV( papszNV, "lat_1", 0.0 ), 
     386                 :                   OSR_GDV( papszNV, "lon_0", 0.0 ), 
     387                 :                   OSR_GDV( papszNV, "x_0", 0.0 ), 
     388                 :                   OSR_GDV( papszNV, "y_0", 0.0 ) );
     389                 :     }
     390                 : 
     391                 :     else if( EQUAL(value,"cass") )
     392                 :     {
     393                 :         SetCS( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     394                 :                OSR_GDV( papszNV, "lon_0", 0.0 ), 
     395                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     396                 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     397                 :     }
     398                 : 
     399                 :     else if( EQUAL(value,"nzmg") )
     400                 :     {
     401                 :         SetNZMG( OSR_GDV( papszNV, "lat_0", -41.0 ), 
     402                 :                  OSR_GDV( papszNV, "lon_0", 173.0 ), 
     403                 :                  OSR_GDV( papszNV, "x_0", 2510000.0 ), 
     404                 :                  OSR_GDV( papszNV, "y_0", 6023150.0 ) );
     405                 :     }
     406                 : 
     407                 :     else if( EQUAL(value,"cea") )
     408                 :     {
     409                 :         SetCEA( OSR_GDV( papszNV, "lat_ts", 0.0 ), 
     410                 :                 OSR_GDV( papszNV, "lon_0", 0.0 ), 
     411                 :                 OSR_GDV( papszNV, "x_0", 0.0 ), 
     412                 :                 OSR_GDV( papszNV, "y_0", 0.0 ) );
     413                 :     }
     414                 : 
     415                 :     else if( EQUAL(value,"merc") /* 2SP form */
     416                 :              && OSR_GDV(papszNV, "lat_ts", 1000.0) < 999.0 )
     417                 :     {
     418                 :         SetMercator2SP( OSR_GDV( papszNV, "lat_ts", 0.0 ), 
     419                 :                         0.0,
     420                 :                         OSR_GDV( papszNV, "lon_0", 0.0 ), 
     421                 :                         OSR_GDV( papszNV, "x_0", 0.0 ), 
     422                 :                         OSR_GDV( papszNV, "y_0", 0.0 ) );
     423                 :     }
     424                 : 
     425                 :     else if( EQUAL(value,"merc") ) /* 1SP form */
     426                 :     {
     427                 :         SetMercator( 0.0,
     428                 :                      OSR_GDV( papszNV, "lon_0", 0.0 ), 
     429                 :                      OSR_GDV( papszNV, "k", 1.0 ), 
     430                 :                      OSR_GDV( papszNV, "x_0", 0.0 ), 
     431                 :                      OSR_GDV( papszNV, "y_0", 0.0 ) );
     432                 :     }
     433                 : 
     434                 :     else if( EQUAL(value,"stere") 
     435                 :              && ABS(OSR_GDV( papszNV, "lat_0", 0.0 ) - 90) < 0.001 )
     436                 :     {
     437                 :         SetPS( OSR_GDV( papszNV, "lat_ts", 90.0 ), 
     438                 :                OSR_GDV( papszNV, "lon_0", 0.0 ), 
     439                 :                OSR_GDV( papszNV, "k", 1.0 ), 
     440                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     441                 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     442                 :     }
     443                 : 
     444                 :     else if( EQUAL(value,"stere") 
     445                 :              && ABS(OSR_GDV( papszNV, "lat_0", 0.0 ) + 90) < 0.001 )
     446                 :     {
     447                 :         SetPS( OSR_GDV( papszNV, "lat_ts", -90.0 ), 
     448                 :                OSR_GDV( papszNV, "lon_0", 0.0 ), 
     449                 :                OSR_GDV( papszNV, "k", 1.0 ), 
     450                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     451                 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     452                 :     }
     453                 : 
     454                 :     else if( EQUALN(value,"stere",5) /* mostly sterea */
     455                 :              && CSLFetchNameValue(papszNV,"k") != NULL )
     456                 :     {
     457                 :         SetOS( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     458                 :                OSR_GDV( papszNV, "lon_0", 0.0 ), 
     459                 :                OSR_GDV( papszNV, "k", 1.0 ), 
     460                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     461                 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     462                 :     }
     463                 : 
     464                 :     else if( EQUAL(value,"stere") )
     465                 :     {
     466                 :         SetStereographic( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     467                 :                           OSR_GDV( papszNV, "lon_0", 0.0 ), 
     468                 :                           1.0, 
     469                 :                           OSR_GDV( papszNV, "x_0", 0.0 ), 
     470                 :                           OSR_GDV( papszNV, "y_0", 0.0 ) );
     471                 :     }
     472                 : 
     473                 :     else if( EQUAL(value,"eqc") )
     474                 :     {
     475                 :         if( OSR_GDV( papszNV, "lat_0", 0.0 ) != OSR_GDV( papszNV, "lat_ts", 0.0 ) )
     476                 :           SetEquirectangular2( OSR_GDV( papszNV, "lat_0", 0.0 ),
     477                 :                                OSR_GDV( papszNV, "lon_0", 0.0 )+dfFromGreenwich,
     478                 :                                OSR_GDV( papszNV, "lat_ts", 0.0 ),
     479                 :                                OSR_GDV( papszNV, "x_0", 0.0 ),
     480                 :                                OSR_GDV( papszNV, "y_0", 0.0 ) );
     481                 :         else
     482                 :           SetEquirectangular( OSR_GDV( papszNV, "lat_ts", 0.0 ),
     483                 :                               OSR_GDV( papszNV, "lon_0", 0.0 )+dfFromGreenwich,
     484                 :                               OSR_GDV( papszNV, "x_0", 0.0 ),
     485                 :                               OSR_GDV( papszNV, "y_0", 0.0 ) );
     486                 :     }
     487                 : 
     488                 :    else if( EQUAL(value,"glabsgm") )
     489                 :    {
     490                 :        SetGaussLabordeReunion( OSR_GDV( papszNV, "lat_0", -21.116666667 ),
     491                 :                                OSR_GDV( papszNV, "lon_0", 55.53333333309)+dfFromGreenwich,
     492                 :                                OSR_GDV( papszNV, "k_0", 1.0 ),
     493                 :                                OSR_GDV( papszNV, "x_0", 160000.000 ),
     494                 :                                OSR_GDV( papszNV, "y_0", 50000.000 ) );
     495                 :    }
     496                 : 
     497                 :     else if( EQUAL(value,"gnom") )
     498                 :     {
     499                 :         SetGnomonic( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     500                 :                      OSR_GDV( papszNV, "lon_0", 0.0 ), 
     501                 :                      OSR_GDV( papszNV, "x_0", 0.0 ), 
     502                 :                      OSR_GDV( papszNV, "y_0", 0.0 ) );
     503                 :     }
     504                 : 
     505                 :     else if( EQUAL(value,"ortho") )
     506                 :     {
     507                 :         SetOrthographic( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     508                 :                          OSR_GDV( papszNV, "lon_0", 0.0 ), 
     509                 :                          OSR_GDV( papszNV, "x_0", 0.0 ), 
     510                 :                          OSR_GDV( papszNV, "y_0", 0.0 ) );
     511                 :     }
     512                 : 
     513                 :     else if( EQUAL(value,"laea") )
     514                 :     {
     515                 :         SetLAEA( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     516                 :                  OSR_GDV( papszNV, "lon_0", 0.0 ), 
     517                 :                  OSR_GDV( papszNV, "x_0", 0.0 ), 
     518                 :                  OSR_GDV( papszNV, "y_0", 0.0 ) );
     519                 :     }
     520                 : 
     521                 :     else if( EQUAL(value,"aeqd") )
     522                 :     {
     523                 :         SetAE( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     524                 :                OSR_GDV( papszNV, "lon_0", 0.0 ), 
     525                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     526                 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     527                 :     }
     528                 : 
     529                 :     else if( EQUAL(value,"eqdc") )
     530                 :     {
     531                 :         SetEC( OSR_GDV( papszNV, "lat_1", 0.0 ), 
     532                 :                OSR_GDV( papszNV, "lat_2", 0.0 ), 
     533                 :                OSR_GDV( papszNV, "lat_0", 0.0 ), 
     534                 :                OSR_GDV( papszNV, "lon_0", 0.0 ), 
     535                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     536                 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     537                 :     }
     538                 : 
     539                 :     else if( EQUAL(value,"mill") )
     540                 :     {
     541                 :         SetMC( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     542                 :                OSR_GDV( papszNV, "lon_0", 0.0 ), 
     543                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     544                 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     545                 :     }
     546                 : 
     547                 :     else if( EQUAL(value,"moll") )
     548                 :     {
     549                 :         SetMollweide( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     550                 :                       OSR_GDV( papszNV, "x_0", 0.0 ), 
     551                 :                       OSR_GDV( papszNV, "y_0", 0.0 ) );
     552                 :     }
     553                 : 
     554                 :     else if( EQUAL(value,"eck4") )
     555                 :     {
     556                 :         SetEckertIV( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     557                 :                      OSR_GDV( papszNV, "x_0", 0.0 ), 
     558                 :                      OSR_GDV( papszNV, "y_0", 0.0 ) );
     559                 :     }
     560                 : 
     561                 :     else if( EQUAL(value,"eck6") )
     562                 :     {
     563                 :         SetEckertVI( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     564                 :                      OSR_GDV( papszNV, "x_0", 0.0 ), 
     565                 :                      OSR_GDV( papszNV, "y_0", 0.0 ) );
     566                 :     }
     567                 : 
     568                 :     else if( EQUAL(value,"poly") )
     569                 :     {
     570                 :         SetPolyconic( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     571                 :                       OSR_GDV( papszNV, "lon_0", 0.0 ), 
     572                 :                       OSR_GDV( papszNV, "x_0", 0.0 ), 
     573                 :                       OSR_GDV( papszNV, "y_0", 0.0 ) );
     574                 :     }
     575                 : 
     576                 :     else if( EQUAL(value,"aea") )
     577                 :     {
     578                 :         SetACEA( OSR_GDV( papszNV, "lat_1", 0.0 ), 
     579                 :                  OSR_GDV( papszNV, "lat_2", 0.0 ), 
     580                 :                  OSR_GDV( papszNV, "lat_0", 0.0 ), 
     581                 :                  OSR_GDV( papszNV, "lon_0", 0.0 ), 
     582                 :                  OSR_GDV( papszNV, "x_0", 0.0 ), 
     583                 :                  OSR_GDV( papszNV, "y_0", 0.0 ) );
     584                 :     }
     585                 : 
     586                 :     else if( EQUAL(value,"robin") )
     587                 :     {
     588                 :         SetRobinson( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     589                 :                      OSR_GDV( papszNV, "x_0", 0.0 ), 
     590                 :                      OSR_GDV( papszNV, "y_0", 0.0 ) );
     591                 :     }
     592                 : 
     593                 :     else if( EQUAL(value,"vandg") )
     594                 :     {
     595                 :         SetVDG( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     596                 :                 OSR_GDV( papszNV, "x_0", 0.0 ), 
     597                 :                 OSR_GDV( papszNV, "y_0", 0.0 ) );
     598                 :     }
     599                 : 
     600                 :     else if( EQUAL(value,"sinu") )
     601                 :     {
     602                 :         SetSinusoidal( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     603                 :                        OSR_GDV( papszNV, "x_0", 0.0 ), 
     604                 :                        OSR_GDV( papszNV, "y_0", 0.0 ) );
     605                 :     }
     606                 : 
     607                 :     else if( EQUAL(value,"gall") )
     608                 :     {
     609                 :         SetGS( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     610                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     611                 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     612                 :     }
     613                 : 
     614                 :     else if( EQUAL(value,"goode") )
     615                 :     {
     616                 :         SetGH( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     617                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     618                 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     619                 :     }
     620                 : 
     621                 :     else if( EQUAL(value,"geos") )
     622                 :     {
     623                 :         SetGEOS( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     624                 :                  OSR_GDV( papszNV, "h", 35785831.0 ), 
     625                 :                  OSR_GDV( papszNV, "x_0", 0.0 ), 
     626                 :                  OSR_GDV( papszNV, "y_0", 0.0 ) );
     627                 :     }
     628                 : 
     629                 :     else if( EQUAL(value,"lcc") ) 
     630                 :     {
     631                 :         if( OSR_GDV(papszNV, "lat_0", 0.0 ) 
     632                 :             == OSR_GDV(papszNV, "lat_1", 0.0 ) )
     633                 :         {
     634                 :             /* 1SP form */
     635                 :             SetLCC1SP( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     636                 :                        OSR_GDV( papszNV, "lon_0", 0.0 ), 
     637                 :                        OSR_GDV( papszNV, "k_0", 1.0 ), 
     638                 :                        OSR_GDV( papszNV, "x_0", 0.0 ), 
     639                 :                        OSR_GDV( papszNV, "y_0", 0.0 ) );
     640                 :         }
     641                 :         else
     642                 :         {
     643                 :             /* 2SP form */
     644                 :             SetLCC( OSR_GDV( papszNV, "lat_1", 0.0 ), 
     645                 :                     OSR_GDV( papszNV, "lat_2", 0.0 ), 
     646                 :                     OSR_GDV( papszNV, "lat_0", 0.0 ), 
     647                 :                     OSR_GDV( papszNV, "lon_0", 0.0 ), 
     648                 :                     OSR_GDV( papszNV, "x_0", 0.0 ), 
     649                 :                     OSR_GDV( papszNV, "y_0", 0.0 ) );
     650                 :         }
     651                 :     }
     652                 : 
     653                 :     else if( EQUAL(value,"omerc") )
     654                 :     {
     655                 :         SetHOM( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     656                 :                 OSR_GDV( papszNV, "lonc", 0.0 ), 
     657                 :                 OSR_GDV( papszNV, "alpha", 0.0 ), 
     658                 :                 0.0, /* ??? */
     659                 :                 OSR_GDV( papszNV, "k", 1.0 ), 
     660                 :                 OSR_GDV( papszNV, "x_0", 0.0 ), 
     661                 :                 OSR_GDV( papszNV, "y_0", 0.0 ) );
     662                 :     }
     663                 : 
     664                 :     else if( EQUAL(value,"somerc") )
     665                 :     {
     666                 :         SetHOM( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     667                 :                 OSR_GDV( papszNV, "lon_0", 0.0 ), 
     668                 :                 90.0,  90.0, 
     669                 :                 OSR_GDV( papszNV, "k", 1.0 ), 
     670                 :                 OSR_GDV( papszNV, "x_0", 0.0 ), 
     671                 :                 OSR_GDV( papszNV, "y_0", 0.0 ) );
     672                 :     }
     673                 : 
     674                 :     else if( EQUAL(value,"krovak") )
     675                 :     {
     676                 :         SetKrovak( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     677                 :                    OSR_GDV( papszNV, "lon_0", 0.0 ), 
     678                 :                    OSR_GDV( papszNV, "alpha", 0.0 ), 
     679                 :                    0.0, /* pseudo_standard_parallel_1 */
     680                 :                    OSR_GDV( papszNV, "k", 1.0 ), 
     681                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     682                 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     683                 :     }
     684                 : 
     685                 :     else if( EQUAL(value, "iwm_p") )
     686                 :     {
     687                 :         SetIWMPolyconic( OSR_GDV( papszNV, "lat_1", 0.0 ), 
     688                 :                          OSR_GDV( papszNV, "lat_2", 0.0 ),
     689                 :                          OSR_GDV( papszNV, "lon_0", 0.0 ), 
     690                 :                          OSR_GDV( papszNV, "x_0", 0.0 ), 
     691                 :                          OSR_GDV( papszNV, "y_0", 0.0 ) );
     692                 :     }
     693                 : 
     694                 :     else if( EQUAL(value, "wag1") )
     695                 :     {
     696                 :         SetWagner( 1, 0.0,
     697                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     698                 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     699                 :     }
     700                 : 
     701                 :     else if( EQUAL(value, "wag2") )
     702                 :     {
     703                 :         SetWagner( 2, 0.0,
     704                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     705                 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     706                 :     }
     707                 : 
     708                 :     else if( EQUAL(value, "wag3") )
     709                 :     {
     710                 :         SetWagner( 3,
     711                 :                    OSR_GDV( papszNV, "lat_ts", 0.0 ),
     712                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     713                 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     714                 :     }
     715                 : 
     716                 :     else if( EQUAL(value, "wag1") )
     717                 :     {
     718                 :         SetWagner( 4, 0.0,
     719                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     720                 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     721                 :     }
     722                 : 
     723                 :     else if( EQUAL(value, "wag1") )
     724                 :     {
     725                 :         SetWagner( 5, 0.0,
     726                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     727                 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     728                 :     }
     729                 : 
     730                 :     else if( EQUAL(value, "wag1") )
     731                 :     {
     732                 :         SetWagner( 6, 0.0,
     733                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     734                 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     735                 :     }
     736                 : 
     737                 :     else if( EQUAL(value, "wag1") )
     738                 :     {
     739                 :         SetWagner( 7, 0.0,
     740                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     741                 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     742                 :     }
     743                 : 
     744                 :     else if( EQUAL(value,"tpeqd") )
     745                 :     {
     746                 :         SetTPED( OSR_GDV( papszNV, "lat_1", 0.0 ), 
     747                 :                  OSR_GDV( papszNV, "lon_1", 0.0 ), 
     748                 :                  OSR_GDV( papszNV, "lat_2", 0.0 ), 
     749                 :                  OSR_GDV( papszNV, "lon_2", 0.0 ), 
     750                 :                  OSR_GDV( papszNV, "x_0", 0.0 ), 
     751                 :                  OSR_GDV( papszNV, "y_0", 0.0 ) );
     752                 :     }
     753                 : #endif
     754                 :     else
     755                 :     {
     756                 :         /* unsupported coordinate system */
     757               0 :         OSRFreeStringList( papszNV );
     758               0 :         return FALSE;
     759                 :     }
     760                 : 
     761                 : /* -------------------------------------------------------------------- */
     762                 : /*      Write the GCS if we have it, otherwise write the datum.         */
     763                 : /* -------------------------------------------------------------------- */
     764               0 :     if( nGCS != KvUserDefined )
     765                 :     {
     766               0 :         GTIFKeySet( gtif, GeographicTypeGeoKey, TYPE_SHORT,
     767                 :                     1, nGCS );
     768                 :     }
     769                 :     else
     770                 :     {
     771               0 :         GTIFKeySet( gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, 
     772                 :                     KvUserDefined );
     773               0 :         GTIFKeySet( gtif, GeogGeodeticDatumGeoKey, TYPE_SHORT,
     774                 :                     1, nDatum );
     775                 :     }
     776                 : 
     777                 : /* -------------------------------------------------------------------- */
     778                 : /*      Write the ellipsoid if we don't know the GCS.                   */
     779                 : /* -------------------------------------------------------------------- */
     780               0 :     if( nGCS == KvUserDefined )
     781                 :     {
     782               0 :         if( nSpheroid != KvUserDefined )
     783               0 :             GTIFKeySet( gtif, GeogEllipsoidGeoKey, TYPE_SHORT, 1, 
     784                 :                         nSpheroid );
     785                 :         else
     786                 :         {
     787               0 :             GTIFKeySet( gtif, GeogEllipsoidGeoKey, TYPE_SHORT, 1, 
     788                 :                         KvUserDefined );
     789               0 :             GTIFKeySet( gtif, GeogSemiMajorAxisGeoKey, TYPE_DOUBLE, 1,
     790                 :                         dfSemiMajor );
     791               0 :             if( dfInvFlattening == 0.0 )
     792               0 :                 GTIFKeySet( gtif, GeogSemiMinorAxisGeoKey, TYPE_DOUBLE, 1,
     793                 :                             dfSemiMajor );
     794                 :             else
     795               0 :                 GTIFKeySet( gtif, GeogInvFlatteningGeoKey, TYPE_DOUBLE, 1,
     796                 :                             dfInvFlattening );
     797                 :         }
     798                 :         
     799                 :     }
     800                 : 
     801                 : /* -------------------------------------------------------------------- */
     802                 : /*      Linear units translation                                        */
     803                 : /* -------------------------------------------------------------------- */
     804               0 :     value = OSR_GSV( papszNV, "units" );
     805                 : 
     806               0 :     if( value == NULL )
     807                 :     {
     808               0 :         value = OSR_GSV( papszNV, "to_meter" );
     809               0 :         if( value )
     810                 :         {
     811               0 :             GTIFKeySet( gtif, ProjLinearUnitsGeoKey, TYPE_SHORT, 1, 
     812                 :                         KvUserDefined );
     813               0 :             GTIFKeySet( gtif, ProjLinearUnitSizeGeoKey, TYPE_DOUBLE, 1, 
     814                 :                         atof(value) );
     815                 :         }
     816                 :     }
     817               0 :     else if( EQUAL(value,"meter") || EQUAL(value,"m") )
     818                 :     {
     819               0 :         GTIFKeySet( gtif, ProjLinearUnitsGeoKey, TYPE_SHORT, 1, 
     820                 :                     Linear_Meter );
     821                 :     } 
     822               0 :     else if( EQUAL(value,"us-ft") )
     823                 :     {
     824               0 :         GTIFKeySet( gtif, ProjLinearUnitsGeoKey, TYPE_SHORT, 1, 
     825                 :                     Linear_Foot_US_Survey );
     826                 :     } 
     827               0 :     else if( EQUAL(value,"ft") )
     828                 :     {
     829               0 :         GTIFKeySet( gtif, ProjLinearUnitsGeoKey, TYPE_SHORT, 1, 
     830                 :                     Linear_Foot );
     831                 :     } 
     832                 : 
     833                 : 
     834               0 :     OSRFreeStringList( papszNV );
     835                 :     
     836               0 :     return TRUE;
     837                 : }
     838                 : 
     839                 : /************************************************************************/
     840                 : /*                          GTIFGetProj4Defn()                          */
     841                 : /************************************************************************/
     842                 : 
     843               0 : char * GTIFGetProj4Defn( GTIFDefn * psDefn )
     844                 : 
     845                 : {
     846                 :     char  szProjection[512];
     847                 :     char  szUnits[64];
     848                 :     double      dfFalseEasting, dfFalseNorthing;
     849                 : 
     850               0 :     if( psDefn == NULL /* || !psDefn->DefnSet */ )
     851               0 :         return strdup("");
     852                 : 
     853               0 :     szProjection[0] = '\0';
     854                 :     
     855                 : /* ==================================================================== */
     856                 : /*      Translate the units of measure.                                 */
     857                 : /*                                                                      */
     858                 : /*      Note that even with a +units, or +to_meter in effect, it is     */
     859                 : /*      still assumed that all the projection parameters are in         */
     860                 : /*      meters.                                                         */
     861                 : /* ==================================================================== */
     862               0 :     if( psDefn->UOMLength == Linear_Meter )
     863                 :     {
     864               0 :         strcpy( szUnits, "+units=m " ); 
     865                 :     }
     866               0 :     else if( psDefn->UOMLength == Linear_Foot )
     867                 :     {
     868               0 :         strcpy( szUnits, "+units=ft " );
     869                 :     }
     870               0 :     else if( psDefn->UOMLength == Linear_Foot_US_Survey )
     871                 :     {
     872               0 :         strcpy( szUnits, "+units=us-ft " );
     873                 :     }
     874               0 :     else if( psDefn->UOMLength == Linear_Foot_Indian )
     875                 :     {
     876               0 :         strcpy( szUnits, "+units=ind-ft " );
     877                 :     }
     878               0 :     else if( psDefn->UOMLength == Linear_Link )
     879                 :     {
     880               0 :         strcpy( szUnits, "+units=link " );
     881                 :     }
     882               0 :     else if( psDefn->UOMLength == Linear_Yard_Indian)
     883                 :     {
     884               0 :         strcpy( szUnits, "+units=ind-yd " );
     885                 :     }
     886               0 :     else if( psDefn->UOMLength == Linear_Fathom )
     887                 :     {
     888               0 :         strcpy( szUnits, "+units=fath " );
     889                 :     }
     890               0 :     else if( psDefn->UOMLength == Linear_Mile_International_Nautical )
     891                 :     {
     892               0 :         strcpy( szUnits, "+units=kmi " );
     893                 :     }
     894                 :     else
     895                 :     {
     896               0 :         sprintf( szUnits, "+to_meter=%.10f", psDefn->UOMLengthInMeters );
     897                 :     }
     898                 : 
     899                 : /* -------------------------------------------------------------------- */
     900                 : /*      false easting and northing are in meters and that is what       */
     901                 : /*      PROJ.4 wants regardless of the linear units.                    */
     902                 : /* -------------------------------------------------------------------- */
     903               0 :     dfFalseEasting = psDefn->ProjParm[5];
     904               0 :     dfFalseNorthing = psDefn->ProjParm[6];
     905                 :     
     906                 : /* ==================================================================== */
     907                 : /*      Handle general projection methods.                              */
     908                 : /* ==================================================================== */
     909                 :  
     910                 : /* -------------------------------------------------------------------- */
     911                 : /*      Geographic.                                                     */
     912                 : /* -------------------------------------------------------------------- */
     913               0 :     if(psDefn->Model==ModelTypeGeographic)
     914                 :     {
     915               0 :         sprintf(szProjection+strlen(szProjection),"+proj=latlong ");
     916                 :         
     917                 :     }
     918                 :  
     919                 : /* -------------------------------------------------------------------- */
     920                 : /*      UTM - special case override on transverse mercator so things    */
     921                 : /*      will be more meaningful to the user.                            */
     922                 : /* -------------------------------------------------------------------- */
     923               0 :     else if( psDefn->MapSys == MapSys_UTM_North )
     924                 :     {
     925               0 :         sprintf( szProjection+strlen(szProjection),
     926                 :                  "+proj=utm +zone=%d ",
     927                 :                  psDefn->Zone );
     928                 :     }
     929                 :     
     930                 : /* -------------------------------------------------------------------- */
     931                 : /*      Transverse Mercator                                             */
     932                 : /* -------------------------------------------------------------------- */
     933               0 :     else if( psDefn->CTProjection == CT_TransverseMercator )
     934                 :     {
     935               0 :         sprintf( szProjection+strlen(szProjection),
     936                 :            "+proj=tmerc +lat_0=%.9f +lon_0=%.9f +k=%f +x_0=%.3f +y_0=%.3f ",
     937                 :                  psDefn->ProjParm[0],
     938                 :                  psDefn->ProjParm[1],
     939                 :                  psDefn->ProjParm[4],
     940                 :                  dfFalseEasting,
     941                 :                  dfFalseNorthing );
     942                 :     }
     943                 : 
     944                 : /* -------------------------------------------------------------------- */
     945                 : /*      Mercator              */
     946                 : /* -------------------------------------------------------------------- */
     947               0 :     else if( psDefn->CTProjection == CT_Mercator )
     948                 :     {
     949               0 :         sprintf( szProjection+strlen(szProjection),
     950                 :            "+proj=merc +lat_ts=%.9f +lon_0=%.9f +k=%f +x_0=%.3f +y_0=%.3f ",
     951                 :                  psDefn->ProjParm[0],
     952                 :                  psDefn->ProjParm[1],
     953                 :                  psDefn->ProjParm[4],
     954                 :                  dfFalseEasting,
     955                 :                  dfFalseNorthing );
     956                 :     }
     957                 : 
     958                 : /* -------------------------------------------------------------------- */
     959                 : /*      Cassini/Soldner                                                 */
     960                 : /* -------------------------------------------------------------------- */
     961               0 :     else if( psDefn->CTProjection == CT_CassiniSoldner )
     962                 :     {
     963               0 :         sprintf( szProjection+strlen(szProjection),
     964                 :                  "+proj=cass +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f ",
     965                 :                  psDefn->ProjParm[0],
     966                 :                  psDefn->ProjParm[1],
     967                 :                  dfFalseEasting,
     968                 :                  dfFalseNorthing );
     969                 :     }
     970                 : 
     971                 : /* -------------------------------------------------------------------- */
     972                 : /*      Oblique Stereographic - Should this really map onto             */
     973                 : /*      Stereographic?                                                  */
     974                 : /* -------------------------------------------------------------------- */
     975               0 :     else if( psDefn->CTProjection == CT_ObliqueStereographic )
     976                 :     {
     977               0 :         sprintf( szProjection+strlen(szProjection),
     978                 :            "+proj=stere +lat_0=%.9f +lon_0=%.9f +k=%f +x_0=%.3f +y_0=%.3f ",
     979                 :                  psDefn->ProjParm[0],
     980                 :                  psDefn->ProjParm[1],
     981                 :                  psDefn->ProjParm[4],
     982                 :                  dfFalseEasting,
     983                 :                  dfFalseNorthing );
     984                 :     }
     985                 : 
     986                 : /* -------------------------------------------------------------------- */
     987                 : /*      Stereographic                                                   */
     988                 : /* -------------------------------------------------------------------- */
     989               0 :     else if( psDefn->CTProjection == CT_Stereographic )
     990                 :     {
     991               0 :         sprintf( szProjection+strlen(szProjection),
     992                 :            "+proj=stere +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f ",
     993                 :                  psDefn->ProjParm[0],
     994                 :                  psDefn->ProjParm[1],
     995                 :                  dfFalseEasting,
     996                 :                  dfFalseNorthing );
     997                 :     }
     998                 : 
     999                 : /* -------------------------------------------------------------------- */
    1000                 : /*      Polar Stereographic                                             */
    1001                 : /* -------------------------------------------------------------------- */
    1002               0 :     else if( psDefn->CTProjection == CT_PolarStereographic )
    1003                 :     {
    1004               0 :         if( psDefn->ProjParm[0] > 0.0 )
    1005               0 :             sprintf( szProjection+strlen(szProjection),
    1006                 :                      "+proj=stere +lat_0=90 +lat_ts=%.9f +lon_0=%.9f "
    1007                 :                      "+k=%.9f +x_0=%.3f +y_0=%.3f ",
    1008                 :                      psDefn->ProjParm[0],
    1009                 :                      psDefn->ProjParm[1],
    1010                 :                      psDefn->ProjParm[4],
    1011                 :                      dfFalseEasting,
    1012                 :                      dfFalseNorthing );
    1013                 :         else
    1014               0 :             sprintf( szProjection+strlen(szProjection),
    1015                 :                      "+proj=stere +lat_0=-90 +lat_ts=%.9f +lon_0=%.9f "
    1016                 :                      "+k=%.9f +x_0=%.3f +y_0=%.3f ",
    1017                 :                      psDefn->ProjParm[0],
    1018                 :                      psDefn->ProjParm[1],
    1019                 :                      psDefn->ProjParm[4],
    1020                 :                      dfFalseEasting,
    1021                 :                      dfFalseNorthing );
    1022                 :     }
    1023                 : 
    1024                 : /* -------------------------------------------------------------------- */
    1025                 : /*      Equirectangular                                                 */
    1026                 : /* -------------------------------------------------------------------- */
    1027               0 :     else if( psDefn->CTProjection == CT_Equirectangular )
    1028                 :     {
    1029               0 :         sprintf( szProjection+strlen(szProjection),
    1030                 :                  "+proj=eqc +lat_0=%.9f +lon_0=%.9f +lat_ts=%.9f +x_0=%.3f +y_0=%.3f ",
    1031                 :                  psDefn->ProjParm[0],
    1032                 :                  psDefn->ProjParm[1],
    1033                 :                  psDefn->ProjParm[2],
    1034                 :                  dfFalseEasting,
    1035                 :                  dfFalseNorthing );
    1036                 :     }
    1037                 : 
    1038                 : /* -------------------------------------------------------------------- */
    1039                 : /*      Gnomonic                                                        */
    1040                 : /* -------------------------------------------------------------------- */
    1041               0 :     else if( psDefn->CTProjection == CT_Gnomonic )
    1042                 :     {
    1043               0 :         sprintf( szProjection+strlen(szProjection),
    1044                 :                  "+proj=gnom +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f ",
    1045                 :                  psDefn->ProjParm[0],
    1046                 :                  psDefn->ProjParm[1],
    1047                 :                  dfFalseEasting,
    1048                 :                  dfFalseNorthing );
    1049                 :     }
    1050                 : 
    1051                 : /* -------------------------------------------------------------------- */
    1052                 : /*      Orthographic                                                    */
    1053                 : /* -------------------------------------------------------------------- */
    1054               0 :     else if( psDefn->CTProjection == CT_Orthographic )
    1055                 :     {
    1056               0 :         sprintf( szProjection+strlen(szProjection),
    1057                 :                  "+proj=ortho +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f ",
    1058                 :                  psDefn->ProjParm[0],
    1059                 :                  psDefn->ProjParm[1],
    1060                 :                  dfFalseEasting,
    1061                 :                  dfFalseNorthing );
    1062                 :     }
    1063                 : 
    1064                 : /* -------------------------------------------------------------------- */
    1065                 : /*      Lambert Azimuthal Equal Area                                    */
    1066                 : /* -------------------------------------------------------------------- */
    1067               0 :     else if( psDefn->CTProjection == CT_LambertAzimEqualArea )
    1068                 :     {
    1069               0 :         sprintf( szProjection+strlen(szProjection),
    1070                 :                  "+proj=laea +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f ",
    1071                 :                  psDefn->ProjParm[0],
    1072                 :                  psDefn->ProjParm[1],
    1073                 :                  dfFalseEasting,
    1074                 :                  dfFalseNorthing );
    1075                 :     }
    1076                 : 
    1077                 : /* -------------------------------------------------------------------- */
    1078                 : /*      Azimuthal Equidistant                                           */
    1079                 : /* -------------------------------------------------------------------- */
    1080               0 :     else if( psDefn->CTProjection == CT_AzimuthalEquidistant )
    1081                 :     {
    1082               0 :         sprintf( szProjection+strlen(szProjection),
    1083                 :            "+proj=aeqd +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f ",
    1084                 :                  psDefn->ProjParm[0],
    1085                 :                  psDefn->ProjParm[1],
    1086                 :                  dfFalseEasting,
    1087                 :                  dfFalseNorthing );
    1088                 :     }
    1089                 : 
    1090                 : /* -------------------------------------------------------------------- */
    1091                 : /*      Miller Cylindrical                                              */
    1092                 : /* -------------------------------------------------------------------- */
    1093               0 :     else if( psDefn->CTProjection == CT_MillerCylindrical )
    1094                 :     {
    1095               0 :         sprintf( szProjection+strlen(szProjection),
    1096                 :            "+proj=mill +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f +R_A ",
    1097                 :                  psDefn->ProjParm[0],
    1098                 :                  psDefn->ProjParm[1],
    1099                 :                  dfFalseEasting,
    1100                 :                  dfFalseNorthing );
    1101                 :     }
    1102                 : 
    1103                 : /* -------------------------------------------------------------------- */
    1104                 : /*      Polyconic                                                       */
    1105                 : /* -------------------------------------------------------------------- */
    1106               0 :     else if( psDefn->CTProjection == CT_Polyconic )
    1107                 :     {
    1108               0 :         sprintf( szProjection+strlen(szProjection),
    1109                 :            "+proj=poly +lat_0=%.9f +lon_0=%.9f +x_0=%.3f +y_0=%.3f ",
    1110                 :                  psDefn->ProjParm[0],
    1111                 :                  psDefn->ProjParm[1],
    1112                 :                  dfFalseEasting,
    1113                 :                  dfFalseNorthing );
    1114                 :     }
    1115                 : 
    1116                 : /* -------------------------------------------------------------------- */
    1117                 : /*      AlbersEqualArea                                                 */
    1118                 : /* -------------------------------------------------------------------- */
    1119               0 :     else if( psDefn->CTProjection == CT_AlbersEqualArea )
    1120                 :     {
    1121               0 :         sprintf( szProjection+strlen(szProjection),
    1122                 :                  "+proj=aea +lat_1=%.9f +lat_2=%.9f +lat_0=%.9f +lon_0=%.9f"
    1123                 :                  " +x_0=%.3f +y_0=%.3f ",
    1124                 :                  psDefn->ProjParm[0],
    1125                 :                  psDefn->ProjParm[1],
    1126                 :                  psDefn->ProjParm[2],
    1127                 :                  psDefn->ProjParm[3],
    1128                 :                  dfFalseEasting,
    1129                 :                  dfFalseNorthing );
    1130                 :     }
    1131                 :     
    1132                 : /* -------------------------------------------------------------------- */
    1133                 : /*      EquidistantConic                                                */
    1134                 : /* -------------------------------------------------------------------- */
    1135               0 :     else if( psDefn->CTProjection == CT_EquidistantConic )
    1136                 :     {
    1137               0 :         sprintf( szProjection+strlen(szProjection),
    1138                 :                  "+proj=eqdc +lat_1=%.9f +lat_2=%.9f +lat_0=%.9f +lon_0=%.9f"
    1139                 :                  " +x_0=%.3f +y_0=%.3f ",
    1140                 :                  psDefn->ProjParm[0],
    1141                 :                  psDefn->ProjParm[1],
    1142                 :                  psDefn->ProjParm[2],
    1143                 :                  psDefn->ProjParm[3],
    1144                 :                  dfFalseEasting,
    1145                 :                  dfFalseNorthing );
    1146                 :     }
    1147                 :     
    1148                 : /* -------------------------------------------------------------------- */
    1149                 : /*      Robinson                                                        */
    1150                 : /* -------------------------------------------------------------------- */
    1151               0 :     else if( psDefn->CTProjection == CT_Robinson )
    1152                 :     {
    1153               0 :         sprintf( szProjection+strlen(szProjection),
    1154                 :                  "+proj=robin +lon_0=%.9f +x_0=%.3f +y_0=%.3f ",
    1155                 :                  psDefn->ProjParm[1],
    1156                 :                  dfFalseEasting,
    1157                 :                  dfFalseNorthing );
    1158                 :     }
    1159                 :     
    1160                 : /* -------------------------------------------------------------------- */
    1161                 : /*      VanDerGrinten                                                   */
    1162                 : /* -------------------------------------------------------------------- */
    1163               0 :     else if( psDefn->CTProjection == CT_VanDerGrinten )
    1164                 :     {
    1165               0 :         sprintf( szProjection+strlen(szProjection),
    1166                 :                  "+proj=vandg +lon_0=%.9f +x_0=%.3f +y_0=%.3f +R_A ",
    1167                 :                  psDefn->ProjParm[1],
    1168                 :                  dfFalseEasting,
    1169                 :                  dfFalseNorthing );
    1170                 :     }
    1171                 :     
    1172                 : /* -------------------------------------------------------------------- */
    1173                 : /*      Sinusoidal                                                      */
    1174                 : /* -------------------------------------------------------------------- */
    1175               0 :     else if( psDefn->CTProjection == CT_Sinusoidal )
    1176                 :     {
    1177               0 :         sprintf( szProjection+strlen(szProjection),
    1178                 :                  "+proj=sinu +lon_0=%.9f +x_0=%.3f +y_0=%.3f ",
    1179                 :                  psDefn->ProjParm[1],
    1180                 :                  dfFalseEasting,
    1181                 :                  dfFalseNorthing );
    1182                 :     }
    1183                 :     
    1184                 : /* -------------------------------------------------------------------- */
    1185                 : /*      LambertConfConic_2SP                                            */
    1186                 : /* -------------------------------------------------------------------- */
    1187               0 :     else if( psDefn->CTProjection == CT_LambertConfConic_2SP )
    1188                 :     {
    1189               0 :         sprintf( szProjection+strlen(szProjection),
    1190                 :                  "+proj=lcc +lat_0=%.9f +lon_0=%.9f +lat_1=%.9f +lat_2=%.9f "
    1191                 :                  " +x_0=%.3f +y_0=%.3f ",
    1192                 :                  psDefn->ProjParm[0],
    1193                 :                  psDefn->ProjParm[1],
    1194                 :                  psDefn->ProjParm[2],
    1195                 :                  psDefn->ProjParm[3],
    1196                 :                  dfFalseEasting,
    1197                 :                  dfFalseNorthing );
    1198                 :     }
    1199                 :     
    1200                 : /* -------------------------------------------------------------------- */
    1201                 : /*      LambertConfConic_1SP                                            */
    1202                 : /* -------------------------------------------------------------------- */
    1203               0 :     else if( psDefn->CTProjection == CT_LambertConfConic_1SP )
    1204                 :     {
    1205               0 :         sprintf( szProjection+strlen(szProjection),
    1206                 :                  "+proj=lcc +lat_0=%.9f +lat_1=%.9f +lon_0=%.9f"
    1207                 :                  " +k_0=%.9f +x_0=%.3f +y_0=%.3f ",
    1208                 :                  psDefn->ProjParm[0],
    1209                 :                  psDefn->ProjParm[0],
    1210                 :                  psDefn->ProjParm[1],
    1211                 :                  psDefn->ProjParm[4],
    1212                 :                  psDefn->ProjParm[5],
    1213                 :                  psDefn->ProjParm[6] );
    1214                 :     }
    1215                 :     
    1216                 : /* -------------------------------------------------------------------- */
    1217                 : /*      CT_CylindricalEqualArea                                         */
    1218                 : /* -------------------------------------------------------------------- */
    1219               0 :     else if( psDefn->CTProjection == CT_CylindricalEqualArea )
    1220                 :     {
    1221               0 :         sprintf( szProjection+strlen(szProjection),
    1222                 :                  "+proj=cea +lat_ts=%.9f +lon_0=%.9f "
    1223                 :                  " +x_0=%.3f +y_0=%.3f ",
    1224                 :                  psDefn->ProjParm[0],
    1225                 :                  psDefn->ProjParm[1],
    1226                 :                  psDefn->ProjParm[5],
    1227                 :                  psDefn->ProjParm[6] );
    1228                 :     }
    1229                 :     
    1230                 : /* -------------------------------------------------------------------- */
    1231                 : /*      NewZealandMapGrid                                               */
    1232                 : /* -------------------------------------------------------------------- */
    1233               0 :     else if( psDefn->CTProjection == CT_NewZealandMapGrid )
    1234                 :     {
    1235               0 :         sprintf( szProjection+strlen(szProjection),
    1236                 :                  "+proj=nzmg +lat_0=%.9f +lon_0=%.9f"
    1237                 :                  " +x_0=%.3f +y_0=%.3f ",
    1238                 :                  psDefn->ProjParm[0],
    1239                 :                  psDefn->ProjParm[1],
    1240                 :                  psDefn->ProjParm[5],
    1241                 :                  psDefn->ProjParm[6] );
    1242                 :     }
    1243                 :     
    1244                 : /* -------------------------------------------------------------------- */
    1245                 : /*      Transverse Mercator - south oriented.                           */
    1246                 : /* -------------------------------------------------------------------- */
    1247               0 :     else if( psDefn->CTProjection == CT_TransvMercator_SouthOriented )
    1248                 :     {
    1249                 :         /* this appears to be an unsupported formulation with PROJ.4 */
    1250                 :     }
    1251                 :     
    1252                 : /* -------------------------------------------------------------------- */
    1253                 : /*      ObliqueMercator (Hotine)                                        */
    1254                 : /* -------------------------------------------------------------------- */
    1255               0 :     else if( psDefn->CTProjection == CT_ObliqueMercator )
    1256                 :     {
    1257                 :         /* not clear how ProjParm[3] - angle from rectified to skewed grid -
    1258                 :            should be applied ... see the +not_rot flag for PROJ.4.
    1259                 :            Just ignoring for now. */
    1260                 : 
    1261               0 :         sprintf( szProjection+strlen(szProjection),
    1262                 :                  "+proj=omerc +lat_0=%.9f +lonc=%.9f +alpha=%.9f"
    1263                 :                  " +k=%.9f +x_0=%.3f +y_0=%.3f ",
    1264                 :                  psDefn->ProjParm[0],
    1265                 :                  psDefn->ProjParm[1],
    1266                 :                  psDefn->ProjParm[2],
    1267                 :                  psDefn->ProjParm[4],
    1268                 :                  psDefn->ProjParm[5],
    1269                 :                  psDefn->ProjParm[6] );
    1270                 :     }
    1271                 : 
    1272                 : /* ==================================================================== */
    1273                 : /*      Handle ellipsoid information.                                   */
    1274                 : /* ==================================================================== */
    1275               0 :     if( psDefn->Ellipsoid == Ellipse_WGS_84 )
    1276               0 :         strcat( szProjection, "+ellps=WGS84 " );
    1277               0 :     else if( psDefn->Ellipsoid == Ellipse_Clarke_1866 )
    1278               0 :         strcat( szProjection, "+ellps=clrk66 " );
    1279               0 :     else if( psDefn->Ellipsoid == Ellipse_Clarke_1880 )
    1280               0 :         strcat( szProjection, "+ellps=clrk80 " );
    1281               0 :     else if( psDefn->Ellipsoid == Ellipse_GRS_1980 )
    1282               0 :         strcat( szProjection, "+ellps=GRS80 " );
    1283                 :     else
    1284                 :     {
    1285               0 :         if( psDefn->SemiMajor != 0.0 && psDefn->SemiMinor != 0.0 )
    1286                 :         {
    1287               0 :             sprintf( szProjection+strlen(szProjection),
    1288                 :                      "+a=%.3f +b=%.3f ",
    1289                 :                      psDefn->SemiMajor,
    1290                 :                      psDefn->SemiMinor );
    1291                 :         }
    1292                 :     }
    1293                 : 
    1294               0 :     strcat( szProjection, szUnits );
    1295                 :     
    1296                 :     /* If we don't have anything, reset */
    1297               0 :     if (strstr(szProjection,"+proj=") == NULL) { return strdup(""); }
    1298                 : 
    1299               0 :     return( strdup( szProjection ) );
    1300                 : }
    1301                 : 
    1302                 : #if !defined(HAVE_LIBPROJ) || !defined(HAVE_PROJECTS_H)
    1303                 : 
    1304               0 : int GTIFProj4ToLatLong( GTIFDefn * psDefn, int nPoints,
    1305                 :                         double *padfX, double *padfY )
    1306                 : {
    1307                 :     (void) psDefn;
    1308                 :     (void) nPoints;
    1309                 :     (void) padfX;
    1310                 :     (void) padfY;
    1311                 : #ifdef DEBUG    
    1312                 :     fprintf( stderr,
    1313                 :              "GTIFProj4ToLatLong() - PROJ.4 support not compiled in.\n" );
    1314                 : #endif    
    1315               0 :     return FALSE;
    1316                 : }
    1317                 : 
    1318               0 : int GTIFProj4FromLatLong( GTIFDefn * psDefn, int nPoints,
    1319                 :                           double *padfX, double *padfY )
    1320                 : {
    1321                 :     (void) psDefn;
    1322                 :     (void) nPoints;
    1323                 :     (void) padfX;
    1324                 :     (void) padfY;
    1325                 : #ifdef DEBUG    
    1326                 :     fprintf( stderr,
    1327                 :              "GTIFProj4FromLatLong() - PROJ.4 support not compiled in.\n" );
    1328                 : #endif    
    1329               0 :     return FALSE;
    1330                 : }
    1331                 : #else
    1332                 : 
    1333                 : #include "projects.h"
    1334                 : 
    1335                 : #ifdef USE_PROJUV
    1336                 : #  define UV projUV
    1337                 : #endif
    1338                 : 
    1339                 : /************************************************************************/
    1340                 : /*                        GTIFProj4FromLatLong()                        */
    1341                 : /*                                                                      */
    1342                 : /*      Convert lat/long values to projected coordinate for a           */
    1343                 : /*      particular definition.                                          */
    1344                 : /************************************************************************/
    1345                 : 
    1346                 : int GTIFProj4FromLatLong( GTIFDefn * psDefn, int nPoints,
    1347                 :                           double *padfX, double *padfY )
    1348                 : 
    1349                 : {
    1350                 :     char  *pszProjection, **papszArgs;
    1351                 :     PJ    *psPJ;
    1352                 :     int   i;
    1353                 :     
    1354                 : /* -------------------------------------------------------------------- */
    1355                 : /*      Get a projection definition.                                    */
    1356                 : /* -------------------------------------------------------------------- */
    1357                 :     pszProjection = GTIFGetProj4Defn( psDefn );
    1358                 : 
    1359                 :     if( pszProjection == NULL )
    1360                 :         return FALSE;
    1361                 : 
    1362                 : /* -------------------------------------------------------------------- */
    1363                 : /*      Parse into tokens for pj_init(), and initialize the projection. */
    1364                 : /* -------------------------------------------------------------------- */
    1365                 :     
    1366                 :     papszArgs = CSLTokenizeStringComplex( pszProjection, " +", TRUE, FALSE );
    1367                 :     free( pszProjection );
    1368                 : 
    1369                 :     psPJ = pj_init( CSLCount(papszArgs), papszArgs );
    1370                 : 
    1371                 :     CSLDestroy( papszArgs );
    1372                 : 
    1373                 :     if( psPJ == NULL )
    1374                 :     {
    1375                 :         return FALSE;
    1376                 :     }
    1377                 : 
    1378                 : /* -------------------------------------------------------------------- */
    1379                 : /*      Process each of the points.                                     */
    1380                 : /* -------------------------------------------------------------------- */
    1381                 :     for( i = 0; i < nPoints; i++ )
    1382                 :     {
    1383                 :         UV  sUV;
    1384                 : 
    1385                 :         sUV.u = padfX[i] * DEG_TO_RAD;
    1386                 :         sUV.v = padfY[i] * DEG_TO_RAD;
    1387                 : 
    1388                 :         sUV = pj_fwd( sUV, psPJ );
    1389                 : 
    1390                 :         padfX[i] = sUV.u;
    1391                 :         padfY[i] = sUV.v;
    1392                 :     }
    1393                 : 
    1394                 :     pj_free( psPJ );
    1395                 : 
    1396                 :     return TRUE;
    1397                 : }
    1398                 : 
    1399                 : /************************************************************************/
    1400                 : /*                         GTIFProj4ToLatLong()                         */
    1401                 : /*                                                                      */
    1402                 : /*      Convert projection coordinates to lat/long for a particular     */
    1403                 : /*      definition.                                                     */
    1404                 : /************************************************************************/
    1405                 : 
    1406                 : int GTIFProj4ToLatLong( GTIFDefn * psDefn, int nPoints,
    1407                 :                         double *padfX, double *padfY )
    1408                 : 
    1409                 : {
    1410                 :     char  *pszProjection, **papszArgs;
    1411                 :     PJ    *psPJ;
    1412                 :     int   i;
    1413                 :     
    1414                 : /* -------------------------------------------------------------------- */
    1415                 : /*      Get a projection definition.                                    */
    1416                 : /* -------------------------------------------------------------------- */
    1417                 :     pszProjection = GTIFGetProj4Defn( psDefn );
    1418                 : 
    1419                 :     if( pszProjection == NULL )
    1420                 :         return FALSE;
    1421                 : 
    1422                 : /* -------------------------------------------------------------------- */
    1423                 : /*      Parse into tokens for pj_init(), and initialize the projection. */
    1424                 : /* -------------------------------------------------------------------- */
    1425                 :     
    1426                 :     papszArgs = CSLTokenizeStringComplex( pszProjection, " +", TRUE, FALSE );
    1427                 :     free( pszProjection );
    1428                 : 
    1429                 :     psPJ = pj_init( CSLCount(papszArgs), papszArgs );
    1430                 : 
    1431                 :     CSLDestroy( papszArgs );
    1432                 : 
    1433                 :     if( psPJ == NULL )
    1434                 :     {
    1435                 :         return FALSE;
    1436                 :     }
    1437                 : 
    1438                 : /* -------------------------------------------------------------------- */
    1439                 : /*      Process each of the points.                                     */
    1440                 : /* -------------------------------------------------------------------- */
    1441                 :     for( i = 0; i < nPoints; i++ )
    1442                 :     {
    1443                 :         UV  sUV;
    1444                 : 
    1445                 :         sUV.u = padfX[i];
    1446                 :         sUV.v = padfY[i];
    1447                 : 
    1448                 :         sUV = pj_inv( sUV, psPJ );
    1449                 : 
    1450                 :         padfX[i] = sUV.u * RAD_TO_DEG;
    1451                 :         padfY[i] = sUV.v * RAD_TO_DEG;
    1452                 :     }
    1453                 : 
    1454                 :     pj_free( psPJ );
    1455                 : 
    1456                 :     return TRUE;
    1457                 : }
    1458                 : 
    1459                 : #endif /* has projects.h and -lproj */
    1460                 : 

Generated by: LCOV version 1.7