LCOV - code coverage report
Current view: top level - frmts/gtiff/libgeotiff - geotiff_proj4.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 0 314 0.0 %
Date: 2024-05-04 12:52:34 Functions: 0 9 0.0 %

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

Generated by: LCOV version 1.14