LCOV - code coverage report
Current view: directory - ogr - ogr_srs_proj4.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 596 398 66.8 %
Date: 2010-01-09 Functions: 7 7 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogr_srs_proj4.cpp 18034 2009-11-15 20:13:38Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  OGRSpatialReference interface to PROJ.4.
       6                 :  * Author:   Frank Warmerdam <warmerdam@pobox.com>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1999,  Les Technologies SoftMap Inc. 
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "ogr_spatialref.h"
      31                 : #include "ogr_p.h"
      32                 : #include "cpl_conv.h"
      33                 : 
      34                 : extern int EPSGGetWGS84Transform( int nGeogCS, double *padfTransform );
      35                 : 
      36                 : CPL_CVSID("$Id: ogr_srs_proj4.cpp 18034 2009-11-15 20:13:38Z rouault $");
      37                 : 
      38                 : /* -------------------------------------------------------------------- */
      39                 : /*      The following list comes from osrs/proj/src/pj_ellps.c          */
      40                 : /*      ... please update from time to time.                            */
      41                 : /* -------------------------------------------------------------------- */
      42                 : static const char *ogr_pj_ellps[] = {
      43                 : "MERIT",        "a=6378137.0", "rf=298.257", "MERIT 1983",
      44                 : "SGS85",        "a=6378136.0", "rf=298.257",  "Soviet Geodetic System 85",
      45                 : "GRS80",        "a=6378137.0", "rf=298.257222101", "GRS 1980(IUGG, 1980)",
      46                 : "IAU76",        "a=6378140.0", "rf=298.257", "IAU 1976",
      47                 : "airy",         "a=6377563.396", "b=6356256.910", "Airy 1830",
      48                 : "APL4.9",       "a=6378137.0.",  "rf=298.25", "Appl. Physics. 1965",
      49                 : "NWL9D",        "a=6378145.0.",  "rf=298.25", "Naval Weapons Lab., 1965",
      50                 : "mod_airy",     "a=6377340.189", "b=6356034.446", "Modified Airy",
      51                 : "andrae",       "a=6377104.43",  "rf=300.0",    "Andrae 1876 (Den., Iclnd.)",
      52                 : "aust_SA",      "a=6378160.0", "rf=298.25", "Australian Natl & S. Amer. 1969",
      53                 : "GRS67",        "a=6378160.0", "rf=298.2471674270", "GRS 67(IUGG 1967)",
      54                 : "bessel",       "a=6377397.155", "rf=299.1528128", "Bessel 1841",
      55                 : "bess_nam",     "a=6377483.865", "rf=299.1528128", "Bessel 1841 (Namibia)",
      56                 : "clrk66",       "a=6378206.4", "b=6356583.8", "Clarke 1866",
      57                 : "clrk80",       "a=6378249.145", "rf=293.4663", "Clarke 1880 mod.",
      58                 : "CPM",          "a=6375738.7", "rf=334.29", "Comm. des Poids et Mesures 1799",
      59                 : "delmbr",       "a=6376428.",  "rf=311.5", "Delambre 1810 (Belgium)",
      60                 : "engelis",      "a=6378136.05", "rf=298.2566", "Engelis 1985",
      61                 : "evrst30",  "a=6377276.345", "rf=300.8017",  "Everest 1830",
      62                 : "evrst48",  "a=6377304.063", "rf=300.8017",  "Everest 1948",
      63                 : "evrst56",  "a=6377301.243", "rf=300.8017",  "Everest 1956",
      64                 : "evrst69",  "a=6377295.664", "rf=300.8017",  "Everest 1969",
      65                 : "evrstSS",  "a=6377298.556", "rf=300.8017",  "Everest (Sabah & Sarawak)",
      66                 : "fschr60",  "a=6378166.",   "rf=298.3", "Fischer (Mercury Datum) 1960",
      67                 : "fschr60m", "a=6378155.",   "rf=298.3", "Modified Fischer 1960",
      68                 : "fschr68",  "a=6378150.",   "rf=298.3", "Fischer 1968",
      69                 : "helmert",  "a=6378200.",   "rf=298.3", "Helmert 1906",
      70                 : "hough",        "a=6378270.0", "rf=297.", "Hough",
      71                 : "intl",         "a=6378388.0", "rf=297.", "International 1909 (Hayford)",
      72                 : "krass",        "a=6378245.0", "rf=298.3", "Krassovsky, 1942",
      73                 : "kaula",        "a=6378163.",  "rf=298.24", "Kaula 1961",
      74                 : "lerch",        "a=6378139.",  "rf=298.257", "Lerch 1979",
      75                 : "mprts",        "a=6397300.",  "rf=191.", "Maupertius 1738",
      76                 : "new_intl",     "a=6378157.5", "b=6356772.2", "New International 1967",
      77                 : "plessis",      "a=6376523.",  "b=6355863.", "Plessis 1817 (France)",
      78                 : "SEasia",       "a=6378155.0", "b=6356773.3205", "Southeast Asia",
      79                 : "walbeck",      "a=6376896.0", "b=6355834.8467", "Walbeck",
      80                 : "WGS60",    "a=6378165.0",  "rf=298.3", "WGS 60",
      81                 : "WGS66",        "a=6378145.0", "rf=298.25", "WGS 66",
      82                 : "WGS72",        "a=6378135.0", "rf=298.26", "WGS 72",
      83                 : "WGS84",    "a=6378137.0",  "rf=298.257223563", "WGS 84",
      84                 : "sphere",   "a=6370997.0",  "b=6370997.0", "Normal Sphere (r=6370997)",
      85                 : 0, 0, 0, 0,
      86                 : };
      87                 : 
      88                 : typedef struct
      89                 : {
      90                 :     const char* pszPJ;
      91                 :     const char* pszOGR;
      92                 :     int         nEPSG;
      93                 :     int         nGCS;
      94                 : } OGRProj4Datum;
      95                 : 
      96                 : /* Derived from proj/src/pj_datum.c */
      97                 : /* WGS84, NAD27 and NAD83 are directly hard-coded in the code */
      98                 : static const OGRProj4Datum ogr_pj_datums[] = {
      99                 :     { "GGRS87", "Greek_Geodetic_Reference_System_1987", 4121, 6121},
     100                 :     { "potsdam", "Deutsches_Hauptdreiecksnetz", 4314, 6314},
     101                 :     { "carthage", "Carthage", 4223, 6223},
     102                 :     { "hermannskogel", "Militar_Geographische_Institut", 4312, 6312},
     103                 :     { "ire65", "TM65", 4299, 6299},
     104                 :     { "nzgd49", "New_Zealand_Geodetic_Datum_1949", 4272, 6272},
     105                 :     { "OSGB36", "OSGB_1936", 4277, 6277}
     106                 : };
     107                 : 
     108              66 : static const char* OGRGetProj4Datum(const char* pszDatum,
     109                 :                                     int nEPSGDatum)
     110                 : {
     111                 :     unsigned int i;
     112             525 :     for(i=0;i<sizeof(ogr_pj_datums)/sizeof(ogr_pj_datums[0]);i++)
     113                 :     {
     114             462 :         if (nEPSGDatum == ogr_pj_datums[i].nGCS ||
     115                 :             EQUAL(pszDatum, ogr_pj_datums[i].pszOGR))
     116                 :         {
     117               3 :             return ogr_pj_datums[i].pszPJ;
     118                 :         }
     119                 :     }
     120              63 :     return NULL;
     121                 : }
     122                 : 
     123                 : /************************************************************************/
     124                 : /*                          OSRProj4Tokenize()                          */
     125                 : /*                                                                      */
     126                 : /*      Custom tokenizing function for PROJ.4 strings.  The main        */
     127                 : /*      reason we can't just use CSLTokenizeString is to handle         */
     128                 : /*      strings with a + sign in the exponents of parameter values.     */
     129                 : /************************************************************************/
     130                 : 
     131              25 : char **OSRProj4Tokenize( const char *pszFull )
     132                 : 
     133                 : {
     134              25 :     char *pszStart = NULL;
     135                 :     char *pszFullWrk;
     136              25 :     char **papszTokens = NULL;
     137                 :     int  i;
     138                 : 
     139              25 :     if( pszFull == NULL )
     140               0 :         return NULL;
     141                 : 
     142              25 :     pszFullWrk = CPLStrdup( pszFull );
     143                 : 
     144            2038 :     for( i=0; pszFullWrk[i] != '\0'; i++ )
     145                 :     {
     146            2013 :         switch( pszFullWrk[i] )
     147                 :         {
     148                 :           case '+':
     149             152 :             if( i == 0 || pszFullWrk[i-1] == '\0' )
     150                 :             {
     151             151 :                 if( pszStart != NULL )
     152                 :                 {
     153             126 :                     if( strstr(pszStart,"=") != NULL )
     154             124 :                         papszTokens = CSLAddString( papszTokens, pszStart );
     155                 :                     else
     156                 :                     {
     157               2 :                         CPLString osAsBoolean = pszStart;
     158               2 :                         osAsBoolean += "=yes";
     159               2 :                         papszTokens = CSLAddString( papszTokens, osAsBoolean );
     160                 :                     }
     161                 :                 }
     162             151 :                 pszStart = pszFullWrk + i + 1;
     163                 :             }
     164             152 :             break;
     165                 : 
     166                 :           case ' ':
     167                 :           case '\t':
     168                 :           case '\n':
     169             150 :             pszFullWrk[i] = '\0';
     170                 :             break;
     171                 : 
     172                 :           default:
     173                 :             break;
     174                 :         }
     175                 :     }
     176                 : 
     177              25 :     if( pszStart != NULL && strlen(pszStart) > 0 )
     178              25 :         papszTokens = CSLAddString( papszTokens, pszStart );
     179                 : 
     180              25 :     CPLFree( pszFullWrk );
     181                 : 
     182              25 :     return papszTokens;
     183                 : }
     184                 : 
     185                 : 
     186                 : /************************************************************************/
     187                 : /*                         OSRImportFromProj4()                         */
     188                 : /************************************************************************/
     189                 : /** 
     190                 :  * \brief Import PROJ.4 coordinate string.
     191                 :  *
     192                 :  * This function is the same as OGRSpatialReference::importFromProj4().
     193                 :  */
     194               7 : OGRErr OSRImportFromProj4( OGRSpatialReferenceH hSRS, const char *pszProj4 )
     195                 : 
     196                 : {
     197               7 :     VALIDATE_POINTER1( hSRS, "OSRImportFromProj4", CE_Failure );
     198                 : 
     199               7 :     return ((OGRSpatialReference *) hSRS)->importFromProj4( pszProj4 );
     200                 : }
     201                 : 
     202                 : /************************************************************************/
     203                 : /*                              OSR_GDV()                               */
     204                 : /*                                                                      */
     205                 : /*      Fetch a particular parameter out of the parameter list, or      */
     206                 : /*      the indicated default if it isn't available.  This is a         */
     207                 : /*      helper function for importFromProj4().                          */
     208                 : /************************************************************************/
     209                 : 
     210             113 : static double OSR_GDV( char **papszNV, const char * pszField, 
     211                 :                        double dfDefaultValue )
     212                 : 
     213                 : {
     214                 :     const char * pszValue;
     215                 : 
     216             113 :     pszValue = CSLFetchNameValue( papszNV, pszField );
     217                 : 
     218                 :     // special hack to use k_0 if available.
     219             113 :     if( pszValue == NULL && EQUAL(pszField,"k") )
     220               4 :         pszValue = CSLFetchNameValue( papszNV, "k_0" );
     221                 : 
     222             113 :     if( pszValue == NULL )
     223              38 :         return dfDefaultValue;
     224                 :     else
     225              75 :         return CPLDMSToDec(pszValue);
     226                 : }
     227                 : 
     228                 : /************************************************************************/
     229                 : /*                          importFromProj4()                           */
     230                 : /************************************************************************/
     231                 : 
     232                 : /**
     233                 :  * \brief Import PROJ.4 coordinate string.
     234                 :  *
     235                 :  * The OGRSpatialReference is initialized from the passed PROJ.4 style
     236                 :  * coordinate system string.  In addition to many +proj formulations which
     237                 :  * have OGC equivelents, it is also possible to import "+init=epsg:n" style
     238                 :  * definitions.  These are passed to importFromEPSG().  Other init strings
     239                 :  * (such as the state plane zones) are not currently supported.   
     240                 :  *
     241                 :  * Example:
     242                 :  *   pszProj4 = "+proj=utm +zone=11 +datum=WGS84" 
     243                 :  *
     244                 :  * Some parameters, such as grids, recognised by PROJ.4 may not be well
     245                 :  * understood and translated into the OGRSpatialReference model. It is possible
     246                 :  * to add the +wktext parameter which is a special keyword that OGR recognises
     247                 :  * as meaning "embed the entire PROJ.4 string in the WKT and use it literally
     248                 :  * when converting back to PROJ.4 format".
     249                 :  * 
     250                 :  * For example:
     251                 :  * "+proj=nzmg +lat_0=-41 +lon_0=173 +x_0=2510000 +y_0=6023150 +ellps=intl
     252                 :  *  +units=m +nadgrids=nzgd2kgrid0005.gsb +wktext"
     253                 :  *
     254                 :  * will be translated as :
     255                 :  * \code
     256                 :  * PROJCS["unnamed",
     257                 :  *    GEOGCS["International 1909 (Hayford)",
     258                 :  *        DATUM["unknown",
     259                 :  *            SPHEROID["intl",6378388,297]],
     260                 :  *        PRIMEM["Greenwich",0],
     261                 :  *        UNIT["degree",0.0174532925199433]],
     262                 :  *    PROJECTION["New_Zealand_Map_Grid"],
     263                 :  *    PARAMETER["latitude_of_origin",-41],
     264                 :  *    PARAMETER["central_meridian",173],
     265                 :  *    PARAMETER["false_easting",2510000],
     266                 :  *    PARAMETER["false_northing",6023150],
     267                 :  *    UNIT["Meter",1],
     268                 :  *    EXTENSION["PROJ4","+proj=nzmg +lat_0=-41 +lon_0=173 +x_0=2510000 
     269                 :  *               +y_0=6023150 +ellps=intl  +units=m +nadgrids=nzgd2kgrid0005.gsb +wktext"]]
     270                 :  * \endcode
     271                 :  *
     272                 :  * This method is the equivalent of the C function OSRImportFromProj4().
     273                 :  *
     274                 :  * @param pszProj4 the PROJ.4 style string. 
     275                 :  *
     276                 :  * @return OGRERR_NONE on success or OGRERR_CORRUPT_DATA on failure.
     277                 :  */
     278                 : 
     279              25 : OGRErr OGRSpatialReference::importFromProj4( const char * pszProj4 )
     280                 : 
     281                 : {
     282              25 :     char **papszNV = NULL;
     283                 :     char **papszTokens;
     284                 :     int  i;
     285                 :     char *pszCleanCopy;
     286                 : 
     287                 : /* -------------------------------------------------------------------- */
     288                 : /*      Clear any existing definition.                                  */
     289                 : /* -------------------------------------------------------------------- */
     290              25 :     Clear();
     291                 : 
     292                 : /* -------------------------------------------------------------------- */
     293                 : /*      Strip any newlines or other "funny" stuff that might occur      */
     294                 : /*      if this string just came from reading a file.                   */
     295                 : /* -------------------------------------------------------------------- */
     296              25 :     pszCleanCopy = CPLStrdup( pszProj4 );
     297            1769 :     for( i = 0; pszCleanCopy[i] != '\0'; i++ )
     298                 :     {
     299            5232 :         if( pszCleanCopy[i] == 10 
     300            1744 :             || pszCleanCopy[i] == 13 
     301            1744 :             || pszCleanCopy[i] == 9 )
     302               0 :             pszCleanCopy[i] = ' ';
     303                 :     }
     304                 : 
     305                 : /* -------------------------------------------------------------------- */
     306                 : /*      Try to normalize the definition.  This should expand +init=     */
     307                 : /*      clauses and so forth.                                           */
     308                 : /* -------------------------------------------------------------------- */
     309                 :     char *pszNormalized;
     310                 : 
     311              25 :     pszNormalized = OCTProj4Normalize( pszCleanCopy );
     312              25 :     CPLFree( pszCleanCopy );
     313                 :     
     314                 : /* -------------------------------------------------------------------- */
     315                 : /*      If we have an EPSG based init string, and no existing +proj     */
     316                 : /*      portion then try to normalize into into a PROJ.4 string.        */
     317                 : /* -------------------------------------------------------------------- */
     318              25 :     if( strstr(pszNormalized,"init=epsg:") != NULL 
     319                 :         && strstr(pszNormalized,"proj=") == NULL )
     320                 :     {
     321                 :         OGRErr eErr;
     322               0 :         const char *pszNumber = strstr(pszNormalized,"init=epsg:") + 10;
     323                 : 
     324               0 :         eErr = importFromEPSG( atoi(pszNumber) );
     325               0 :         if( eErr == OGRERR_NONE )
     326                 :         {
     327               0 :             CPLFree( pszNormalized );
     328               0 :             return eErr;
     329                 :         }
     330                 :     }
     331                 : 
     332                 : /* -------------------------------------------------------------------- */
     333                 : /*      Parse the PROJ.4 string into a cpl_string.h style name/value    */
     334                 : /*      list.                                                           */
     335                 : /* -------------------------------------------------------------------- */
     336              25 :     papszTokens = OSRProj4Tokenize( pszNormalized );
     337              25 :     CPLFree( pszNormalized );
     338                 :     
     339             176 :     for( i = 0; papszTokens != NULL && papszTokens[i] != NULL; i++ )
     340                 :     {
     341             151 :         char *pszEqual = strstr(papszTokens[i],"=");
     342                 : 
     343             151 :         if( pszEqual == NULL )
     344               6 :             papszNV = CSLAddNameValue(papszNV, papszTokens[i], "" );
     345                 :         else
     346                 :         {
     347             145 :             pszEqual[0] = '\0';
     348             145 :             papszNV = CSLAddNameValue( papszNV, papszTokens[i], pszEqual+1 );
     349                 :         }
     350                 :     }
     351                 : 
     352              25 :     CSLDestroy( papszTokens );
     353                 : 
     354                 : /* -------------------------------------------------------------------- */
     355                 : /*      Extract the prime meridian, if there is one set.                */
     356                 : /* -------------------------------------------------------------------- */
     357              25 :     const char *pszPM = CSLFetchNameValue( papszNV, "pm" );
     358              25 :     double dfFromGreenwich = 0.0;
     359              25 :     int    nPMCode = -1;
     360                 : 
     361              25 :     if( pszPM != NULL )
     362                 :     {
     363               3 :         if( EQUAL(pszPM,"lisbon") )
     364                 :         {
     365               0 :             dfFromGreenwich = CPLDMSToDec( "9d07'54.862\"W" );
     366               0 :             nPMCode = 8902;
     367                 :         }
     368               3 :         else if( EQUAL(pszPM,"paris") )
     369                 :         {
     370               1 :             dfFromGreenwich = CPLDMSToDec( "2d20'14.025\"E" );
     371               1 :             nPMCode = 8903;
     372                 :         }
     373               2 :         else if( EQUAL(pszPM,"bogota") )
     374                 :         {
     375               1 :             dfFromGreenwich = CPLDMSToDec( "74d04'51.3\"W" );
     376               1 :             nPMCode = 8904;
     377                 :         }
     378               1 :         else if( EQUAL(pszPM,"madrid") )
     379                 :         {
     380               0 :             dfFromGreenwich = CPLDMSToDec( "3d41'16.48\"W" );
     381               0 :             nPMCode = 8905;
     382                 :         }
     383               1 :         else if( EQUAL(pszPM,"rome") )
     384                 :         {
     385               0 :             dfFromGreenwich = CPLDMSToDec( "12d27'8.4\"E" );
     386               0 :             nPMCode = 8906;
     387                 :         }
     388               1 :         else if( EQUAL(pszPM,"bern") )
     389                 :         {
     390               0 :             dfFromGreenwich = CPLDMSToDec( "7d26'22.5\"E" );
     391               0 :             nPMCode = 8907;
     392                 :         }
     393               1 :         else if( EQUAL(pszPM,"jakarta") )
     394                 :         {
     395               0 :             dfFromGreenwich = CPLDMSToDec( "106d48'27.79\"E" );
     396               0 :             nPMCode = 8908;
     397                 :         }
     398               1 :         else if( EQUAL(pszPM,"ferro") )
     399                 :         {
     400               0 :             dfFromGreenwich = CPLDMSToDec( "17d40'W" );
     401               0 :             nPMCode = 8909;
     402                 :         }
     403               1 :         else if( EQUAL(pszPM,"brussels") )
     404                 :         {
     405               0 :             dfFromGreenwich = CPLDMSToDec( "4d22'4.71\"E" );
     406               0 :             nPMCode = 8910;
     407                 :         }
     408               1 :         else if( EQUAL(pszPM,"stockholm") )
     409                 :         {
     410               0 :             dfFromGreenwich = CPLDMSToDec( "18d3'29.8\"E" );
     411               0 :             nPMCode = 8911;
     412                 :         }
     413               1 :         else if( EQUAL(pszPM,"athens") )
     414                 :         {
     415               0 :             dfFromGreenwich = CPLDMSToDec( "23d42'58.815\"E" );
     416               0 :             nPMCode = 8912;
     417                 :         }
     418               1 :         else if( EQUAL(pszPM,"oslo") )
     419                 :         {
     420               0 :             dfFromGreenwich = CPLDMSToDec( "10d43'22.5\"E" );
     421               0 :             nPMCode = 8913;
     422                 :         }
     423                 :         else
     424                 :         {
     425               1 :             dfFromGreenwich = CPLDMSToDec( pszPM );
     426               1 :             pszPM = "unnamed";
     427                 :         }
     428                 :     }
     429                 :     else
     430              22 :         pszPM = "Greenwich";
     431                 : 
     432                 : /* -------------------------------------------------------------------- */
     433                 : /*      Operate on the basis of the projection name.                    */
     434                 : /* -------------------------------------------------------------------- */
     435              25 :     const char *pszProj = CSLFetchNameValue(papszNV,"proj");
     436                 : 
     437              25 :     if( pszProj == NULL )
     438                 :     {
     439               0 :         CPLDebug( "OGR_PROJ4", "Can't find +proj= in:\n%s", pszProj4 );
     440               0 :         CSLDestroy( papszNV );
     441               0 :         return OGRERR_CORRUPT_DATA;
     442                 :     }
     443                 : 
     444              25 :     else if( EQUAL(pszProj,"longlat") || EQUAL(pszProj,"latlong") )
     445                 :     {
     446                 :     }
     447                 :     
     448              22 :     else if( EQUAL(pszProj,"bonne") )
     449                 :     {
     450                 :         SetBonne( OSR_GDV( papszNV, "lat_1", 0.0 ), 
     451                 :                   OSR_GDV( papszNV, "lon_0", 0.0 ), 
     452                 :                   OSR_GDV( papszNV, "x_0", 0.0 ), 
     453               0 :                   OSR_GDV( papszNV, "y_0", 0.0 ) );
     454                 :     }
     455                 : 
     456              22 :     else if( EQUAL(pszProj,"cass") )
     457                 :     {
     458                 :         SetCS( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     459                 :                OSR_GDV( papszNV, "lon_0", 0.0 ), 
     460                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     461               0 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     462                 :     }
     463                 : 
     464              22 :     else if( EQUAL(pszProj,"nzmg") )
     465                 :     {
     466                 :         SetNZMG( OSR_GDV( papszNV, "lat_0", -41.0 ), 
     467                 :                  OSR_GDV( papszNV, "lon_0", 173.0 ), 
     468                 :                  OSR_GDV( papszNV, "x_0", 2510000.0 ), 
     469               0 :                  OSR_GDV( papszNV, "y_0", 6023150.0 ) );
     470                 :     }
     471                 : 
     472              22 :     else if( EQUAL(pszProj,"cea") )
     473                 :     {
     474                 :         SetCEA( OSR_GDV( papszNV, "lat_ts", 0.0 ), 
     475                 :                 OSR_GDV( papszNV, "lon_0", 0.0 ), 
     476                 :                 OSR_GDV( papszNV, "x_0", 0.0 ), 
     477               0 :                 OSR_GDV( papszNV, "y_0", 0.0 ) );
     478                 :     }
     479                 : 
     480              22 :     else if( EQUAL(pszProj,"tmerc") )
     481                 :     {
     482                 :         SetTM( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     483                 :                OSR_GDV( papszNV, "lon_0", 0.0 ), 
     484                 :                OSR_GDV( papszNV, "k", 1.0 ), 
     485                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     486               3 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     487                 :     }
     488                 : 
     489              19 :     else if( EQUAL(pszProj,"utm") )
     490                 :     {
     491                 :         SetUTM( (int) OSR_GDV( papszNV, "zone", 0.0 ),
     492               5 :                 (int) OSR_GDV( papszNV, "south", 1.0 ) );
     493                 :     }
     494                 : 
     495              14 :     else if( EQUAL(pszProj,"merc") /* 2SP form */
     496                 :              && OSR_GDV(papszNV, "lat_ts", 1000.0) < 999.0 )
     497                 :     {
     498                 :         SetMercator2SP( OSR_GDV( papszNV, "lat_ts", 0.0 ), 
     499                 :                         0.0,
     500                 :                         OSR_GDV( papszNV, "lon_0", 0.0 ), 
     501                 :                         OSR_GDV( papszNV, "x_0", 0.0 ), 
     502               1 :                         OSR_GDV( papszNV, "y_0", 0.0 ) );
     503                 :     }
     504                 : 
     505              13 :     else if( EQUAL(pszProj,"merc") ) /* 1SP form */
     506                 :     {
     507                 :         SetMercator( 0.0,
     508                 :                      OSR_GDV( papszNV, "lon_0", 0.0 ), 
     509                 :                      OSR_GDV( papszNV, "k", 1.0 ), 
     510                 :                      OSR_GDV( papszNV, "x_0", 0.0 ), 
     511               0 :                      OSR_GDV( papszNV, "y_0", 0.0 ) );
     512                 :     }
     513                 : 
     514              13 :     else if( EQUAL(pszProj,"stere") 
     515                 :              && ABS(OSR_GDV( papszNV, "lat_0", 0.0 ) - 90) < 0.001 )
     516                 :     {
     517                 :         SetPS( OSR_GDV( papszNV, "lat_ts", 90.0 ), 
     518                 :                OSR_GDV( papszNV, "lon_0", 0.0 ), 
     519                 :                OSR_GDV( papszNV, "k", 1.0 ), 
     520                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     521               0 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     522                 :     }
     523                 : 
     524              13 :     else if( EQUAL(pszProj,"stere") 
     525                 :              && ABS(OSR_GDV( papszNV, "lat_0", 0.0 ) + 90) < 0.001 )
     526                 :     {
     527                 :         SetPS( OSR_GDV( papszNV, "lat_ts", -90.0 ), 
     528                 :                OSR_GDV( papszNV, "lon_0", 0.0 ), 
     529                 :                OSR_GDV( papszNV, "k", 1.0 ), 
     530                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     531               0 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     532                 :     }
     533                 : 
     534              13 :     else if( EQUALN(pszProj,"stere",5) /* mostly sterea */
     535                 :              && CSLFetchNameValue(papszNV,"k") != NULL )
     536                 :     {
     537                 :         SetOS( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     538                 :                OSR_GDV( papszNV, "lon_0", 0.0 ), 
     539                 :                OSR_GDV( papszNV, "k", 1.0 ), 
     540                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     541               0 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     542                 :     }
     543                 : 
     544              13 :     else if( EQUAL(pszProj,"stere") )
     545                 :     {
     546                 :         SetStereographic( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     547                 :                           OSR_GDV( papszNV, "lon_0", 0.0 ), 
     548                 :                           1.0, 
     549                 :                           OSR_GDV( papszNV, "x_0", 0.0 ), 
     550               0 :                           OSR_GDV( papszNV, "y_0", 0.0 ) );
     551                 :     }
     552                 : 
     553              13 :     else if( EQUAL(pszProj,"eqc") )
     554                 :     {
     555               2 :         if( OSR_GDV( papszNV, "lat_ts", 0.0 ) != 0.0 )
     556                 :           SetEquirectangular2( OSR_GDV( papszNV, "lat_0", 0.0 ),
     557                 :                                OSR_GDV( papszNV, "lon_0", 0.0 ),
     558                 :                                OSR_GDV( papszNV, "lat_ts", 0.0 ),
     559                 :                                OSR_GDV( papszNV, "x_0", 0.0 ),
     560               2 :                                OSR_GDV( papszNV, "y_0", 0.0 ) );
     561                 :         else
     562                 :           SetEquirectangular( OSR_GDV( papszNV, "lat_0", 0.0 ),
     563                 :                               OSR_GDV( papszNV, "lon_0", 0.0 ),
     564                 :                               OSR_GDV( papszNV, "x_0", 0.0 ),
     565               0 :                               OSR_GDV( papszNV, "y_0", 0.0 ) );
     566                 :     }
     567                 : 
     568              11 :     else if( EQUAL(pszProj,"gstmerc") )
     569                 :     {
     570                 :         SetGaussSchreiberTMercator( OSR_GDV( papszNV, "lat_0", -21.116666667 ),
     571                 :                                     OSR_GDV( papszNV, "lon_0", 55.53333333309),
     572                 :                                     OSR_GDV( papszNV, "k_0", 1.0 ),
     573                 :                                     OSR_GDV( papszNV, "x_0", 160000.000 ),
     574               0 :                                     OSR_GDV( papszNV, "y_0", 50000.000 ) );
     575                 :     }
     576                 : 
     577              11 :     else if( EQUAL(pszProj,"gnom") )
     578                 :     {
     579                 :         SetGnomonic( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     580                 :                      OSR_GDV( papszNV, "lon_0", 0.0 ), 
     581                 :                      OSR_GDV( papszNV, "x_0", 0.0 ), 
     582               0 :                      OSR_GDV( papszNV, "y_0", 0.0 ) );
     583                 :     }
     584                 : 
     585              11 :     else if( EQUAL(pszProj,"ortho") )
     586                 :     {
     587                 :         SetOrthographic( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     588                 :                          OSR_GDV( papszNV, "lon_0", 0.0 ), 
     589                 :                          OSR_GDV( papszNV, "x_0", 0.0 ), 
     590               0 :                          OSR_GDV( papszNV, "y_0", 0.0 ) );
     591                 :     }
     592                 : 
     593              11 :     else if( EQUAL(pszProj,"laea") )
     594                 :     {
     595                 :         SetLAEA( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     596                 :                  OSR_GDV( papszNV, "lon_0", 0.0 ), 
     597                 :                  OSR_GDV( papszNV, "x_0", 0.0 ), 
     598               0 :                  OSR_GDV( papszNV, "y_0", 0.0 ) );
     599                 :     }
     600                 : 
     601              11 :     else if( EQUAL(pszProj,"aeqd") )
     602                 :     {
     603                 :         SetAE( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     604                 :                OSR_GDV( papszNV, "lon_0", 0.0 ), 
     605                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     606               1 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     607                 :     }
     608                 : 
     609              10 :     else if( EQUAL(pszProj,"eqdc") )
     610                 :     {
     611                 :         SetEC( OSR_GDV( papszNV, "lat_1", 0.0 ), 
     612                 :                OSR_GDV( papszNV, "lat_2", 0.0 ), 
     613                 :                OSR_GDV( papszNV, "lat_0", 0.0 ), 
     614                 :                OSR_GDV( papszNV, "lon_0", 0.0 ), 
     615                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     616               0 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     617                 :     }
     618                 : 
     619              10 :     else if( EQUAL(pszProj,"mill") )
     620                 :     {
     621                 :         SetMC( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     622                 :                OSR_GDV( papszNV, "lon_0", 0.0 ), 
     623                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     624               1 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     625                 :     }
     626                 : 
     627               9 :     else if( EQUAL(pszProj,"moll") )
     628                 :     {
     629                 :         SetMollweide( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     630                 :                       OSR_GDV( papszNV, "x_0", 0.0 ), 
     631               0 :                       OSR_GDV( papszNV, "y_0", 0.0 ) );
     632                 :     }
     633                 : 
     634              10 :     else if( EQUAL(pszProj,"eck1") || EQUAL(pszProj,"eck2") || EQUAL(pszProj,"eck3") ||
     635                 :              EQUAL(pszProj,"eck4") || EQUAL(pszProj,"eck5") || EQUAL(pszProj,"eck6"))
     636                 :     {
     637               1 :         SetEckert(   pszProj[3] - '0',
     638                 :                      OSR_GDV( papszNV, "lon_0", 0.0 ), 
     639                 :                      OSR_GDV( papszNV, "x_0", 0.0 ), 
     640               2 :                      OSR_GDV( papszNV, "y_0", 0.0 ) );
     641                 :     }
     642                 : 
     643               8 :     else if( EQUAL(pszProj,"poly") )
     644                 :     {
     645                 :         SetPolyconic( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     646                 :                       OSR_GDV( papszNV, "lon_0", 0.0 ), 
     647                 :                       OSR_GDV( papszNV, "x_0", 0.0 ), 
     648               0 :                       OSR_GDV( papszNV, "y_0", 0.0 ) );
     649                 :     }
     650                 : 
     651               8 :     else if( EQUAL(pszProj,"aea") )
     652                 :     {
     653                 :         SetACEA( OSR_GDV( papszNV, "lat_1", 0.0 ), 
     654                 :                  OSR_GDV( papszNV, "lat_2", 0.0 ), 
     655                 :                  OSR_GDV( papszNV, "lat_0", 0.0 ), 
     656                 :                  OSR_GDV( papszNV, "lon_0", 0.0 ), 
     657                 :                  OSR_GDV( papszNV, "x_0", 0.0 ), 
     658               0 :                  OSR_GDV( papszNV, "y_0", 0.0 ) );
     659                 :     }
     660                 : 
     661               8 :     else if( EQUAL(pszProj,"robin") )
     662                 :     {
     663                 :         SetRobinson( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     664                 :                      OSR_GDV( papszNV, "x_0", 0.0 ), 
     665               0 :                      OSR_GDV( papszNV, "y_0", 0.0 ) );
     666                 :     }
     667                 : 
     668               8 :     else if( EQUAL(pszProj,"vandg") )
     669                 :     {
     670                 :         SetVDG( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     671                 :                 OSR_GDV( papszNV, "x_0", 0.0 ), 
     672               1 :                 OSR_GDV( papszNV, "y_0", 0.0 ) );
     673                 :     }
     674                 : 
     675               7 :     else if( EQUAL(pszProj,"sinu") )
     676                 :     {
     677                 :         SetSinusoidal( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     678                 :                        OSR_GDV( papszNV, "x_0", 0.0 ), 
     679               1 :                        OSR_GDV( papszNV, "y_0", 0.0 ) );
     680                 :     }
     681                 : 
     682               6 :     else if( EQUAL(pszProj,"gall") )
     683                 :     {
     684                 :         SetGS( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     685                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     686               1 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     687                 :     }
     688                 : 
     689               5 :     else if( EQUAL(pszProj,"goode") )
     690                 :     {
     691                 :         SetGH( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     692                 :                OSR_GDV( papszNV, "x_0", 0.0 ), 
     693               0 :                OSR_GDV( papszNV, "y_0", 0.0 ) );
     694                 :     }
     695                 : 
     696               5 :     else if( EQUAL(pszProj,"geos") )
     697                 :     {
     698                 :         SetGEOS( OSR_GDV( papszNV, "lon_0", 0.0 ), 
     699                 :                  OSR_GDV( papszNV, "h", 35785831.0 ), 
     700                 :                  OSR_GDV( papszNV, "x_0", 0.0 ), 
     701               0 :                  OSR_GDV( papszNV, "y_0", 0.0 ) );
     702                 :     }
     703                 : 
     704               5 :     else if( EQUAL(pszProj,"lcc") ) 
     705                 :     {
     706               3 :         if( OSR_GDV(papszNV, "lat_0", 0.0 ) 
     707                 :             == OSR_GDV(papszNV, "lat_1", 0.0 ) )
     708                 :         {
     709                 :             /* 1SP form */
     710                 :             SetLCC1SP( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     711                 :                        OSR_GDV( papszNV, "lon_0", 0.0 ), 
     712                 :                        OSR_GDV( papszNV, "k_0", 1.0 ), 
     713                 :                        OSR_GDV( papszNV, "x_0", 0.0 ), 
     714               2 :                        OSR_GDV( papszNV, "y_0", 0.0 ) );
     715                 :         }
     716                 :         else
     717                 :         {
     718                 :             /* 2SP form */
     719                 :             SetLCC( OSR_GDV( papszNV, "lat_1", 0.0 ), 
     720                 :                     OSR_GDV( papszNV, "lat_2", 0.0 ), 
     721                 :                     OSR_GDV( papszNV, "lat_0", 0.0 ), 
     722                 :                     OSR_GDV( papszNV, "lon_0", 0.0 ), 
     723                 :                     OSR_GDV( papszNV, "x_0", 0.0 ), 
     724               1 :                     OSR_GDV( papszNV, "y_0", 0.0 ) );
     725                 :         }
     726                 :     }
     727                 : 
     728               2 :     else if( EQUAL(pszProj,"omerc") )
     729                 :     {
     730                 :         SetHOM( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     731                 :                 OSR_GDV( papszNV, "lonc", 0.0 ), 
     732                 :                 OSR_GDV( papszNV, "alpha", 0.0 ), 
     733                 :                 0.0, /* ??? */
     734                 :                 OSR_GDV( papszNV, "k", 1.0 ), 
     735                 :                 OSR_GDV( papszNV, "x_0", 0.0 ), 
     736               0 :                 OSR_GDV( papszNV, "y_0", 0.0 ) );
     737                 :     }
     738                 : 
     739               2 :     else if( EQUAL(pszProj,"somerc") )
     740                 :     {
     741                 :         SetHOM( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     742                 :                 OSR_GDV( papszNV, "lon_0", 0.0 ), 
     743                 :                 90.0,  90.0, 
     744                 :                 OSR_GDV( papszNV, "k", 1.0 ), 
     745                 :                 OSR_GDV( papszNV, "x_0", 0.0 ), 
     746               1 :                 OSR_GDV( papszNV, "y_0", 0.0 ) );
     747                 :     }
     748                 : 
     749               1 :     else if( EQUAL(pszProj,"krovak") )
     750                 :     {
     751                 :         SetKrovak( OSR_GDV( papszNV, "lat_0", 0.0 ), 
     752                 :                    OSR_GDV( papszNV, "lon_0", 0.0 ), 
     753                 :                    OSR_GDV( papszNV, "alpha", 0.0 ), 
     754                 :                    0.0, // pseudo_standard_parallel_1
     755                 :                    OSR_GDV( papszNV, "k", 1.0 ), 
     756                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     757               0 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     758                 :     }
     759                 : 
     760               1 :     else if( EQUAL(pszProj, "iwm_p") )
     761                 :     {
     762                 :         SetIWMPolyconic( OSR_GDV( papszNV, "lat_1", 0.0 ), 
     763                 :                          OSR_GDV( papszNV, "lat_2", 0.0 ),
     764                 :                          OSR_GDV( papszNV, "lon_0", 0.0 ), 
     765                 :                          OSR_GDV( papszNV, "x_0", 0.0 ), 
     766               0 :                          OSR_GDV( papszNV, "y_0", 0.0 ) );
     767                 :     }
     768                 : 
     769               1 :     else if( EQUAL(pszProj, "wag1") )
     770                 :     {
     771                 :         SetWagner( 1, 0.0,
     772                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     773               0 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     774                 :     }
     775                 : 
     776               1 :     else if( EQUAL(pszProj, "wag2") )
     777                 :     {
     778                 :         SetWagner( 2, 0.0,
     779                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     780               0 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     781                 :     }
     782                 : 
     783               1 :     else if( EQUAL(pszProj, "wag3") )
     784                 :     {
     785                 :         SetWagner( 3,
     786                 :                    OSR_GDV( papszNV, "lat_ts", 0.0 ),
     787                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     788               0 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     789                 :     }
     790                 : 
     791               1 :     else if( EQUAL(pszProj, "wag4") )
     792                 :     {
     793                 :         SetWagner( 4, 0.0,
     794                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     795               0 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     796                 :     }
     797                 : 
     798               1 :     else if( EQUAL(pszProj, "wag5") )
     799                 :     {
     800                 :         SetWagner( 5, 0.0,
     801                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     802               0 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     803                 :     }
     804                 : 
     805               1 :     else if( EQUAL(pszProj, "wag6") )
     806                 :     {
     807                 :         SetWagner( 6, 0.0,
     808                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     809               0 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     810                 :     }
     811                 : 
     812               1 :     else if( EQUAL(pszProj, "wag7") )
     813                 :     {
     814                 :         SetWagner( 7, 0.0,
     815                 :                    OSR_GDV( papszNV, "x_0", 0.0 ), 
     816               0 :                    OSR_GDV( papszNV, "y_0", 0.0 ) );
     817                 :     }
     818                 : 
     819               1 :     else if( EQUAL(pszProj,"tpeqd") )
     820                 :     {
     821                 :         SetTPED( OSR_GDV( papszNV, "lat_1", 0.0 ), 
     822                 :                  OSR_GDV( papszNV, "lon_1", 0.0 ), 
     823                 :                  OSR_GDV( papszNV, "lat_2", 0.0 ), 
     824                 :                  OSR_GDV( papszNV, "lon_2", 0.0 ), 
     825                 :                  OSR_GDV( papszNV, "x_0", 0.0 ), 
     826               1 :                  OSR_GDV( papszNV, "y_0", 0.0 ) );
     827                 :     }
     828                 : 
     829                 :     else
     830                 :     {
     831               0 :         CPLDebug( "OGR_PROJ4", "Unsupported projection: %s", pszProj );
     832               0 :         CSLDestroy( papszNV );
     833               0 :         return OGRERR_CORRUPT_DATA;
     834                 :     }
     835                 : 
     836                 : /* -------------------------------------------------------------------- */
     837                 : /*      Try to translate the datum.                                     */
     838                 : /* -------------------------------------------------------------------- */
     839                 :     const char *pszValue;
     840              25 :     int  bFullyDefined = FALSE;
     841                 : 
     842              25 :     pszValue = CSLFetchNameValue(papszNV, "datum");
     843              25 :     if( pszValue == NULL )
     844                 :     {
     845                 :         /* do nothing */
     846                 :     }
     847              17 :     else if( (EQUAL(pszValue,"NAD27") || EQUAL(pszValue,"NAD83")
     848                 :               || EQUAL(pszValue,"WGS84") || EQUAL(pszValue,"WGS72"))
     849                 :              && dfFromGreenwich == 0.0 )
     850                 :     {
     851               8 :         SetWellKnownGeogCS( pszValue );
     852               8 :         bFullyDefined = TRUE;
     853                 :     }
     854                 :     else
     855                 :     {
     856                 :         unsigned int i;
     857               8 :         for(i=0;i<sizeof(ogr_pj_datums)/sizeof(ogr_pj_datums[0]);i++)
     858                 :         {
     859               7 :             if ( EQUAL(pszValue, ogr_pj_datums[i].pszPJ) )
     860                 :             {
     861               0 :                 OGRSpatialReference oGCS;
     862               0 :                 oGCS.importFromEPSG( ogr_pj_datums[i].nEPSG );
     863               0 :                 CopyGeogCSFrom( &oGCS );
     864               0 :                 bFullyDefined = TRUE;
     865               0 :                 break;
     866                 :             }
     867                 :         }
     868                 : 
     869                 :         /* If we don't recognise the datum, we ignore it */
     870                 :     }
     871                 : 
     872                 : /* -------------------------------------------------------------------- */
     873                 : /*      Set the ellipsoid information.                                   */
     874                 : /* -------------------------------------------------------------------- */
     875                 :     double dfSemiMajor, dfInvFlattening, dfSemiMinor;
     876                 : 
     877              25 :     pszValue = CSLFetchNameValue(papszNV, "ellps");
     878              25 :     if( pszValue != NULL && !bFullyDefined )
     879                 :     {
     880             772 :         for( i = 0; ogr_pj_ellps[i] != NULL; i += 4 )
     881                 :         {
     882             386 :             if( !EQUAL(ogr_pj_ellps[i],pszValue) )
     883             375 :                 continue;
     884                 : 
     885                 :             CPLAssert( EQUALN(ogr_pj_ellps[i+1],"a=",2) );
     886                 :             
     887              11 :             dfSemiMajor = CPLAtof(ogr_pj_ellps[i+1]+2);
     888              11 :             if( EQUALN(ogr_pj_ellps[i+2],"rf=",3) )
     889               8 :                 dfInvFlattening = CPLAtof(ogr_pj_ellps[i+2]+3);
     890                 :             else
     891                 :             {
     892                 :                 CPLAssert( EQUALN(ogr_pj_ellps[i+2],"b=",2) );
     893               3 :                 dfSemiMinor = CPLAtof(ogr_pj_ellps[i+2]+2);
     894                 :                 
     895               3 :                 if( ABS(dfSemiMajor/dfSemiMinor) - 1.0 < 0.0000000000001 )
     896               3 :                     dfInvFlattening = 0.0;
     897                 :                 else
     898               0 :                     dfInvFlattening = -1.0 / (dfSemiMinor/dfSemiMajor - 1.0);
     899                 :             }
     900                 :             
     901                 :             SetGeogCS( ogr_pj_ellps[i+3], "unknown", ogr_pj_ellps[i], 
     902                 :                        dfSemiMajor, dfInvFlattening,
     903              11 :                        pszPM, dfFromGreenwich );
     904                 : 
     905              11 :             bFullyDefined = TRUE;
     906              11 :             break;
     907                 :         }
     908                 :     }
     909                 : 
     910              25 :     if( !bFullyDefined )
     911                 :     {
     912               6 :         dfSemiMajor = OSR_GDV( papszNV, "a", 0.0 );
     913               6 :         if( dfSemiMajor == 0.0 )
     914                 :         {
     915               0 :             dfSemiMajor = OSR_GDV( papszNV, "R", 0.0 );
     916               0 :             if( dfSemiMajor != 0.0 )
     917                 :             {
     918               0 :                 dfSemiMinor = -1.0;
     919               0 :                 dfInvFlattening = 0.0;
     920                 :             }
     921                 :             else
     922                 :             {
     923                 :                 CPLDebug( "OGR_PROJ4", "Can't find ellipse definition, default to WGS84:\n%s", 
     924               0 :                           pszProj4 );
     925                 :                 
     926               0 :                 dfSemiMajor = SRS_WGS84_SEMIMAJOR;
     927               0 :                 dfSemiMinor = -1.0;
     928               0 :                 dfInvFlattening = SRS_WGS84_INVFLATTENING;
     929                 :             }
     930                 :         }
     931                 :         else
     932                 :         {
     933               6 :             dfSemiMinor = OSR_GDV( papszNV, "b", -1.0 );
     934               6 :             dfInvFlattening = OSR_GDV( papszNV, "rf", -1.0 );
     935                 :         }
     936                 :         
     937               6 :         if( dfSemiMinor == -1.0 && dfInvFlattening == -1.0 )
     938                 :         {
     939                 :             CPLDebug( "OGR_PROJ4", "Can't find ellipse definition in:\n%s", 
     940               0 :                       pszProj4 );
     941               0 :             CSLDestroy( papszNV );
     942               0 :             return OGRERR_UNSUPPORTED_SRS;
     943                 :         }
     944                 : 
     945               6 :         if( dfInvFlattening == -1.0 )
     946                 :         {
     947               4 :             if( ABS(dfSemiMajor/dfSemiMinor) - 1.0 < 0.0000000000001 )
     948               2 :                 dfInvFlattening = 0.0;
     949                 :             else
     950               2 :                 dfInvFlattening = -1.0 / (dfSemiMinor/dfSemiMajor - 1.0);
     951                 :         }
     952                 :         
     953                 :         SetGeogCS( "unnamed ellipse", "unknown", "unnamed",
     954                 :                    dfSemiMajor, dfInvFlattening,
     955               6 :                    pszPM, dfFromGreenwich );
     956                 :         
     957               6 :         bFullyDefined = TRUE;
     958                 :     }
     959                 : 
     960                 : /* -------------------------------------------------------------------- */
     961                 : /*      Handle TOWGS84 conversion.                                      */
     962                 : /* -------------------------------------------------------------------- */
     963              25 :     pszValue = CSLFetchNameValue(papszNV, "towgs84");
     964              25 :     if(pszValue!=NULL)
     965                 :     {
     966                 :         char **papszToWGS84 = CSLTokenizeStringComplex( pszValue, ",", 
     967              12 :                                                         FALSE, TRUE );
     968                 : 
     969              12 :         if( CSLCount(papszToWGS84) >= 7 )
     970               4 :             SetTOWGS84( CPLAtof(papszToWGS84[0]), 
     971               4 :                         CPLAtof(papszToWGS84[1]), 
     972               4 :                         CPLAtof(papszToWGS84[2]), 
     973               4 :                         CPLAtof(papszToWGS84[3]), 
     974               4 :                         CPLAtof(papszToWGS84[4]), 
     975               4 :                         CPLAtof(papszToWGS84[5]), 
     976              28 :                         CPLAtof(papszToWGS84[6]) );
     977               8 :         else if( CSLCount(papszToWGS84) >= 3 )
     978               8 :             SetTOWGS84( CPLAtof(papszToWGS84[0]), 
     979               8 :                         CPLAtof(papszToWGS84[1]), 
     980              24 :                         CPLAtof(papszToWGS84[2]) );
     981                 :         else
     982                 :             CPLError( CE_Warning, CPLE_AppDefined, 
     983                 :                       "Seemingly corrupt +towgs84 option (%s), ignoring.", 
     984               0 :                       pszValue );
     985                 :                         
     986              12 :         CSLDestroy(papszToWGS84);
     987                 :     }
     988                 : 
     989                 : /* -------------------------------------------------------------------- */
     990                 : /*      Linear units translation                                        */
     991                 : /* -------------------------------------------------------------------- */
     992              25 :     if( IsProjected() || IsLocal() )
     993                 :     {
     994              22 :         pszValue = CSLFetchNameValue(papszNV, "to_meter");
     995                 : 
     996              22 :         if( pszValue != NULL && CPLAtofM(pszValue) > 0.0 )
     997                 :         {
     998               0 :             double dfValue = CPLAtofM(pszValue);
     999                 : 
    1000               0 :             if( fabs(dfValue - CPLAtof(SRS_UL_US_FOOT_CONV)) < 0.00000001 )
    1001               0 :                 SetLinearUnits( SRS_UL_US_FOOT, CPLAtof(SRS_UL_US_FOOT_CONV) );
    1002               0 :             else if( fabs(dfValue - CPLAtof(SRS_UL_FOOT_CONV)) < 0.00000001 )
    1003               0 :                 SetLinearUnits( SRS_UL_FOOT, CPLAtof(SRS_UL_FOOT_CONV) );
    1004               0 :             else if( dfValue == 1.0 )
    1005               0 :                 SetLinearUnits( SRS_UL_METER, 1.0 );
    1006                 :             else
    1007               0 :                 SetLinearUnits( "unknown", CPLAtofM(pszValue) );
    1008                 :         }
    1009              22 :         else if( (pszValue = CSLFetchNameValue(papszNV, "units")) != NULL )
    1010                 :         {
    1011              16 :             if( EQUAL(pszValue,"meter" ) || EQUAL(pszValue,"m") )
    1012               8 :                 SetLinearUnits( SRS_UL_METER, 1.0 );
    1013               0 :             else if( EQUAL(pszValue,"us-ft" ) )
    1014               0 :                 SetLinearUnits( SRS_UL_US_FOOT, CPLAtof(SRS_UL_US_FOOT_CONV) );
    1015               0 :             else if( EQUAL(pszValue,"ft" ) )
    1016               0 :                 SetLinearUnits( SRS_UL_FOOT, CPLAtof(SRS_UL_FOOT_CONV) );
    1017               0 :             else if( EQUAL(pszValue,"yd" ) )
    1018               0 :                 SetLinearUnits( pszValue, 0.9144 );
    1019               0 :             else if( EQUAL(pszValue,"us-yd" ) )
    1020               0 :                 SetLinearUnits( pszValue, 0.914401828803658 );
    1021                 :             else // This case is untranslatable.  Should add all proj.4 unts
    1022               0 :                 SetLinearUnits( pszValue, 1.0 );
    1023                 :         }
    1024                 :     }
    1025                 : 
    1026                 : /* -------------------------------------------------------------------- */
    1027                 : /*      Adjust linear parameters into PROJCS units if the linear        */
    1028                 : /*      units are not meters.                                           */
    1029                 : /* -------------------------------------------------------------------- */
    1030              25 :     if( GetLinearUnits() != 1.0 && IsProjected() )
    1031                 :     {
    1032               0 :         OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
    1033                 :         int  i;
    1034                 : 
    1035               0 :         for( i = 0; i < poPROJCS->GetChildCount(); i++ )
    1036                 :         {
    1037               0 :             OGR_SRSNode *poParm = poPROJCS->GetChild(i);
    1038               0 :             if( !EQUAL(poParm->GetValue(),"PARAMETER") 
    1039                 :                 || poParm->GetChildCount() != 2 )
    1040               0 :                 continue;
    1041                 : 
    1042               0 :             const char *pszParmName = poParm->GetChild(0)->GetValue();
    1043                 : 
    1044               0 :             if( IsLinearParameter(pszParmName) )
    1045               0 :                 SetNormProjParm(pszParmName,GetProjParm(pszParmName));
    1046                 :         }        
    1047                 :     }
    1048                 : 
    1049                 : 
    1050                 : /* -------------------------------------------------------------------- */
    1051                 : /*      do we want to insert a PROJ.4 EXTENSION item?                   */
    1052                 : /* -------------------------------------------------------------------- */
    1053              25 :     if( strstr(pszProj4,"wktext") != NULL )
    1054               0 :         SetExtension( GetRoot()->GetValue(), "PROJ4", pszProj4 );
    1055                 :         
    1056              25 :     CSLDestroy( papszNV );
    1057                 :     
    1058              25 :     return OGRERR_NONE;
    1059                 : }
    1060                 : 
    1061                 : 
    1062                 : /************************************************************************/
    1063                 : /*                          OSRExportToProj4()                          */
    1064                 : /************************************************************************/
    1065                 : /** 
    1066                 :  * \brief Export coordinate system in PROJ.4 format.
    1067                 :  *
    1068                 :  * This function is the same as OGRSpatialReference::exportToProj4().
    1069                 :  */
    1070              26 : OGRErr CPL_STDCALL OSRExportToProj4( OGRSpatialReferenceH hSRS, 
    1071                 :                                      char ** ppszReturn )
    1072                 : 
    1073                 : {
    1074              26 :     VALIDATE_POINTER1( hSRS, "OSRExportToProj4", CE_Failure );
    1075                 : 
    1076              26 :     *ppszReturn = NULL;
    1077                 : 
    1078              26 :     return ((OGRSpatialReference *) hSRS)->exportToProj4( ppszReturn );
    1079                 : }
    1080                 : 
    1081                 : /************************************************************************/
    1082                 : /*                           exportToProj4()                            */
    1083                 : /************************************************************************/
    1084                 : 
    1085                 : /**
    1086                 :  * \brief Export coordinate system in PROJ.4 format.
    1087                 :  *
    1088                 :  * Converts the loaded coordinate reference system into PROJ.4 format
    1089                 :  * to the extent possible.  The string returned in ppszProj4 should be
    1090                 :  * deallocated by the caller with CPLFree() when no longer needed.
    1091                 :  *
    1092                 :  * LOCAL_CS coordinate systems are not translatable.  An empty string
    1093                 :  * will be returned along with OGRERR_NONE.  
    1094                 :  *
    1095                 :  * This method is the equivelent of the C function OSRExportToProj4().
    1096                 :  *
    1097                 :  * @param ppszProj4 pointer to which dynamically allocated PROJ.4 definition 
    1098                 :  * will be assigned. 
    1099                 :  *
    1100                 :  * @return OGRERR_NONE on success or an error code on failure. 
    1101                 :  */
    1102                 : 
    1103             309 : OGRErr OGRSpatialReference::exportToProj4( char ** ppszProj4 ) const
    1104                 : 
    1105                 : {
    1106                 :     char        szProj4[512];
    1107             309 :     const char *pszProjection = GetAttrValue("PROJECTION");
    1108             309 :     CPLLocaleC  oLocaleEnforcer;
    1109                 : 
    1110             309 :     szProj4[0] = '\0';
    1111                 : 
    1112             309 :     if( GetRoot() == NULL )
    1113                 :     {
    1114               1 :         *ppszProj4 = CPLStrdup("");
    1115                 :         CPLError( CE_Failure, CPLE_NotSupported,
    1116               1 :                   "No translation an empty SRS to PROJ.4 format is known.");
    1117               1 :         return OGRERR_UNSUPPORTED_SRS;
    1118                 :     }
    1119                 : 
    1120                 : /* -------------------------------------------------------------------- */
    1121                 : /*      Do we have a PROJ.4 override definition?                        */
    1122                 : /* -------------------------------------------------------------------- */
    1123                 :     const char *pszPredefProj4 = GetExtension( GetRoot()->GetValue(), 
    1124             308 :                                                "PROJ4", NULL );
    1125             308 :     if( pszPredefProj4 != NULL )
    1126                 :     {
    1127               8 :         *ppszProj4 = CPLStrdup( pszPredefProj4 );
    1128               8 :         return OGRERR_NONE;
    1129                 :     }
    1130                 : 
    1131                 : /* -------------------------------------------------------------------- */
    1132                 : /*      Get the prime meridian info.                                    */
    1133                 : /* -------------------------------------------------------------------- */
    1134             300 :     const OGR_SRSNode *poPRIMEM = GetAttrNode( "PRIMEM" );
    1135             300 :     double dfFromGreenwich = 0.0;
    1136                 : 
    1137             300 :     if( poPRIMEM != NULL && poPRIMEM->GetChildCount() >= 2 
    1138                 :         && CPLAtof(poPRIMEM->GetChild(1)->GetValue()) != 0.0 )
    1139                 :     {
    1140               6 :         dfFromGreenwich = CPLAtof(poPRIMEM->GetChild(1)->GetValue());
    1141                 :     }
    1142                 : 
    1143                 : /* ==================================================================== */
    1144                 : /*      Handle the projection definition.                               */
    1145                 : /* ==================================================================== */
    1146                 : 
    1147             300 :     if( pszProjection == NULL && IsGeographic() )
    1148                 :     {
    1149             151 :         sprintf( szProj4+strlen(szProj4), "+proj=longlat " );
    1150                 :     }
    1151             149 :     else if( pszProjection == NULL && !IsGeographic() )
    1152                 :     {
    1153                 :         // LOCAL_CS, or incompletely initialized coordinate systems.
    1154               0 :         *ppszProj4 = CPLStrdup("");
    1155               0 :         return OGRERR_NONE;
    1156                 :     }
    1157             149 :     else if( EQUAL(pszProjection,SRS_PT_CYLINDRICAL_EQUAL_AREA) )
    1158                 :     {
    1159                 :         sprintf( szProj4+strlen(szProj4),
    1160                 :            "+proj=cea +lon_0=%.16g +lat_ts=%.16g +x_0=%.16g +y_0=%.16g ",
    1161                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1162                 :                  GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0),
    1163                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1164               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1165                 :     }
    1166                 : 
    1167             149 :     else if( EQUAL(pszProjection,SRS_PT_BONNE) )
    1168                 :     {
    1169                 :         sprintf( szProj4+strlen(szProj4),
    1170                 :            "+proj=bonne +lon_0=%.16g +lat_1=%.16g +x_0=%.16g +y_0=%.16g ",
    1171                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1172                 :                  GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0),
    1173                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1174               2 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1175                 :     }
    1176                 : 
    1177             147 :     else if( EQUAL(pszProjection,SRS_PT_CASSINI_SOLDNER) )
    1178                 :     {
    1179                 :         sprintf( szProj4+strlen(szProj4),
    1180                 :            "+proj=cass +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1181                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1182                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1183                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1184               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1185                 :     }
    1186                 : 
    1187             147 :     else if( EQUAL(pszProjection,SRS_PT_NEW_ZEALAND_MAP_GRID) )
    1188                 :     {
    1189                 :         sprintf( szProj4+strlen(szProj4),
    1190                 :                  "+proj=nzmg +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1191                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1192                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1193                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1194               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1195                 :     }
    1196                 : 
    1197             253 :     else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR) ||
    1198                 :              EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_21) ||
    1199                 :              EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_22) ||
    1200                 :              EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_23) ||
    1201                 :              EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_24) ||
    1202                 :              EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_25) )
    1203                 :     {
    1204                 :         int bNorth;
    1205             106 :         int nZone = GetUTMZone( &bNorth );
    1206                 : 
    1207             106 :         if( nZone != 0 )
    1208                 :         {
    1209              97 :             if( bNorth )
    1210                 :                 sprintf( szProj4+strlen(szProj4), "+proj=utm +zone=%d ", 
    1211              96 :                          nZone );
    1212                 :             else
    1213                 :                 sprintf( szProj4+strlen(szProj4),"+proj=utm +zone=%d +south ", 
    1214               1 :                          nZone );
    1215                 :         }            
    1216                 :         else
    1217                 :             sprintf( szProj4+strlen(szProj4),
    1218                 :              "+proj=tmerc +lat_0=%.16g +lon_0=%.16g +k=%.16g +x_0=%.16g +y_0=%.16g ",
    1219                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1220                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1221                 :                  GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
    1222                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1223               9 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1224                 :     }
    1225                 : 
    1226              41 :     else if( EQUAL(pszProjection,SRS_PT_MERCATOR_1SP) )
    1227                 :     {
    1228               2 :         if( GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0) == 0.0 )
    1229                 :             sprintf( szProj4+strlen(szProj4),
    1230                 :                      "+proj=merc +lon_0=%.16g +k=%.16g +x_0=%.16g +y_0=%.16g ",
    1231                 :                      GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1232                 :                      GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
    1233                 :                      GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1234               0 :                      GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1235               2 :         else if( GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0) == 1.0 )
    1236                 :             sprintf( szProj4+strlen(szProj4),
    1237                 :                      "+proj=merc +lon_0=%.16g +lat_ts=%.16g +x_0=%.16g +y_0=%.16g ",
    1238                 :                      GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1239                 :                      GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1240                 :                      GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1241               2 :                      GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1242                 :         else
    1243                 :         {
    1244                 :             CPLError( CE_Failure, CPLE_NotSupported,
    1245               0 :                       "Mercator_1SP with scale != 1.0 and latitude of origin != 0, not supported by PROJ.4." );
    1246               0 :             *ppszProj4 = CPLStrdup("");
    1247               0 :             return OGRERR_UNSUPPORTED_SRS;
    1248                 :         }
    1249                 :     }
    1250                 : 
    1251              39 :     else if( EQUAL(pszProjection,SRS_PT_MERCATOR_2SP) )
    1252                 :     {
    1253                 :         sprintf( szProj4+strlen(szProj4),
    1254                 :            "+proj=merc +lon_0=%.16g +lat_ts=%.16g +x_0=%.16g +y_0=%.16g ",
    1255                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1256                 :                  GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0),
    1257                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1258               5 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1259                 :     }
    1260                 : 
    1261              34 :     else if( EQUAL(pszProjection,SRS_PT_OBLIQUE_STEREOGRAPHIC) )
    1262                 :     {
    1263                 :         sprintf( szProj4+strlen(szProj4),
    1264                 :          "+proj=sterea +lat_0=%.16g +lon_0=%.16g +k=%.16g +x_0=%.16g +y_0=%.16g ",
    1265                 : //         "+proj=stere +lat_0=%.16g +lon_0=%.16g +k=%.16g +x_0=%.16g +y_0=%.16g ",
    1266                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1267                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1268                 :                  GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
    1269                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1270               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1271                 :     }
    1272                 : 
    1273              34 :     else if( EQUAL(pszProjection,SRS_PT_STEREOGRAPHIC) )
    1274                 :     {
    1275                 :         sprintf( szProj4+strlen(szProj4),
    1276                 :            "+proj=stere +lat_0=%.16g +lon_0=%.16g +k=%.16g +x_0=%.16g +y_0=%.16g ",
    1277                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1278                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1279                 :                  GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
    1280                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1281               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1282                 :     }
    1283                 : 
    1284              34 :     else if( EQUAL(pszProjection,SRS_PT_POLAR_STEREOGRAPHIC) )
    1285                 :     {
    1286               0 :         if( GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0) >= 0.0 )
    1287                 :             sprintf( szProj4+strlen(szProj4),
    1288                 :                      "+proj=stere +lat_0=90 +lat_ts=%.16g +lon_0=%.16g "
    1289                 :                      "+k=%.16g +x_0=%.16g +y_0=%.16g ",
    1290                 :                      GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,90.0),
    1291                 :                      GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1292                 :                      GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
    1293                 :                      GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1294               0 :                      GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1295                 :         else
    1296                 :             sprintf( szProj4+strlen(szProj4),
    1297                 :                      "+proj=stere +lat_0=-90 +lat_ts=%.16g +lon_0=%.16g "
    1298                 :                      "+k=%.16g +x_0=%.16g +y_0=%.16g ",
    1299                 :                      GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,-90.0),
    1300                 :                      GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1301                 :                      GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
    1302                 :                      GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1303               0 :                      GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1304                 :     }
    1305                 : 
    1306              34 :     else if( EQUAL(pszProjection,SRS_PT_EQUIRECTANGULAR) )
    1307                 :     {
    1308                 :         sprintf( szProj4+strlen(szProj4),
    1309                 :                  "+proj=eqc +lat_ts=%.16g +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1310                 :                  GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0),
    1311                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1312                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1313                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1314               2 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1315                 :     }
    1316                 : 
    1317              32 :     else if( EQUAL(pszProjection,SRS_PT_GAUSSSCHREIBERTMERCATOR) )
    1318                 :     {
    1319                 :       sprintf( szProj4+strlen(szProj4),
    1320                 :                "+proj=gstmerc +lat_0=%.16g +lon_0=%.16g"
    1321                 :                " +k_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1322                 :                GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,-21.116666667),
    1323                 :                GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,55.53333333309),
    1324                 :                GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
    1325                 :                GetNormProjParm(SRS_PP_FALSE_EASTING,160000.000),
    1326               0 :                GetNormProjParm(SRS_PP_FALSE_NORTHING,50000.000) );
    1327                 :     }
    1328                 : 
    1329              32 :     else if( EQUAL(pszProjection,SRS_PT_GNOMONIC) )
    1330                 :     {
    1331                 :         sprintf( szProj4+strlen(szProj4),
    1332                 :                  "+proj=gnom +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1333                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1334                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1335                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1336               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1337                 :     }
    1338                 : 
    1339              32 :     else if( EQUAL(pszProjection,SRS_PT_ORTHOGRAPHIC) )
    1340                 :     {
    1341                 :         sprintf( szProj4+strlen(szProj4),
    1342                 :                  "+proj=ortho +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1343                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1344                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1345                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1346               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1347                 :     }
    1348                 : 
    1349              32 :     else if( EQUAL(pszProjection,SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA) )
    1350                 :     {
    1351                 :         sprintf( szProj4+strlen(szProj4),
    1352                 :                  "+proj=laea +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1353                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1354                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1355                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1356               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1357                 :     }
    1358                 : 
    1359              32 :     else if( EQUAL(pszProjection,SRS_PT_AZIMUTHAL_EQUIDISTANT) )
    1360                 :     {
    1361                 :         sprintf( szProj4+strlen(szProj4),
    1362                 :                  "+proj=aeqd +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1363                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1364                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1365                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1366               6 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1367                 :     }
    1368                 : 
    1369              26 :     else if( EQUAL(pszProjection,SRS_PT_EQUIDISTANT_CONIC) )
    1370                 :     {
    1371                 :         sprintf( szProj4+strlen(szProj4),
    1372                 :                  "+proj=eqdc +lat_0=%.16g +lon_0=%.16g +lat_1=%.16g +lat_2=%.16g"
    1373                 :                  " +x_0=%.16g +y_0=%.16g ",
    1374                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0),
    1375                 :                  GetNormProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0),
    1376                 :                  GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0),
    1377                 :                  GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0),
    1378                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1379               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1380                 :     }
    1381                 : 
    1382              26 :     else if( EQUAL(pszProjection,SRS_PT_MILLER_CYLINDRICAL) )
    1383                 :     {
    1384                 :         sprintf( szProj4+strlen(szProj4),
    1385                 :                 "+proj=mill +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g +R_A ",
    1386                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1387                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1388                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1389               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1390                 :     }
    1391                 : 
    1392              26 :     else if( EQUAL(pszProjection,SRS_PT_MOLLWEIDE) )
    1393                 :     {
    1394                 :         sprintf( szProj4+strlen(szProj4),
    1395                 :                  "+proj=moll +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1396                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1397                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1398               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1399                 :     }
    1400                 : 
    1401              26 :     else if( EQUAL(pszProjection,SRS_PT_ECKERT_I) )
    1402                 :     {
    1403                 :         sprintf( szProj4+strlen(szProj4),
    1404                 :                  "+proj=eck1 +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1405                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1406                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1407               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1408                 :     }
    1409                 : 
    1410              26 :     else if( EQUAL(pszProjection,SRS_PT_ECKERT_II) )
    1411                 :     {
    1412                 :         sprintf( szProj4+strlen(szProj4),
    1413                 :                  "+proj=eck2 +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1414                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1415                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1416               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1417                 :     }
    1418                 : 
    1419              26 :     else if( EQUAL(pszProjection,SRS_PT_ECKERT_III) )
    1420                 :     {
    1421                 :         sprintf( szProj4+strlen(szProj4),
    1422                 :                  "+proj=eck3 +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1423                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1424                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1425               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1426                 :     }
    1427                 :     
    1428              26 :     else if( EQUAL(pszProjection,SRS_PT_ECKERT_IV) )
    1429                 :     {
    1430                 :         sprintf( szProj4+strlen(szProj4),
    1431                 :                  "+proj=eck4 +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1432                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1433                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1434               6 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1435                 :     }
    1436                 :     
    1437              20 :     else if( EQUAL(pszProjection,SRS_PT_ECKERT_V) )
    1438                 :     {
    1439                 :         sprintf( szProj4+strlen(szProj4),
    1440                 :                  "+proj=eck5 +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1441                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1442                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1443               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1444                 :     }
    1445                 :     
    1446              20 :     else if( EQUAL(pszProjection,SRS_PT_ECKERT_VI) )
    1447                 :     {
    1448                 :         sprintf( szProj4+strlen(szProj4),
    1449                 :                  "+proj=eck6 +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1450                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1451                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1452               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1453                 :     }
    1454                 : 
    1455              20 :     else if( EQUAL(pszProjection,SRS_PT_POLYCONIC) )
    1456                 :     {
    1457                 :         sprintf( szProj4+strlen(szProj4),
    1458                 :                  "+proj=poly +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1459                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1460                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1461                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1462               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1463                 :     }
    1464                 : 
    1465              20 :     else if( EQUAL(pszProjection,SRS_PT_ALBERS_CONIC_EQUAL_AREA) )
    1466                 :     {
    1467                 :         sprintf( szProj4+strlen(szProj4),
    1468                 :                  "+proj=aea +lat_1=%.16g +lat_2=%.16g +lat_0=%.16g +lon_0=%.16g"
    1469                 :                  " +x_0=%.16g +y_0=%.16g ",
    1470                 :                  GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0),
    1471                 :                  GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0),
    1472                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1473                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1474                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1475               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1476                 :     }
    1477                 : 
    1478              20 :     else if( EQUAL(pszProjection,SRS_PT_ROBINSON) )
    1479                 :     {
    1480                 :         sprintf( szProj4+strlen(szProj4),
    1481                 :                  "+proj=robin +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1482                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1483                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1484               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1485                 :     }
    1486                 : 
    1487              20 :     else if( EQUAL(pszProjection,SRS_PT_VANDERGRINTEN) )
    1488                 :     {
    1489                 :         sprintf( szProj4+strlen(szProj4),
    1490                 :                  "+proj=vandg +lon_0=%.16g +x_0=%.16g +y_0=%.16g +R_A ",
    1491                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1492                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1493               6 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1494                 :     }
    1495                 : 
    1496              14 :     else if( EQUAL(pszProjection,SRS_PT_SINUSOIDAL) )
    1497                 :     {
    1498                 :         sprintf( szProj4+strlen(szProj4),
    1499                 :                  "+proj=sinu +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1500                 :                  GetNormProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0),
    1501                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1502               6 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1503                 :     }
    1504                 : 
    1505               8 :     else if( EQUAL(pszProjection,SRS_PT_GALL_STEREOGRAPHIC) )
    1506                 :     {
    1507                 :         sprintf( szProj4+strlen(szProj4),
    1508                 :                  "+proj=gall +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1509                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1510                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1511               1 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1512                 :     }
    1513                 : 
    1514               7 :     else if( EQUAL(pszProjection,SRS_PT_GOODE_HOMOLOSINE) )
    1515                 :     {
    1516                 :         sprintf( szProj4+strlen(szProj4),
    1517                 :                  "+proj=goode +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1518                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1519                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1520               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1521                 :     }
    1522                 : 
    1523               7 :     else if( EQUAL(pszProjection,SRS_PT_GEOSTATIONARY_SATELLITE) )
    1524                 :     {
    1525                 :         sprintf( szProj4+strlen(szProj4),
    1526                 :                  "+proj=geos +lon_0=%.16g +h=%.16g +x_0=%.16g +y_0=%.16g ",
    1527                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1528                 :                  GetNormProjParm(SRS_PP_SATELLITE_HEIGHT,35785831.0),
    1529                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1530               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1531                 :     }
    1532                 : 
    1533               8 :     else if( EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP)
    1534                 :          || EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM) )
    1535                 :     {
    1536                 :         sprintf( szProj4+strlen(szProj4),
    1537                 :                  "+proj=lcc +lat_1=%.16g +lat_2=%.16g +lat_0=%.16g +lon_0=%.16g"
    1538                 :                  " +x_0=%.16g +y_0=%.16g ",
    1539                 :                  GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0),
    1540                 :                  GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0),
    1541                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1542                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1543                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1544               1 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1545                 :     }
    1546                 :     
    1547               6 :     else if( EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP) )
    1548                 :     {
    1549                 :         sprintf( szProj4+strlen(szProj4),
    1550                 :                  "+proj=lcc +lat_1=%.16g +lat_0=%.16g +lon_0=%.16g"
    1551                 :                  " +k_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1552                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1553                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1554                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1555                 :                  GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
    1556                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1557               2 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1558                 :     }
    1559                 : 
    1560               4 :     else if( EQUAL(pszProjection,SRS_PT_HOTINE_OBLIQUE_MERCATOR) )
    1561                 :     {
    1562                 :         /* not clear how ProjParm[3] - angle from rectified to skewed grid -
    1563                 :            should be applied ... see the +not_rot flag for PROJ.4.
    1564                 :            Just ignoring for now. */
    1565                 : 
    1566                 :         /* special case for swiss oblique mercator : see bug 423 */
    1567               1 :         if( fabs(GetNormProjParm(SRS_PP_AZIMUTH,0.0) - 90.0) < 0.0001 
    1568                 :             && fabs(GetNormProjParm(SRS_PP_RECTIFIED_GRID_ANGLE,0.0)-90.0) < 0.0001 )
    1569                 :         {
    1570                 :             sprintf( szProj4+strlen(szProj4),
    1571                 :                      "+proj=somerc +lat_0=%.16g +lon_0=%.16g"
    1572                 :                      " +k_0=%.16g +x_0=%.16g +y_0=%.16g ",
    1573                 :                      GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1574                 :                      GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1575                 :                      GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
    1576                 :                      GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1577               1 :                      GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1578                 :         }
    1579                 :         else
    1580                 :         {
    1581                 :             sprintf( szProj4+strlen(szProj4),
    1582                 :                      "+proj=omerc +lat_0=%.16g +lonc=%.16g +alpha=%.16g"
    1583                 :                      " +k=%.16g +x_0=%.16g +y_0=%.16g ",
    1584                 :                      GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1585                 :                      GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1586                 :                      GetNormProjParm(SRS_PP_AZIMUTH,0.0),
    1587                 :                      GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
    1588                 :                      GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1589               0 :                      GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1590                 :         }
    1591                 :     }
    1592                 : 
    1593               3 :     else if( EQUAL(pszProjection,
    1594                 :                    SRS_PT_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN) )
    1595                 :     {
    1596                 :         sprintf( szProj4+strlen(szProj4),
    1597                 :                  "+proj=omerc +lat_0=%.16g"
    1598                 :                  " +lon_1=%.16g +lat_1=%.16g +lon_2=%.16g +lat_2=%.16g"
    1599                 :                  " +k=%.16g +x_0=%.16g +y_0=%.16g ",
    1600                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1601                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_POINT_1,0.0),
    1602                 :                  GetNormProjParm(SRS_PP_LONGITUDE_OF_POINT_1,0.0),
    1603                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_POINT_2,0.0),
    1604                 :                  GetNormProjParm(SRS_PP_LONGITUDE_OF_POINT_2,0.0),
    1605                 :                  GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
    1606                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1607               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1608                 :     }
    1609                 : 
    1610               3 :     else if( EQUAL(pszProjection,SRS_PT_KROVAK) )
    1611                 :     {
    1612                 :         sprintf( szProj4+strlen(szProj4),
    1613                 :                  "+proj=krovak +lat_0=%.16g +lon_0=%.16g +alpha=%.16g"
    1614                 :                  " +k=%.16g +x_0=%.16g +y_0=%.16g ",
    1615                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0),
    1616                 :                  GetNormProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0),
    1617                 :                  GetNormProjParm(SRS_PP_AZIMUTH,0.0),
    1618                 :                  GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
    1619                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1620               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1621                 :     }
    1622                 : 
    1623               3 :     else if( EQUAL(pszProjection,SRS_PT_TWO_POINT_EQUIDISTANT) )
    1624                 :     {
    1625                 :         sprintf( szProj4+strlen(szProj4),
    1626                 :                  "+proj=tpeqd +lat_1=%.16g +lon_1=%.16g "
    1627                 :                  "+lat_2=%.16g +lon_2=%.16g "
    1628                 :                  "+x_0=%.16g +y_0=%.16g ",
    1629                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_1ST_POINT,0.0),
    1630                 :                  GetNormProjParm(SRS_PP_LONGITUDE_OF_1ST_POINT,0.0),
    1631                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_2ND_POINT,0.0),
    1632                 :                  GetNormProjParm(SRS_PP_LONGITUDE_OF_2ND_POINT,0.0),
    1633                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1634               2 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1635                 :     }
    1636                 : 
    1637               1 :     else if( EQUAL(pszProjection, SRS_PT_IMW_POLYCONIC) )
    1638                 :     {
    1639                 :         sprintf( szProj4+strlen(szProj4),
    1640                 :                  "+proj=iwm_p +lat_1=%.16g +lat_2=%.16g +lon_0=%.16g "
    1641                 :                  "+x_0=%.16g +y_0=%.16g ",
    1642                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_1ST_POINT, 0.0),
    1643                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_2ND_POINT, 0.0),
    1644                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0),
    1645                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
    1646               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
    1647                 :     }
    1648                 : 
    1649               1 :     else if( EQUAL(pszProjection, SRS_PT_WAGNER_I) )
    1650                 :     {
    1651                 :         sprintf( szProj4+strlen(szProj4),
    1652                 :                  "+proj=wag1 +x_0=%.16g +y_0=%.16g ",
    1653                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
    1654               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
    1655                 :     }
    1656                 : 
    1657               1 :     else if( EQUAL(pszProjection, SRS_PT_WAGNER_II) )
    1658                 :     {
    1659                 :         sprintf( szProj4+strlen(szProj4),
    1660                 :                  "+proj=wag2 +x_0=%.16g +y_0=%.16g ",
    1661                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
    1662               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
    1663                 :     }
    1664                 : 
    1665               1 :     else if( EQUAL(pszProjection, SRS_PT_WAGNER_III) )
    1666                 :     {
    1667                 :         sprintf( szProj4+strlen(szProj4),
    1668                 :                  "+proj=wag3 +lat_ts=%.16g +x_0=%.16g +y_0=%.16g ",
    1669                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0),
    1670                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
    1671               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
    1672                 :     }
    1673                 : 
    1674               1 :     else if( EQUAL(pszProjection, SRS_PT_WAGNER_IV) )
    1675                 :     {
    1676                 :         sprintf( szProj4+strlen(szProj4),
    1677                 :                  "+proj=wag4 +x_0=%.16g +y_0=%.16g ",
    1678                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
    1679               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
    1680                 :     }
    1681                 : 
    1682               1 :     else if( EQUAL(pszProjection, SRS_PT_WAGNER_V) )
    1683                 :     {
    1684                 :         sprintf( szProj4+strlen(szProj4),
    1685                 :                  "+proj=wag5 +x_0=%.16g +y_0=%.16g ",
    1686                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
    1687               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
    1688                 :     }
    1689                 : 
    1690               1 :     else if( EQUAL(pszProjection, SRS_PT_WAGNER_VI) )
    1691                 :     {
    1692                 :         sprintf( szProj4+strlen(szProj4),
    1693                 :                  "+proj=wag6 +x_0=%.16g +y_0=%.16g ",
    1694                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
    1695               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
    1696                 :     }
    1697                 : 
    1698               1 :     else if( EQUAL(pszProjection, SRS_PT_WAGNER_VII) )
    1699                 :     {
    1700                 :         sprintf( szProj4+strlen(szProj4),
    1701                 :                  "+proj=wag7 +x_0=%.16g +y_0=%.16g ",
    1702                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
    1703               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
    1704                 :     }
    1705                 : 
    1706                 :     /* Note: This never really gets used currently.  See bug 423 */
    1707               1 :     else if( EQUAL(pszProjection,SRS_PT_SWISS_OBLIQUE_CYLINDRICAL) )
    1708                 :     {
    1709                 :         sprintf( szProj4+strlen(szProj4),
    1710                 :                  "+proj=somerc +lat_0=%.16g +lon_0=%.16g"
    1711                 :                  " +x_0=%.16g +y_0=%.16g ",
    1712                 :                  GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
    1713                 :                  GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
    1714                 :                  GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
    1715               0 :                  GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
    1716                 :     }
    1717                 : 
    1718                 :     else
    1719                 :     {
    1720                 :         CPLError( CE_Failure, CPLE_NotSupported,
    1721                 :                   "No translation for %s to PROJ.4 format is known.", 
    1722               1 :                   pszProjection );
    1723               1 :         *ppszProj4 = CPLStrdup("");
    1724               1 :         return OGRERR_UNSUPPORTED_SRS;
    1725                 :     }
    1726                 : 
    1727                 : /* -------------------------------------------------------------------- */
    1728                 : /*      Handle earth model.  For now we just always emit the user       */
    1729                 : /*      defined ellipsoid parameters.                                   */
    1730                 : /* -------------------------------------------------------------------- */
    1731             299 :     double      dfSemiMajor = GetSemiMajor();
    1732             299 :     double      dfInvFlattening = GetInvFlattening();
    1733             299 :     const char  *pszPROJ4Ellipse = NULL;
    1734             299 :     const char  *pszDatum = GetAttrValue("DATUM");
    1735                 : 
    1736             299 :     if( ABS(dfSemiMajor-6378249.145) < 0.01
    1737                 :         && ABS(dfInvFlattening-293.465) < 0.0001 )
    1738                 :     {
    1739               0 :         pszPROJ4Ellipse = "clrk80";     /* Clark 1880 */
    1740                 :     }
    1741             299 :     else if( ABS(dfSemiMajor-6378245.0) < 0.01
    1742                 :              && ABS(dfInvFlattening-298.3) < 0.0001 )
    1743                 :     {
    1744               0 :         pszPROJ4Ellipse = "krass";      /* Krassovsky */
    1745                 :     }
    1746             303 :     else if( ABS(dfSemiMajor-6378388.0) < 0.01
    1747                 :              && ABS(dfInvFlattening-297.0) < 0.0001 )
    1748                 :     {
    1749               4 :         pszPROJ4Ellipse = "intl";       /* International 1924 */
    1750                 :     }
    1751             295 :     else if( ABS(dfSemiMajor-6378160.0) < 0.01
    1752                 :              && ABS(dfInvFlattening-298.25) < 0.0001 )
    1753                 :     {
    1754               0 :         pszPROJ4Ellipse = "aust_SA";    /* Australian */
    1755                 :     }
    1756             295 :     else if( ABS(dfSemiMajor-6377397.155) < 0.01
    1757                 :              && ABS(dfInvFlattening-299.1528128) < 0.0001 )
    1758                 :     {
    1759               0 :         pszPROJ4Ellipse = "bessel";     /* Bessel 1841 */
    1760                 :     }
    1761             295 :     else if( ABS(dfSemiMajor-6377483.865) < 0.01
    1762                 :              && ABS(dfInvFlattening-299.1528128) < 0.0001 )
    1763                 :     {
    1764               0 :         pszPROJ4Ellipse = "bess_nam";   /* Bessel 1841 (Namibia / Schwarzeck)*/
    1765                 :     }
    1766             296 :     else if( ABS(dfSemiMajor-6378160.0) < 0.01
    1767                 :              && ABS(dfInvFlattening-298.247167427) < 0.0001 )
    1768                 :     {
    1769               1 :         pszPROJ4Ellipse = "GRS67";      /* GRS 1967 */
    1770                 :     }
    1771             303 :     else if( ABS(dfSemiMajor-6378137) < 0.01
    1772                 :              && ABS(dfInvFlattening-298.257222101) < 0.000001 )
    1773                 :     {
    1774               9 :         pszPROJ4Ellipse = "GRS80";      /* GRS 1980 */
    1775                 :     }
    1776             329 :     else if( ABS(dfSemiMajor-6378206.4) < 0.01
    1777                 :              && ABS(dfInvFlattening-294.9786982) < 0.0001 )
    1778                 :     {
    1779              44 :         pszPROJ4Ellipse = "clrk66";     /* Clarke 1866 */
    1780                 :     }
    1781             241 :     else if( ABS(dfSemiMajor-6377340.189) < 0.01
    1782                 :              && ABS(dfInvFlattening-299.3249646) < 0.0001 )
    1783                 :     {
    1784               0 :         pszPROJ4Ellipse = "mod_airy";   /* Modified Airy */
    1785                 :     }
    1786             244 :     else if( ABS(dfSemiMajor-6377563.396) < 0.01
    1787                 :              && ABS(dfInvFlattening-299.3249646) < 0.0001 )
    1788                 :     {
    1789               3 :         pszPROJ4Ellipse = "airy";       /* Airy */
    1790                 :     }
    1791             238 :     else if( ABS(dfSemiMajor-6378200) < 0.01
    1792                 :              && ABS(dfInvFlattening-298.3) < 0.0001 )
    1793                 :     {
    1794               0 :         pszPROJ4Ellipse = "helmert";    /* Helmert 1906 */
    1795                 :     }
    1796             238 :     else if( ABS(dfSemiMajor-6378155) < 0.01
    1797                 :              && ABS(dfInvFlattening-298.3) < 0.0001 )
    1798                 :     {
    1799               0 :         pszPROJ4Ellipse = "fschr60m";   /* Modified Fischer 1960 */
    1800                 :     }
    1801             238 :     else if( ABS(dfSemiMajor-6377298.556) < 0.01
    1802                 :              && ABS(dfInvFlattening-300.8017) < 0.0001 )
    1803                 :     {
    1804               0 :         pszPROJ4Ellipse = "evrstSS";    /* Everest (Sabah & Sarawak) */
    1805                 :     }
    1806             238 :     else if( ABS(dfSemiMajor-6378165.0) < 0.01
    1807                 :              && ABS(dfInvFlattening-298.3) < 0.0001 )
    1808                 :     {
    1809               0 :         pszPROJ4Ellipse = "WGS60";      
    1810                 :     }
    1811             238 :     else if( ABS(dfSemiMajor-6378145.0) < 0.01
    1812                 :              && ABS(dfInvFlattening-298.25) < 0.0001 )
    1813                 :     {
    1814               0 :         pszPROJ4Ellipse = "WGS66";      
    1815                 :     }
    1816             239 :     else if( ABS(dfSemiMajor-6378135.0) < 0.01
    1817                 :              && ABS(dfInvFlattening-298.26) < 0.0001 )
    1818                 :     {
    1819               1 :         pszPROJ4Ellipse = "WGS72";      
    1820                 :     }
    1821             458 :     else if( ABS(dfSemiMajor-6378137.0) < 0.01
    1822                 :              && ABS(dfInvFlattening-298.257223563) < 0.000001 )
    1823                 :     {
    1824             221 :         pszPROJ4Ellipse = "WGS84";
    1825                 :     }
    1826              16 :     else if( EQUAL(pszDatum,"North_American_Datum_1927") )
    1827                 :     {
    1828                 : //        pszPROJ4Ellipse = "clrk66:+datum=nad27"; /* NAD 27 */
    1829               0 :         pszPROJ4Ellipse = "clrk66";
    1830                 :     }
    1831              16 :     else if( EQUAL(pszDatum,"North_American_Datum_1983") )
    1832                 :     {
    1833                 : //        pszPROJ4Ellipse = "GRS80:+datum=nad83";       /* NAD 83 */
    1834               0 :         pszPROJ4Ellipse = "GRS80";
    1835                 :     }
    1836                 :     
    1837             299 :     if( pszPROJ4Ellipse == NULL )
    1838                 :         sprintf( szProj4+strlen(szProj4), "+a=%.16g +b=%.16g ",
    1839              16 :                  GetSemiMajor(), GetSemiMinor() );
    1840                 :     else
    1841                 :         sprintf( szProj4+strlen(szProj4), "+ellps=%s ",
    1842             283 :                  pszPROJ4Ellipse );
    1843                 : 
    1844                 : /* -------------------------------------------------------------------- */
    1845                 : /*      Translate the datum.                                            */
    1846                 : /* -------------------------------------------------------------------- */
    1847             299 :     const char *pszPROJ4Datum = NULL;
    1848             299 :     const OGR_SRSNode *poTOWGS84 = GetAttrNode( "TOWGS84" );
    1849                 :     char  szTOWGS84[256];
    1850             299 :     int nEPSGDatum = -1;
    1851                 :     const char *pszAuthority;
    1852             299 :     int nEPSGGeogCS = -1;
    1853                 :     const char *pszGeogCSAuthority;
    1854                 : 
    1855             299 :     pszAuthority = GetAuthorityName( "DATUM" );
    1856                 : 
    1857             299 :     if( pszAuthority != NULL && EQUAL(pszAuthority,"EPSG") )
    1858             233 :         nEPSGDatum = atoi(GetAuthorityCode( "DATUM" ));
    1859                 : 
    1860             299 :     pszGeogCSAuthority = GetAuthorityName( "GEOGCS" );
    1861                 : 
    1862             299 :     if( pszGeogCSAuthority != NULL && EQUAL(pszGeogCSAuthority,"EPSG") )
    1863             239 :         nEPSGGeogCS = atoi(GetAuthorityCode( "GEOGCS" ));
    1864                 : 
    1865             299 :     if( pszDatum == NULL )
    1866                 :         /* nothing */;
    1867                 : 
    1868             339 :     else if( EQUAL(pszDatum,SRS_DN_NAD27) || nEPSGDatum == 6267 )
    1869              40 :         pszPROJ4Datum = "+datum=NAD27";
    1870                 : 
    1871             262 :     else if( EQUAL(pszDatum,SRS_DN_NAD83) || nEPSGDatum == 6269 )
    1872               3 :         pszPROJ4Datum = "+datum=NAD83";
    1873                 : 
    1874             446 :     else if( EQUAL(pszDatum,SRS_DN_WGS84) || nEPSGDatum == 6326 )
    1875             190 :         pszPROJ4Datum = "+datum=WGS84";
    1876                 : 
    1877              66 :     else if( (pszPROJ4Datum = OGRGetProj4Datum(pszDatum, nEPSGDatum)) != NULL )
    1878                 :     {
    1879               3 :         strcat( szProj4, "+datum=" );
    1880                 :         /* The datum name contained in pszPROJ4Datum will be appended below */
    1881                 :     }
    1882                 : 
    1883              63 :     else if( poTOWGS84 != NULL )
    1884                 :     {
    1885              10 :         int bOverflow = FALSE;
    1886                 :         int iChild;
    1887              80 :         for(iChild=0;iChild<poTOWGS84->GetChildCount() && !bOverflow;iChild++)
    1888                 :         {
    1889              70 :             if (strlen(poTOWGS84->GetChild(iChild)->GetValue()) > 24)
    1890               0 :                 bOverflow = TRUE;
    1891                 :         }
    1892                 :         
    1893              10 :         if( !bOverflow && poTOWGS84->GetChildCount() > 2
    1894                 :             && (poTOWGS84->GetChildCount() < 6 
    1895                 :                 || (EQUAL(poTOWGS84->GetChild(3)->GetValue(),"")
    1896                 :                 && EQUAL(poTOWGS84->GetChild(4)->GetValue(),"")
    1897                 :                 && EQUAL(poTOWGS84->GetChild(5)->GetValue(),"")
    1898                 :                 && EQUAL(poTOWGS84->GetChild(6)->GetValue(),""))) )
    1899                 :         {
    1900                 :             sprintf( szTOWGS84, "+towgs84=%s,%s,%s",
    1901                 :                      poTOWGS84->GetChild(0)->GetValue(),
    1902                 :                      poTOWGS84->GetChild(1)->GetValue(),
    1903               0 :                      poTOWGS84->GetChild(2)->GetValue() );
    1904               0 :             pszPROJ4Datum = szTOWGS84;
    1905                 :         }
    1906              10 :         else if( !bOverflow && poTOWGS84->GetChildCount() > 6)
    1907                 :         {
    1908                 :             sprintf( szTOWGS84, "+towgs84=%s,%s,%s,%s,%s,%s,%s",
    1909                 :                      poTOWGS84->GetChild(0)->GetValue(),
    1910                 :                      poTOWGS84->GetChild(1)->GetValue(),
    1911                 :                      poTOWGS84->GetChild(2)->GetValue(),
    1912                 :                      poTOWGS84->GetChild(3)->GetValue(),
    1913                 :                      poTOWGS84->GetChild(4)->GetValue(),
    1914                 :                      poTOWGS84->GetChild(5)->GetValue(),
    1915              10 :                      poTOWGS84->GetChild(6)->GetValue() );
    1916              10 :             pszPROJ4Datum = szTOWGS84;
    1917                 :         }
    1918                 :     }
    1919                 : 
    1920              53 :     else if( nEPSGGeogCS != -1 )
    1921                 :     {
    1922                 :         double padfTransform[7];
    1923               5 :         if( EPSGGetWGS84Transform( nEPSGGeogCS, padfTransform ) )
    1924                 :         {
    1925                 :             sprintf( szTOWGS84, "+towgs84=%.16g,%.16g,%.16g,%.16g,%.16g,%.16g,%.16g",
    1926                 :                      padfTransform[0],
    1927                 :                      padfTransform[1],
    1928                 :                      padfTransform[2],
    1929                 :                      padfTransform[3],
    1930                 :                      padfTransform[4],
    1931                 :                      padfTransform[5],
    1932               0 :                      padfTransform[6] );
    1933               0 :             pszPROJ4Datum = szTOWGS84;
    1934                 :         }
    1935                 :     }
    1936                 :     
    1937             299 :     if( pszPROJ4Datum != NULL )
    1938                 :     {
    1939             246 :         strcat( szProj4, pszPROJ4Datum );
    1940             246 :         strcat( szProj4, " " );
    1941                 :     }
    1942                 : 
    1943                 : /* -------------------------------------------------------------------- */
    1944                 : /*      Is there prime meridian info to apply?                          */
    1945                 : /* -------------------------------------------------------------------- */
    1946             299 :     if( poPRIMEM != NULL && poPRIMEM->GetChildCount() >= 2 
    1947                 :         && CPLAtof(poPRIMEM->GetChild(1)->GetValue()) != 0.0 )
    1948                 :     {
    1949               6 :         const char *pszAuthority = GetAuthorityName( "PRIMEM" );
    1950                 :         char szPMValue[128];
    1951               6 :         int  nCode = -1;
    1952                 : 
    1953               6 :         if( pszAuthority != NULL && EQUAL(pszAuthority,"EPSG") )
    1954               5 :             nCode = atoi(GetAuthorityCode( "PRIMEM" ));
    1955                 : 
    1956               6 :         switch( nCode )
    1957                 :         {
    1958                 :           case 8902:
    1959               0 :             strcpy( szPMValue, "lisbon" );
    1960               0 :             break;
    1961                 : 
    1962                 :           case 8903:
    1963               1 :             strcpy( szPMValue, "paris" );
    1964               1 :             break;
    1965                 : 
    1966                 :           case 8904:
    1967               0 :             strcpy( szPMValue, "bogota" );
    1968               0 :             break;
    1969                 : 
    1970                 :           case 8905:
    1971               0 :             strcpy( szPMValue, "madrid" );
    1972               0 :             break;
    1973                 : 
    1974                 :           case 8906:
    1975               2 :             strcpy( szPMValue, "rome" );
    1976               2 :             break;
    1977                 : 
    1978                 :           case 8907:
    1979               0 :             strcpy( szPMValue, "bern" );
    1980               0 :             break;
    1981                 : 
    1982                 :           case 8908:
    1983               0 :             strcpy( szPMValue, "jakarta" );
    1984               0 :             break;
    1985                 : 
    1986                 :           case 8909:
    1987               0 :             strcpy( szPMValue, "ferro" );
    1988               0 :             break;
    1989                 : 
    1990                 :           case 8910:
    1991               0 :             strcpy( szPMValue, "brussels" );
    1992               0 :             break;
    1993                 : 
    1994                 :           case 8911:
    1995               0 :             strcpy( szPMValue, "stockholm" );
    1996               0 :             break;
    1997                 : 
    1998                 :           case 8912:
    1999               0 :             strcpy( szPMValue, "athens" );
    2000               0 :             break;
    2001                 : 
    2002                 :           case 8913:
    2003               2 :             strcpy( szPMValue, "oslo" );
    2004               2 :             break;
    2005                 : 
    2006                 :           default:
    2007               1 :             sprintf( szPMValue, "%.16g", dfFromGreenwich );
    2008                 :         }
    2009                 : 
    2010               6 :         sprintf( szProj4+strlen(szProj4), "+pm=%s ", szPMValue );
    2011                 :     }
    2012                 :     
    2013                 : /* -------------------------------------------------------------------- */
    2014                 : /*      Handle linear units.                                            */
    2015                 : /* -------------------------------------------------------------------- */
    2016             299 :     const char  *pszPROJ4Units=NULL;
    2017             299 :     char        *pszLinearUnits = NULL;
    2018                 :     double      dfLinearConv;
    2019                 : 
    2020             299 :     dfLinearConv = GetLinearUnits( &pszLinearUnits );
    2021                 :         
    2022             299 :     if( strstr(szProj4,"longlat") != NULL )
    2023             151 :         pszPROJ4Units = NULL;
    2024                 :     
    2025             148 :     else if( dfLinearConv == 1.0 )
    2026             147 :         pszPROJ4Units = "m";
    2027                 : 
    2028               1 :     else if( dfLinearConv == 1000.0 )
    2029               0 :         pszPROJ4Units = "km";
    2030                 :     
    2031               1 :     else if( dfLinearConv == 0.0254 )
    2032               0 :         pszPROJ4Units = "in";
    2033                 :     
    2034               1 :     else if( EQUAL(pszLinearUnits,SRS_UL_FOOT) 
    2035                 :              || fabs(dfLinearConv - atof(SRS_UL_FOOT_CONV)) < 0.000000001 )
    2036               0 :         pszPROJ4Units = "ft";
    2037                 :     
    2038               1 :     else if( EQUAL(pszLinearUnits,"IYARD") || dfLinearConv == 0.9144 )
    2039               0 :         pszPROJ4Units = "yd";
    2040                 :     
    2041               1 :     else if( dfLinearConv == 0.001 )
    2042               0 :         pszPROJ4Units = "mm";
    2043                 :     
    2044               1 :     else if( dfLinearConv == 0.01 )
    2045               0 :         pszPROJ4Units = "cm";
    2046                 : 
    2047               2 :     else if( EQUAL(pszLinearUnits,SRS_UL_US_FOOT) 
    2048                 :              || fabs(dfLinearConv - atof(SRS_UL_US_FOOT_CONV)) < 0.00000001 )
    2049               1 :         pszPROJ4Units = "us-ft";
    2050                 : 
    2051               0 :     else if( EQUAL(pszLinearUnits,SRS_UL_NAUTICAL_MILE) )
    2052               0 :         pszPROJ4Units = "kmi";
    2053                 : 
    2054               0 :     else if( EQUAL(pszLinearUnits,"Mile") 
    2055                 :              || EQUAL(pszLinearUnits,"IMILE") )
    2056               0 :         pszPROJ4Units = "mi";
    2057                 : 
    2058                 :     else
    2059                 :     {
    2060                 :         sprintf( szProj4+strlen(szProj4), "+to_meter=%.16g ",
    2061               0 :                  dfLinearConv );
    2062                 :     }
    2063                 : 
    2064             299 :     if( pszPROJ4Units != NULL )
    2065                 :         sprintf( szProj4+strlen(szProj4), "+units=%s ",
    2066             148 :                  pszPROJ4Units );
    2067                 : 
    2068                 : /* -------------------------------------------------------------------- */
    2069                 : /*      Add the no_defs flag to ensure that no values from              */
    2070                 : /*      proj_def.dat are implicitly used with our definitions.          */
    2071                 : /* -------------------------------------------------------------------- */
    2072             299 :     sprintf( szProj4+strlen(szProj4), "+no_defs " );
    2073                 :     
    2074             299 :     *ppszProj4 = CPLStrdup( szProj4 );
    2075                 : 
    2076             299 :     return OGRERR_NONE;
    2077                 : }
    2078                 : 

Generated by: LCOV version 1.7