LTP GCOV extension - code coverage report
Current view: directory - ogr - ogr_srs_proj4.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 568
Code covered: 75.5 % Executed lines: 429

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

Generated by: LTP GCOV extension version 1.5