1 : /******************************************************************************
2 : * $Id: ogr_srs_proj4.cpp 25229 2012-11-16 19:06:58Z 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 25229 2012-11-16 19:06:58Z 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 345 : static const char* OGRGetProj4Datum(const char* pszDatum,
134 : int nEPSGDatum)
135 : {
136 : unsigned int i;
137 2747 : for(i=0;i<sizeof(ogr_pj_datums)/sizeof(ogr_pj_datums[0]);i++)
138 : {
139 2409 : if (nEPSGDatum == ogr_pj_datums[i].nGCS ||
140 : EQUAL(pszDatum, ogr_pj_datums[i].pszOGR))
141 : {
142 7 : return ogr_pj_datums[i].pszPJ;
143 : }
144 : }
145 338 : return NULL;
146 : }
147 :
148 7 : static const OGRProj4PM* OGRGetProj4PMFromProj4Name(const char* pszProj4PMName)
149 : {
150 : unsigned int i;
151 46 : for(i=0;i<sizeof(ogr_pj_pms)/sizeof(ogr_pj_pms[0]);i++)
152 : {
153 45 : if (EQUAL(pszProj4PMName, ogr_pj_pms[i].pszProj4PMName))
154 : {
155 6 : return &ogr_pj_pms[i];
156 : }
157 : }
158 1 : return NULL;
159 : }
160 :
161 7 : static const OGRProj4PM* OGRGetProj4PMFromCode(int nPMCode)
162 : {
163 : unsigned int i;
164 40 : for(i=0;i<sizeof(ogr_pj_pms)/sizeof(ogr_pj_pms[0]);i++)
165 : {
166 40 : if (nPMCode == ogr_pj_pms[i].nPMCode)
167 : {
168 7 : return &ogr_pj_pms[i];
169 : }
170 : }
171 0 : return NULL;
172 : }
173 :
174 1 : static const OGRProj4PM* OGRGetProj4PMFromVal(double dfVal)
175 : {
176 : unsigned int i;
177 3 : for(i=0;i<sizeof(ogr_pj_pms)/sizeof(ogr_pj_pms[0]);i++)
178 : {
179 3 : if (fabs(dfVal - CPLDMSToDec(ogr_pj_pms[i].pszFromGreenwich)) < 1e-10)
180 : {
181 1 : return &ogr_pj_pms[i];
182 : }
183 : }
184 0 : 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 141 : char **OSRProj4Tokenize( const char *pszFull )
196 :
197 : {
198 141 : char *pszStart = NULL;
199 : char *pszFullWrk;
200 141 : char **papszTokens = NULL;
201 : int i;
202 :
203 141 : if( pszFull == NULL )
204 0 : return NULL;
205 :
206 141 : pszFullWrk = CPLStrdup( pszFull );
207 :
208 10824 : for( i=0; pszFullWrk[i] != '\0'; i++ )
209 : {
210 10683 : switch( pszFullWrk[i] )
211 : {
212 : case '+':
213 934 : if( i == 0 || pszFullWrk[i-1] == '\0' )
214 : {
215 933 : if( pszStart != NULL )
216 : {
217 794 : if( strstr(pszStart,"=") != NULL )
218 770 : papszTokens = CSLAddString( papszTokens, pszStart );
219 : else
220 : {
221 24 : CPLString osAsBoolean = pszStart;
222 24 : osAsBoolean += "=yes";
223 24 : papszTokens = CSLAddString( papszTokens, osAsBoolean );
224 : }
225 : }
226 933 : pszStart = pszFullWrk + i + 1;
227 : }
228 934 : break;
229 :
230 : case ' ':
231 : case '\t':
232 : case '\n':
233 923 : pszFullWrk[i] = '\0';
234 : break;
235 :
236 : default:
237 : break;
238 : }
239 : }
240 :
241 141 : if( pszStart != NULL && strlen(pszStart) > 0 )
242 139 : papszTokens = CSLAddString( papszTokens, pszStart );
243 :
244 141 : CPLFree( pszFullWrk );
245 :
246 141 : 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 73 : OGRErr OSRImportFromProj4( OGRSpatialReferenceH hSRS, const char *pszProj4 )
259 :
260 : {
261 73 : VALIDATE_POINTER1( hSRS, "OSRImportFromProj4", CE_Failure );
262 :
263 73 : 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 583 : static double OSR_GDV( char **papszNV, const char * pszField,
275 : double dfDefaultValue )
276 :
277 : {
278 : const char * pszValue;
279 :
280 583 : pszValue = CSLFetchNameValue( papszNV, pszField );
281 :
282 : // special hack to use k_0 if available.
283 583 : if( pszValue == NULL && EQUAL(pszField,"k") )
284 9 : pszValue = CSLFetchNameValue( papszNV, "k_0" );
285 :
286 583 : if( pszValue == NULL )
287 72 : return dfDefaultValue;
288 : else
289 511 : 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 : * Special processing for 'etmerc' (GDAL >= 1.10 ): if +proj=etmerc is found
337 : * in the passed string, the SRS built will use the WKT representation for a
338 : * standard Transverse Mercator, but will aso include a PROJ4 EXTENSION node to
339 : * preserve the etmerc projection method.
340 : *
341 : * For example:
342 : * "+proj=etmerc +lat_0=0 +lon_0=9 +k=0.9996 +units=m +x_0=500000 +datum=WGS84"
343 : *
344 : * will be translated as :
345 : * \code
346 : * PROJCS["unnamed",
347 : * GEOGCS["WGS 84",
348 : * DATUM["WGS_1984",
349 : * SPHEROID["WGS 84",6378137,298.257223563,
350 : * AUTHORITY["EPSG","7030"]],
351 : * TOWGS84[0,0,0,0,0,0,0],
352 : * AUTHORITY["EPSG","6326"]],
353 : * PRIMEM["Greenwich",0,
354 : * AUTHORITY["EPSG","8901"]],
355 : * UNIT["degree",0.0174532925199433,
356 : * AUTHORITY["EPSG","9108"]],
357 : * AUTHORITY["EPSG","4326"]],
358 : * PROJECTION["Transverse_Mercator"],
359 : * PARAMETER["latitude_of_origin",0],
360 : * PARAMETER["central_meridian",9],
361 : * PARAMETER["scale_factor",0.9996],
362 : * PARAMETER["false_easting",500000],
363 : * PARAMETER["false_northing",0],
364 : * UNIT["Meter",1],
365 : * EXTENSION["PROJ4","+proj=etmerc +lat_0=0 +lon_0=9 +k=0.9996 +units=m +x_0=500000 +datum=WGS84 +nodefs"]]
366 : * \endcode
367 : *
368 : * This method is the equivalent of the C function OSRImportFromProj4().
369 : *
370 : * @param pszProj4 the PROJ.4 style string.
371 : *
372 : * @return OGRERR_NONE on success or OGRERR_CORRUPT_DATA on failure.
373 : */
374 :
375 141 : OGRErr OGRSpatialReference::importFromProj4( const char * pszProj4 )
376 :
377 : {
378 141 : char **papszNV = NULL;
379 : char **papszTokens;
380 : int i;
381 : char *pszCleanCopy;
382 141 : int bAddProj4Extension = FALSE;
383 :
384 : /* -------------------------------------------------------------------- */
385 : /* Clear any existing definition. */
386 : /* -------------------------------------------------------------------- */
387 141 : Clear();
388 :
389 : /* -------------------------------------------------------------------- */
390 : /* Strip any newlines or other "funny" stuff that might occur */
391 : /* if this string just came from reading a file. */
392 : /* -------------------------------------------------------------------- */
393 141 : pszCleanCopy = CPLStrdup( pszProj4 );
394 9085 : for( i = 0; pszCleanCopy[i] != '\0'; i++ )
395 : {
396 26832 : if( pszCleanCopy[i] == 10
397 8944 : || pszCleanCopy[i] == 13
398 8944 : || pszCleanCopy[i] == 9 )
399 0 : pszCleanCopy[i] = ' ';
400 : }
401 :
402 : /* -------------------------------------------------------------------- */
403 : /* Try to normalize the definition. This should expand +init= */
404 : /* clauses and so forth. */
405 : /* -------------------------------------------------------------------- */
406 : char *pszNormalized;
407 :
408 141 : pszNormalized = OCTProj4Normalize( pszCleanCopy );
409 141 : CPLFree( pszCleanCopy );
410 :
411 : /* -------------------------------------------------------------------- */
412 : /* If we have an EPSG based init string, and no existing +proj */
413 : /* portion then try to normalize into into a PROJ.4 string. */
414 : /* -------------------------------------------------------------------- */
415 141 : if( strstr(pszNormalized,"init=epsg:") != NULL
416 : && strstr(pszNormalized,"proj=") == NULL )
417 : {
418 : OGRErr eErr;
419 0 : const char *pszNumber = strstr(pszNormalized,"init=epsg:") + 10;
420 :
421 0 : eErr = importFromEPSG( atoi(pszNumber) );
422 0 : if( eErr == OGRERR_NONE )
423 : {
424 0 : CPLFree( pszNormalized );
425 0 : return eErr;
426 : }
427 : }
428 :
429 : /* -------------------------------------------------------------------- */
430 : /* Parse the PROJ.4 string into a cpl_string.h style name/value */
431 : /* list. */
432 : /* -------------------------------------------------------------------- */
433 141 : papszTokens = OSRProj4Tokenize( pszNormalized );
434 141 : CPLFree( pszNormalized );
435 :
436 1074 : for( i = 0; papszTokens != NULL && papszTokens[i] != NULL; i++ )
437 : {
438 933 : char *pszEqual = strstr(papszTokens[i],"=");
439 :
440 933 : if( pszEqual == NULL )
441 40 : papszNV = CSLAddNameValue(papszNV, papszTokens[i], "" );
442 : else
443 : {
444 893 : pszEqual[0] = '\0';
445 893 : papszNV = CSLAddNameValue( papszNV, papszTokens[i], pszEqual+1 );
446 : }
447 : }
448 :
449 141 : CSLDestroy( papszTokens );
450 :
451 : /* -------------------------------------------------------------------- */
452 : /* Extract the prime meridian, if there is one set. */
453 : /* -------------------------------------------------------------------- */
454 141 : const char *pszPM = CSLFetchNameValue( papszNV, "pm" );
455 141 : double dfFromGreenwich = 0.0;
456 141 : int nPMCode = -1;
457 :
458 141 : if( pszPM != NULL )
459 : {
460 7 : const OGRProj4PM* psProj4PM = OGRGetProj4PMFromProj4Name(pszPM);
461 7 : if (psProj4PM)
462 : {
463 6 : dfFromGreenwich = CPLDMSToDec(psProj4PM->pszFromGreenwich);
464 6 : pszPM = psProj4PM->pszWKTPMName;
465 6 : nPMCode = psProj4PM->nPMCode;
466 : }
467 : else
468 : {
469 1 : dfFromGreenwich = CPLDMSToDec( pszPM );
470 1 : pszPM = "unnamed";
471 : }
472 : }
473 : else
474 134 : pszPM = "Greenwich";
475 :
476 : /* -------------------------------------------------------------------- */
477 : /* Operate on the basis of the projection name. */
478 : /* -------------------------------------------------------------------- */
479 141 : const char *pszProj = CSLFetchNameValue(papszNV,"proj");
480 :
481 141 : if( pszProj == NULL )
482 : {
483 3 : CPLDebug( "OGR_PROJ4", "Can't find +proj= in:\n%s", pszProj4 );
484 3 : CSLDestroy( papszNV );
485 3 : return OGRERR_CORRUPT_DATA;
486 : }
487 :
488 138 : else if( EQUAL(pszProj,"longlat") || EQUAL(pszProj,"latlong") )
489 : {
490 : }
491 :
492 123 : else if( EQUAL(pszProj,"geocent") )
493 : {
494 2 : SetGeocCS( "Geocentric" );
495 : }
496 :
497 121 : else if( EQUAL(pszProj,"bonne") )
498 : {
499 : SetBonne( OSR_GDV( papszNV, "lat_1", 0.0 ),
500 : OSR_GDV( papszNV, "lon_0", 0.0 ),
501 : OSR_GDV( papszNV, "x_0", 0.0 ),
502 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
503 : }
504 :
505 120 : else if( EQUAL(pszProj,"cass") )
506 : {
507 : SetCS( OSR_GDV( papszNV, "lat_0", 0.0 ),
508 : OSR_GDV( papszNV, "lon_0", 0.0 ),
509 : OSR_GDV( papszNV, "x_0", 0.0 ),
510 2 : OSR_GDV( papszNV, "y_0", 0.0 ) );
511 : }
512 :
513 118 : else if( EQUAL(pszProj,"nzmg") )
514 : {
515 : SetNZMG( OSR_GDV( papszNV, "lat_0", -41.0 ),
516 : OSR_GDV( papszNV, "lon_0", 173.0 ),
517 : OSR_GDV( papszNV, "x_0", 2510000.0 ),
518 2 : OSR_GDV( papszNV, "y_0", 6023150.0 ) );
519 : }
520 :
521 116 : else if( EQUAL(pszProj,"cea") )
522 : {
523 : SetCEA( OSR_GDV( papszNV, "lat_ts", 0.0 ),
524 : OSR_GDV( papszNV, "lon_0", 0.0 ),
525 : OSR_GDV( papszNV, "x_0", 0.0 ),
526 3 : OSR_GDV( papszNV, "y_0", 0.0 ) );
527 : }
528 :
529 113 : else if( EQUAL(pszProj,"tmerc") )
530 : {
531 6 : const char *pszAxis = CSLFetchNameValue( papszNV, "axis" );
532 :
533 11 : if( pszAxis == NULL || !EQUAL(pszAxis,"wsu") )
534 : SetTM( OSR_GDV( papszNV, "lat_0", 0.0 ),
535 : OSR_GDV( papszNV, "lon_0", 0.0 ),
536 : OSR_GDV( papszNV, "k", 1.0 ),
537 : OSR_GDV( papszNV, "x_0", 0.0 ),
538 5 : OSR_GDV( papszNV, "y_0", 0.0 ) );
539 : else
540 : SetTMSO( OSR_GDV( papszNV, "lat_0", 0.0 ),
541 : OSR_GDV( papszNV, "lon_0", 0.0 ),
542 : OSR_GDV( papszNV, "k", 1.0 ),
543 : OSR_GDV( papszNV, "x_0", 0.0 ),
544 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
545 : }
546 :
547 : /* For etmerc, we translate it into standard TM for the WKT */
548 : /* point of view, but make sure that the original proj.4 */
549 : /* definition is preserved for accurate reprojection */
550 107 : else if( EQUAL(pszProj,"etmerc") &&
551 : CSLFetchNameValue( papszNV, "axis" ) == NULL )
552 : {
553 2 : bAddProj4Extension = TRUE;
554 :
555 : SetTM( OSR_GDV( papszNV, "lat_0", 0.0 ),
556 : OSR_GDV( papszNV, "lon_0", 0.0 ),
557 : OSR_GDV( papszNV, "k", 1.0 ),
558 : OSR_GDV( papszNV, "x_0", 0.0 ),
559 2 : OSR_GDV( papszNV, "y_0", 0.0 ) );
560 : }
561 :
562 105 : else if( EQUAL(pszProj,"utm") )
563 : {
564 : SetUTM( (int) OSR_GDV( papszNV, "zone", 0.0 ),
565 13 : (int) OSR_GDV( papszNV, "south", 1.0 ) );
566 : }
567 :
568 92 : else if( EQUAL(pszProj,"merc") /* 2SP form */
569 : && OSR_GDV(papszNV, "lat_ts", 1000.0) < 999.0 )
570 : {
571 : SetMercator2SP( OSR_GDV( papszNV, "lat_ts", 0.0 ),
572 : 0.0,
573 : OSR_GDV( papszNV, "lon_0", 0.0 ),
574 : OSR_GDV( papszNV, "x_0", 0.0 ),
575 3 : OSR_GDV( papszNV, "y_0", 0.0 ) );
576 : }
577 :
578 89 : else if( EQUAL(pszProj,"merc") ) /* 1SP form */
579 : {
580 : SetMercator( 0.0,
581 : OSR_GDV( papszNV, "lon_0", 0.0 ),
582 : OSR_GDV( papszNV, "k", 1.0 ),
583 : OSR_GDV( papszNV, "x_0", 0.0 ),
584 3 : OSR_GDV( papszNV, "y_0", 0.0 ) );
585 : }
586 :
587 86 : else if( EQUAL(pszProj,"stere")
588 : && ABS(OSR_GDV( papszNV, "lat_0", 0.0 ) - 90) < 0.001 )
589 : {
590 : SetPS( OSR_GDV( papszNV, "lat_ts", 90.0 ),
591 : OSR_GDV( papszNV, "lon_0", 0.0 ),
592 : OSR_GDV( papszNV, "k", 1.0 ),
593 : OSR_GDV( papszNV, "x_0", 0.0 ),
594 4 : OSR_GDV( papszNV, "y_0", 0.0 ) );
595 : }
596 :
597 82 : else if( EQUAL(pszProj,"stere")
598 : && ABS(OSR_GDV( papszNV, "lat_0", 0.0 ) + 90) < 0.001 )
599 : {
600 : SetPS( OSR_GDV( papszNV, "lat_ts", -90.0 ),
601 : OSR_GDV( papszNV, "lon_0", 0.0 ),
602 : OSR_GDV( papszNV, "k", 1.0 ),
603 : OSR_GDV( papszNV, "x_0", 0.0 ),
604 3 : OSR_GDV( papszNV, "y_0", 0.0 ) );
605 : }
606 :
607 79 : else if( EQUAL(pszProj,"sterea") )
608 : {
609 : SetOS( OSR_GDV( papszNV, "lat_0", 0.0 ),
610 : OSR_GDV( papszNV, "lon_0", 0.0 ),
611 : OSR_GDV( papszNV, "k", 1.0 ),
612 : OSR_GDV( papszNV, "x_0", 0.0 ),
613 4 : OSR_GDV( papszNV, "y_0", 0.0 ) );
614 : }
615 :
616 75 : else if( EQUAL(pszProj,"stere") )
617 : {
618 : SetStereographic( OSR_GDV( papszNV, "lat_0", 0.0 ),
619 : OSR_GDV( papszNV, "lon_0", 0.0 ),
620 : OSR_GDV( papszNV, "k", 1.0 ),
621 : OSR_GDV( papszNV, "x_0", 0.0 ),
622 3 : OSR_GDV( papszNV, "y_0", 0.0 ) );
623 : }
624 :
625 72 : else if( EQUAL(pszProj,"eqc") )
626 : {
627 4 : if( OSR_GDV( papszNV, "lat_ts", 0.0 ) != 0.0 )
628 : SetEquirectangular2( OSR_GDV( papszNV, "lat_0", 0.0 ),
629 : OSR_GDV( papszNV, "lon_0", 0.0 ),
630 : OSR_GDV( papszNV, "lat_ts", 0.0 ),
631 : OSR_GDV( papszNV, "x_0", 0.0 ),
632 2 : OSR_GDV( papszNV, "y_0", 0.0 ) );
633 : else
634 : SetEquirectangular( OSR_GDV( papszNV, "lat_0", 0.0 ),
635 : OSR_GDV( papszNV, "lon_0", 0.0 ),
636 : OSR_GDV( papszNV, "x_0", 0.0 ),
637 2 : OSR_GDV( papszNV, "y_0", 0.0 ) );
638 : }
639 :
640 68 : else if( EQUAL(pszProj,"gstmerc") )
641 : {
642 : SetGaussSchreiberTMercator( OSR_GDV( papszNV, "lat_0", -21.116666667 ),
643 : OSR_GDV( papszNV, "lon_0", 55.53333333309),
644 : OSR_GDV( papszNV, "k_0", 1.0 ),
645 : OSR_GDV( papszNV, "x_0", 160000.000 ),
646 1 : OSR_GDV( papszNV, "y_0", 50000.000 ) );
647 : }
648 :
649 67 : else if( EQUAL(pszProj,"gnom") )
650 : {
651 : SetGnomonic( OSR_GDV( papszNV, "lat_0", 0.0 ),
652 : OSR_GDV( papszNV, "lon_0", 0.0 ),
653 : OSR_GDV( papszNV, "x_0", 0.0 ),
654 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
655 : }
656 :
657 66 : else if( EQUAL(pszProj,"ortho") )
658 : {
659 : SetOrthographic( OSR_GDV( papszNV, "lat_0", 0.0 ),
660 : OSR_GDV( papszNV, "lon_0", 0.0 ),
661 : OSR_GDV( papszNV, "x_0", 0.0 ),
662 4 : OSR_GDV( papszNV, "y_0", 0.0 ) );
663 : }
664 :
665 62 : else if( EQUAL(pszProj,"laea") )
666 : {
667 : SetLAEA( OSR_GDV( papszNV, "lat_0", 0.0 ),
668 : OSR_GDV( papszNV, "lon_0", 0.0 ),
669 : OSR_GDV( papszNV, "x_0", 0.0 ),
670 3 : OSR_GDV( papszNV, "y_0", 0.0 ) );
671 : }
672 :
673 59 : else if( EQUAL(pszProj,"aeqd") )
674 : {
675 : SetAE( OSR_GDV( papszNV, "lat_0", 0.0 ),
676 : OSR_GDV( papszNV, "lon_0", 0.0 ),
677 : OSR_GDV( papszNV, "x_0", 0.0 ),
678 5 : OSR_GDV( papszNV, "y_0", 0.0 ) );
679 : }
680 :
681 54 : else if( EQUAL(pszProj,"eqdc") )
682 : {
683 : SetEC( OSR_GDV( papszNV, "lat_1", 0.0 ),
684 : OSR_GDV( papszNV, "lat_2", 0.0 ),
685 : OSR_GDV( papszNV, "lat_0", 0.0 ),
686 : OSR_GDV( papszNV, "lon_0", 0.0 ),
687 : OSR_GDV( papszNV, "x_0", 0.0 ),
688 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
689 : }
690 :
691 53 : else if( EQUAL(pszProj,"mill") )
692 : {
693 : SetMC( OSR_GDV( papszNV, "lat_0", 0.0 ),
694 : OSR_GDV( papszNV, "lon_0", 0.0 ),
695 : OSR_GDV( papszNV, "x_0", 0.0 ),
696 2 : OSR_GDV( papszNV, "y_0", 0.0 ) );
697 : }
698 :
699 51 : else if( EQUAL(pszProj,"moll") )
700 : {
701 : SetMollweide( OSR_GDV( papszNV, "lon_0", 0.0 ),
702 : OSR_GDV( papszNV, "x_0", 0.0 ),
703 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
704 : }
705 :
706 57 : else if( EQUAL(pszProj,"eck1") || EQUAL(pszProj,"eck2") || EQUAL(pszProj,"eck3") ||
707 : EQUAL(pszProj,"eck4") || EQUAL(pszProj,"eck5") || EQUAL(pszProj,"eck6"))
708 : {
709 7 : SetEckert( pszProj[3] - '0',
710 : OSR_GDV( papszNV, "lon_0", 0.0 ),
711 : OSR_GDV( papszNV, "x_0", 0.0 ),
712 14 : OSR_GDV( papszNV, "y_0", 0.0 ) );
713 : }
714 :
715 43 : else if( EQUAL(pszProj,"poly") )
716 : {
717 : SetPolyconic( OSR_GDV( papszNV, "lat_0", 0.0 ),
718 : OSR_GDV( papszNV, "lon_0", 0.0 ),
719 : OSR_GDV( papszNV, "x_0", 0.0 ),
720 2 : OSR_GDV( papszNV, "y_0", 0.0 ) );
721 : }
722 :
723 41 : else if( EQUAL(pszProj,"aea") )
724 : {
725 : SetACEA( OSR_GDV( papszNV, "lat_1", 0.0 ),
726 : OSR_GDV( papszNV, "lat_2", 0.0 ),
727 : OSR_GDV( papszNV, "lat_0", 0.0 ),
728 : OSR_GDV( papszNV, "lon_0", 0.0 ),
729 : OSR_GDV( papszNV, "x_0", 0.0 ),
730 2 : OSR_GDV( papszNV, "y_0", 0.0 ) );
731 : }
732 :
733 39 : else if( EQUAL(pszProj,"robin") )
734 : {
735 : SetRobinson( OSR_GDV( papszNV, "lon_0", 0.0 ),
736 : OSR_GDV( papszNV, "x_0", 0.0 ),
737 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
738 : }
739 :
740 38 : else if( EQUAL(pszProj,"vandg") )
741 : {
742 : SetVDG( OSR_GDV( papszNV, "lon_0", 0.0 ),
743 : OSR_GDV( papszNV, "x_0", 0.0 ),
744 5 : OSR_GDV( papszNV, "y_0", 0.0 ) );
745 : }
746 :
747 33 : else if( EQUAL(pszProj,"sinu") )
748 : {
749 : SetSinusoidal( OSR_GDV( papszNV, "lon_0", 0.0 ),
750 : OSR_GDV( papszNV, "x_0", 0.0 ),
751 2 : OSR_GDV( papszNV, "y_0", 0.0 ) );
752 : }
753 :
754 31 : else if( EQUAL(pszProj,"gall") )
755 : {
756 : SetGS( OSR_GDV( papszNV, "lon_0", 0.0 ),
757 : OSR_GDV( papszNV, "x_0", 0.0 ),
758 2 : OSR_GDV( papszNV, "y_0", 0.0 ) );
759 : }
760 :
761 29 : else if( EQUAL(pszProj,"goode") )
762 : {
763 : SetGH( OSR_GDV( papszNV, "lon_0", 0.0 ),
764 : OSR_GDV( papszNV, "x_0", 0.0 ),
765 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
766 : }
767 :
768 28 : else if( EQUAL(pszProj,"igh") )
769 : {
770 1 : SetIGH();
771 : }
772 :
773 27 : else if( EQUAL(pszProj,"geos") )
774 : {
775 : SetGEOS( OSR_GDV( papszNV, "lon_0", 0.0 ),
776 : OSR_GDV( papszNV, "h", 35785831.0 ),
777 : OSR_GDV( papszNV, "x_0", 0.0 ),
778 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
779 : }
780 :
781 26 : else if( EQUAL(pszProj,"lcc") )
782 : {
783 8 : if( OSR_GDV(papszNV, "lat_0", 0.0 )
784 : == OSR_GDV(papszNV, "lat_1", 0.0 ) )
785 : {
786 : /* 1SP form */
787 : SetLCC1SP( OSR_GDV( papszNV, "lat_0", 0.0 ),
788 : OSR_GDV( papszNV, "lon_0", 0.0 ),
789 : OSR_GDV( papszNV, "k_0", 1.0 ),
790 : OSR_GDV( papszNV, "x_0", 0.0 ),
791 5 : OSR_GDV( papszNV, "y_0", 0.0 ) );
792 : }
793 : else
794 : {
795 : /* 2SP form */
796 : SetLCC( OSR_GDV( papszNV, "lat_1", 0.0 ),
797 : OSR_GDV( papszNV, "lat_2", 0.0 ),
798 : OSR_GDV( papszNV, "lat_0", 0.0 ),
799 : OSR_GDV( papszNV, "lon_0", 0.0 ),
800 : OSR_GDV( papszNV, "x_0", 0.0 ),
801 3 : OSR_GDV( papszNV, "y_0", 0.0 ) );
802 : }
803 : }
804 :
805 18 : else if( EQUAL(pszProj,"omerc") )
806 : {
807 2 : if( CSLFetchNameValue(papszNV,"no_uoff") != NULL
808 : || CSLFetchNameValue(papszNV,"no_off") != NULL )
809 : {
810 : SetHOM( OSR_GDV( papszNV, "lat_0", 0.0 ),
811 : OSR_GDV( papszNV, "lonc", 0.0 ),
812 : OSR_GDV( papszNV, "alpha", 0.0 ),
813 : OSR_GDV( papszNV, "gamma", 0.0 ),
814 : OSR_GDV( papszNV, "k", 1.0 ),
815 : OSR_GDV( papszNV, "x_0", 0.0 ),
816 0 : OSR_GDV( papszNV, "y_0", 0.0 ) );
817 : }
818 : else
819 : {
820 : SetHOMAC( OSR_GDV( papszNV, "lat_0", 0.0 ),
821 : OSR_GDV( papszNV, "lonc", 0.0 ),
822 : OSR_GDV( papszNV, "alpha", 0.0 ),
823 : OSR_GDV( papszNV, "gamma", 0.0 ),
824 : OSR_GDV( papszNV, "k", 1.0 ),
825 : OSR_GDV( papszNV, "x_0", 0.0 ),
826 2 : OSR_GDV( papszNV, "y_0", 0.0 ) );
827 : }
828 : }
829 :
830 16 : else if( EQUAL(pszProj,"somerc") )
831 : {
832 : SetHOMAC( OSR_GDV( papszNV, "lat_0", 0.0 ),
833 : OSR_GDV( papszNV, "lon_0", 0.0 ),
834 : 90.0, 90.0,
835 : OSR_GDV( papszNV, "k", 1.0 ),
836 : OSR_GDV( papszNV, "x_0", 0.0 ),
837 3 : OSR_GDV( papszNV, "y_0", 0.0 ) );
838 : }
839 :
840 13 : else if( EQUAL(pszProj,"krovak") )
841 : {
842 : SetKrovak( OSR_GDV( papszNV, "lat_0", 0.0 ),
843 : OSR_GDV( papszNV, "lon_0", 0.0 ),
844 : OSR_GDV( papszNV, "alpha", 0.0 ),
845 : 0.0, // pseudo_standard_parallel_1
846 : OSR_GDV( papszNV, "k", 1.0 ),
847 : OSR_GDV( papszNV, "x_0", 0.0 ),
848 2 : OSR_GDV( papszNV, "y_0", 0.0 ) );
849 : }
850 :
851 11 : else if( EQUAL(pszProj, "iwm_p") )
852 : {
853 : SetIWMPolyconic( OSR_GDV( papszNV, "lat_1", 0.0 ),
854 : OSR_GDV( papszNV, "lat_2", 0.0 ),
855 : OSR_GDV( papszNV, "lon_0", 0.0 ),
856 : OSR_GDV( papszNV, "x_0", 0.0 ),
857 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
858 : }
859 :
860 10 : else if( EQUAL(pszProj, "wag1") )
861 : {
862 : SetWagner( 1, 0.0,
863 : OSR_GDV( papszNV, "x_0", 0.0 ),
864 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
865 : }
866 :
867 9 : else if( EQUAL(pszProj, "wag2") )
868 : {
869 : SetWagner( 2, 0.0,
870 : OSR_GDV( papszNV, "x_0", 0.0 ),
871 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
872 : }
873 :
874 8 : else if( EQUAL(pszProj, "wag3") )
875 : {
876 : SetWagner( 3,
877 : OSR_GDV( papszNV, "lat_ts", 0.0 ),
878 : OSR_GDV( papszNV, "x_0", 0.0 ),
879 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
880 : }
881 :
882 7 : else if( EQUAL(pszProj, "wag4") )
883 : {
884 : SetWagner( 4, 0.0,
885 : OSR_GDV( papszNV, "x_0", 0.0 ),
886 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
887 : }
888 :
889 6 : else if( EQUAL(pszProj, "wag5") )
890 : {
891 : SetWagner( 5, 0.0,
892 : OSR_GDV( papszNV, "x_0", 0.0 ),
893 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
894 : }
895 :
896 5 : else if( EQUAL(pszProj, "wag6") )
897 : {
898 : SetWagner( 6, 0.0,
899 : OSR_GDV( papszNV, "x_0", 0.0 ),
900 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
901 : }
902 :
903 4 : else if( EQUAL(pszProj, "wag7") )
904 : {
905 : SetWagner( 7, 0.0,
906 : OSR_GDV( papszNV, "x_0", 0.0 ),
907 1 : OSR_GDV( papszNV, "y_0", 0.0 ) );
908 : }
909 :
910 3 : else if( EQUAL(pszProj,"tpeqd") )
911 : {
912 : SetTPED( OSR_GDV( papszNV, "lat_1", 0.0 ),
913 : OSR_GDV( papszNV, "lon_1", 0.0 ),
914 : OSR_GDV( papszNV, "lat_2", 0.0 ),
915 : OSR_GDV( papszNV, "lon_2", 0.0 ),
916 : OSR_GDV( papszNV, "x_0", 0.0 ),
917 2 : OSR_GDV( papszNV, "y_0", 0.0 ) );
918 : }
919 :
920 1 : else if( strstr(pszProj4,"wktext") != NULL )
921 : {
922 : // Fake out a projected coordinate system for otherwise
923 : // unrecognised projections for which we are already planning
924 : // to embed the actual PROJ.4 string via extension node.
925 0 : SetProjection( "custom_proj4" );
926 : }
927 :
928 : else
929 : {
930 1 : CPLDebug( "OGR_PROJ4", "Unsupported projection: %s", pszProj );
931 1 : CSLDestroy( papszNV );
932 1 : return OGRERR_CORRUPT_DATA;
933 : }
934 :
935 : /* -------------------------------------------------------------------- */
936 : /* Try to translate the datum. */
937 : /* -------------------------------------------------------------------- */
938 : const char *pszValue;
939 137 : int bFullyDefined = FALSE;
940 :
941 137 : pszValue = CSLFetchNameValue(papszNV, "datum");
942 137 : if( pszValue == NULL )
943 : {
944 : /* do nothing */
945 : }
946 65 : else if( (EQUAL(pszValue,"NAD27") || EQUAL(pszValue,"NAD83")
947 : || EQUAL(pszValue,"WGS84") || EQUAL(pszValue,"WGS72"))
948 : && dfFromGreenwich == 0.0 )
949 : {
950 32 : SetWellKnownGeogCS( pszValue );
951 32 : bFullyDefined = TRUE;
952 : }
953 : else
954 : {
955 : unsigned int i;
956 8 : for(i=0;i<sizeof(ogr_pj_datums)/sizeof(ogr_pj_datums[0]);i++)
957 : {
958 7 : if ( EQUAL(pszValue, ogr_pj_datums[i].pszPJ) )
959 : {
960 0 : OGRSpatialReference oGCS;
961 0 : oGCS.importFromEPSG( ogr_pj_datums[i].nEPSG );
962 0 : CopyGeogCSFrom( &oGCS );
963 0 : bFullyDefined = TRUE;
964 0 : break;
965 : }
966 : }
967 :
968 : /* If we don't recognise the datum, we ignore it */
969 : }
970 :
971 : /* -------------------------------------------------------------------- */
972 : /* Set the ellipsoid information. */
973 : /* -------------------------------------------------------------------- */
974 : double dfSemiMajor, dfInvFlattening, dfSemiMinor;
975 :
976 137 : pszValue = CSLFetchNameValue(papszNV, "ellps");
977 137 : if( pszValue != NULL && !bFullyDefined )
978 : {
979 6436 : for( i = 0; ogr_pj_ellps[i] != NULL; i += 4 )
980 : {
981 3218 : if( !EQUAL(ogr_pj_ellps[i],pszValue) )
982 3129 : continue;
983 :
984 89 : CPLAssert( EQUALN(ogr_pj_ellps[i+1],"a=",2) );
985 :
986 89 : dfSemiMajor = CPLAtof(ogr_pj_ellps[i+1]+2);
987 89 : if( EQUALN(ogr_pj_ellps[i+2],"rf=",3) )
988 85 : dfInvFlattening = CPLAtof(ogr_pj_ellps[i+2]+3);
989 : else
990 : {
991 4 : CPLAssert( EQUALN(ogr_pj_ellps[i+2],"b=",2) );
992 4 : dfSemiMinor = CPLAtof(ogr_pj_ellps[i+2]+2);
993 :
994 4 : if( ABS(dfSemiMajor/dfSemiMinor) - 1.0 < 0.0000000000001 )
995 3 : dfInvFlattening = 0.0;
996 : else
997 1 : dfInvFlattening = -1.0 / (dfSemiMinor/dfSemiMajor - 1.0);
998 : }
999 :
1000 : SetGeogCS( ogr_pj_ellps[i+3], "unknown", ogr_pj_ellps[i],
1001 : dfSemiMajor, dfInvFlattening,
1002 89 : pszPM, dfFromGreenwich );
1003 :
1004 89 : bFullyDefined = TRUE;
1005 89 : break;
1006 : }
1007 : }
1008 :
1009 137 : if( !bFullyDefined )
1010 : {
1011 16 : dfSemiMajor = OSR_GDV( papszNV, "a", 0.0 );
1012 16 : if( dfSemiMajor == 0.0 )
1013 : {
1014 2 : dfSemiMajor = OSR_GDV( papszNV, "R", 0.0 );
1015 2 : if( dfSemiMajor != 0.0 )
1016 : {
1017 0 : dfSemiMinor = -1.0;
1018 0 : dfInvFlattening = 0.0;
1019 : }
1020 : else
1021 : {
1022 : CPLDebug( "OGR_PROJ4", "Can't find ellipse definition, default to WGS84:\n%s",
1023 2 : pszProj4 );
1024 :
1025 2 : dfSemiMajor = SRS_WGS84_SEMIMAJOR;
1026 2 : dfSemiMinor = -1.0;
1027 2 : dfInvFlattening = SRS_WGS84_INVFLATTENING;
1028 : }
1029 : }
1030 : else
1031 : {
1032 14 : dfSemiMinor = OSR_GDV( papszNV, "b", -1.0 );
1033 14 : dfInvFlattening = OSR_GDV( papszNV, "rf", -1.0 );
1034 14 : if ( dfSemiMinor == -1.0 && dfInvFlattening == -1.0 )
1035 : {
1036 1 : double dfFlattening = OSR_GDV( papszNV, "f", -1.0 );
1037 1 : if ( dfFlattening == 0.0 )
1038 0 : dfSemiMinor = dfSemiMajor;
1039 1 : else if ( dfFlattening != -1.0 )
1040 0 : dfInvFlattening = 1.0 / dfFlattening;
1041 : }
1042 : }
1043 :
1044 16 : if( dfSemiMinor == -1.0 && dfInvFlattening == -1.0 )
1045 : {
1046 : CPLDebug( "OGR_PROJ4", "Can't find ellipse definition in:\n%s",
1047 1 : pszProj4 );
1048 1 : CSLDestroy( papszNV );
1049 1 : return OGRERR_UNSUPPORTED_SRS;
1050 : }
1051 :
1052 15 : if( dfInvFlattening == -1.0 )
1053 : {
1054 10 : if( ABS(dfSemiMajor/dfSemiMinor) - 1.0 < 0.0000000000001 )
1055 6 : dfInvFlattening = 0.0;
1056 : else
1057 4 : dfInvFlattening = -1.0 / (dfSemiMinor/dfSemiMajor - 1.0);
1058 : }
1059 :
1060 : SetGeogCS( "unnamed ellipse", "unknown", "unnamed",
1061 : dfSemiMajor, dfInvFlattening,
1062 15 : pszPM, dfFromGreenwich );
1063 :
1064 15 : bFullyDefined = TRUE;
1065 : }
1066 :
1067 : /* -------------------------------------------------------------------- */
1068 : /* Handle TOWGS84 conversion. */
1069 : /* -------------------------------------------------------------------- */
1070 136 : pszValue = CSLFetchNameValue(papszNV, "towgs84");
1071 136 : if(pszValue!=NULL)
1072 : {
1073 : char **papszToWGS84 = CSLTokenizeStringComplex( pszValue, ",",
1074 46 : FALSE, TRUE );
1075 :
1076 46 : if( CSLCount(papszToWGS84) >= 7 )
1077 18 : SetTOWGS84( CPLAtof(papszToWGS84[0]),
1078 18 : CPLAtof(papszToWGS84[1]),
1079 18 : CPLAtof(papszToWGS84[2]),
1080 18 : CPLAtof(papszToWGS84[3]),
1081 18 : CPLAtof(papszToWGS84[4]),
1082 18 : CPLAtof(papszToWGS84[5]),
1083 126 : CPLAtof(papszToWGS84[6]) );
1084 28 : else if( CSLCount(papszToWGS84) >= 3 )
1085 27 : SetTOWGS84( CPLAtof(papszToWGS84[0]),
1086 27 : CPLAtof(papszToWGS84[1]),
1087 81 : CPLAtof(papszToWGS84[2]) );
1088 : else
1089 : CPLError( CE_Warning, CPLE_AppDefined,
1090 : "Seemingly corrupt +towgs84 option (%s), ignoring.",
1091 1 : pszValue );
1092 :
1093 46 : CSLDestroy(papszToWGS84);
1094 : }
1095 :
1096 : /* -------------------------------------------------------------------- */
1097 : /* Handle nadgrids via an extension node. */
1098 : /* -------------------------------------------------------------------- */
1099 136 : pszValue = CSLFetchNameValue(papszNV, "nadgrids");
1100 136 : if( pszValue != NULL )
1101 : {
1102 4 : SetExtension( "DATUM", "PROJ4_GRIDS", pszValue );
1103 : }
1104 :
1105 : /* -------------------------------------------------------------------- */
1106 : /* Linear units translation */
1107 : /* -------------------------------------------------------------------- */
1108 136 : if( IsProjected() || IsLocal() || IsGeocentric() )
1109 : {
1110 122 : pszValue = CSLFetchNameValue(papszNV, "to_meter");
1111 :
1112 122 : if( pszValue != NULL && CPLAtofM(pszValue) > 0.0 )
1113 : {
1114 1 : double dfValue = CPLAtofM(pszValue);
1115 :
1116 1 : if( fabs(dfValue - CPLAtof(SRS_UL_US_FOOT_CONV)) < 0.00000001 )
1117 0 : SetLinearUnits( SRS_UL_US_FOOT, CPLAtof(SRS_UL_US_FOOT_CONV) );
1118 1 : else if( fabs(dfValue - CPLAtof(SRS_UL_FOOT_CONV)) < 0.00000001 )
1119 0 : SetLinearUnits( SRS_UL_FOOT, CPLAtof(SRS_UL_FOOT_CONV) );
1120 1 : else if( dfValue == 1.0 )
1121 0 : SetLinearUnits( SRS_UL_METER, 1.0 );
1122 : else
1123 1 : SetLinearUnits( "unknown", CPLAtofM(pszValue) );
1124 : }
1125 121 : else if( (pszValue = CSLFetchNameValue(papszNV, "units")) != NULL )
1126 : {
1127 101 : if( EQUAL(pszValue,"meter" ) || EQUAL(pszValue,"m") || EQUAL(pszValue,"metre") )
1128 48 : SetLinearUnits( SRS_UL_METER, 1.0 );
1129 5 : else if( EQUAL(pszValue,"km") )
1130 0 : SetLinearUnits( "kilometre", 1000.0 );
1131 5 : else if( EQUAL(pszValue,"us-ft" ) )
1132 2 : SetLinearUnits( SRS_UL_US_FOOT, CPLAtof(SRS_UL_US_FOOT_CONV) );
1133 3 : else if( EQUAL(pszValue,"ft" ) )
1134 1 : SetLinearUnits( SRS_UL_FOOT, CPLAtof(SRS_UL_FOOT_CONV) );
1135 2 : else if( EQUAL(pszValue,"yd" ) )
1136 1 : SetLinearUnits( pszValue, 0.9144 );
1137 1 : else if( EQUAL(pszValue,"us-yd" ) )
1138 1 : SetLinearUnits( pszValue, 0.914401828803658 );
1139 : else // This case is untranslatable. Should add all proj.4 unts
1140 0 : SetLinearUnits( pszValue, 1.0 );
1141 : }
1142 : }
1143 :
1144 : /* -------------------------------------------------------------------- */
1145 : /* Adjust linear parameters into PROJCS units if the linear */
1146 : /* units are not meters. */
1147 : /* -------------------------------------------------------------------- */
1148 136 : if( GetLinearUnits() != 1.0 && IsProjected() )
1149 : {
1150 6 : OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
1151 : int i;
1152 :
1153 60 : for( i = 0; i < poPROJCS->GetChildCount(); i++ )
1154 : {
1155 54 : OGR_SRSNode *poParm = poPROJCS->GetChild(i);
1156 54 : if( !EQUAL(poParm->GetValue(),"PARAMETER")
1157 : || poParm->GetChildCount() != 2 )
1158 24 : continue;
1159 :
1160 30 : const char *pszParmName = poParm->GetChild(0)->GetValue();
1161 :
1162 30 : if( IsLinearParameter(pszParmName) )
1163 12 : SetNormProjParm(pszParmName,GetProjParm(pszParmName));
1164 : }
1165 : }
1166 :
1167 : /* -------------------------------------------------------------------- */
1168 : /* Handle geoidgrids via an extension node and COMPD_CS. */
1169 : /* -------------------------------------------------------------------- */
1170 136 : pszValue = CSLFetchNameValue(papszNV, "geoidgrids");
1171 136 : if( pszValue != NULL )
1172 : {
1173 1 : OGR_SRSNode *poHorizSRS = GetRoot()->Clone();
1174 :
1175 1 : Clear();
1176 :
1177 1 : CPLString osName = poHorizSRS->GetChild(0)->GetValue();
1178 1 : osName += " + ";
1179 1 : osName += "Unnamed Vertical Datum";
1180 :
1181 1 : SetNode( "COMPD_CS", osName );
1182 1 : GetRoot()->AddChild( poHorizSRS );
1183 :
1184 : OGR_SRSNode *poVertSRS;
1185 :
1186 1 : poVertSRS = new OGR_SRSNode( "VERT_CS" );
1187 2 : GetRoot()->AddChild( poVertSRS );
1188 1 : poVertSRS->AddChild( new OGR_SRSNode( "Unnamed" ) );
1189 :
1190 1 : CPLString osTarget = GetRoot()->GetValue();
1191 1 : osTarget += "|VERT_CS|VERT_DATUM";
1192 :
1193 1 : SetNode( osTarget, "Unnamed" );
1194 :
1195 1 : poVertSRS->GetChild(1)->AddChild( new OGR_SRSNode( "2005" ) );
1196 1 : SetExtension( osTarget, "PROJ4_GRIDS", pszValue );
1197 :
1198 1 : OGR_SRSNode *poAxis = new OGR_SRSNode( "AXIS" );
1199 :
1200 2 : poAxis->AddChild( new OGR_SRSNode( "Up" ) );
1201 1 : poAxis->AddChild( new OGR_SRSNode( "UP" ) );
1202 :
1203 1 : poVertSRS->AddChild( poAxis );
1204 : }
1205 :
1206 : /* -------------------------------------------------------------------- */
1207 : /* Handle vertical units. */
1208 : /* -------------------------------------------------------------------- */
1209 136 : if( GetRoot()->GetNode( "VERT_CS" ) != NULL )
1210 : {
1211 1 : const char *pszUnitName = NULL;
1212 1 : const char *pszUnitConv = NULL;
1213 :
1214 1 : pszValue = CSLFetchNameValue(papszNV, "vto_meter");
1215 :
1216 1 : if( pszValue != NULL && CPLAtofM(pszValue) > 0.0 )
1217 : {
1218 0 : double dfValue = CPLAtofM(pszValue);
1219 :
1220 0 : if( fabs(dfValue - CPLAtof(SRS_UL_US_FOOT_CONV)) < 0.00000001 )
1221 : {
1222 0 : pszUnitName = SRS_UL_US_FOOT;
1223 0 : pszUnitConv = SRS_UL_US_FOOT_CONV;
1224 : }
1225 0 : else if( fabs(dfValue - CPLAtof(SRS_UL_FOOT_CONV)) < 0.00000001 )
1226 : {
1227 0 : pszUnitName = SRS_UL_FOOT;
1228 0 : pszUnitConv = SRS_UL_FOOT_CONV;
1229 : }
1230 0 : else if( dfValue == 1.0 )
1231 : {
1232 0 : pszUnitName = SRS_UL_METER;
1233 0 : pszUnitConv = "1.0";
1234 : }
1235 : else
1236 : {
1237 0 : pszUnitName = "unknown";
1238 0 : pszUnitConv = pszValue;
1239 : }
1240 : }
1241 1 : else if( (pszValue = CSLFetchNameValue(papszNV, "vunits")) != NULL )
1242 : {
1243 1 : if( EQUAL(pszValue,"meter" ) || EQUAL(pszValue,"m") || EQUAL(pszValue,"metre") )
1244 : {
1245 0 : pszUnitName = SRS_UL_METER;
1246 0 : pszUnitConv = "1.0";
1247 : }
1248 1 : else if( EQUAL(pszValue,"us-ft" ) )
1249 : {
1250 1 : pszUnitName = SRS_UL_US_FOOT;
1251 1 : pszUnitConv = SRS_UL_US_FOOT_CONV;
1252 : }
1253 0 : else if( EQUAL(pszValue,"ft" ) )
1254 : {
1255 0 : pszUnitName = SRS_UL_FOOT;
1256 0 : pszUnitConv = SRS_UL_FOOT_CONV;
1257 : }
1258 0 : else if( EQUAL(pszValue,"yd" ) )
1259 : {
1260 0 : pszUnitName = "Yard";
1261 0 : pszUnitConv = "0.9144";
1262 : }
1263 0 : else if( EQUAL(pszValue,"us-yd" ) )
1264 : {
1265 0 : pszUnitName = "US Yard";
1266 0 : pszUnitConv = "0.914401828803658";
1267 : }
1268 : }
1269 :
1270 1 : if( pszUnitName != NULL )
1271 : {
1272 1 : OGR_SRSNode *poVERT_CS = GetRoot()->GetNode( "VERT_CS" );
1273 : OGR_SRSNode *poUnits;
1274 :
1275 1 : poUnits = new OGR_SRSNode( "UNIT" );
1276 2 : poUnits->AddChild( new OGR_SRSNode( pszUnitName ) );
1277 2 : poUnits->AddChild( new OGR_SRSNode( pszUnitConv ) );
1278 :
1279 1 : poVERT_CS->AddChild( poUnits );
1280 : }
1281 : }
1282 :
1283 : /* -------------------------------------------------------------------- */
1284 : /* do we want to insert a PROJ.4 EXTENSION item? */
1285 : /* -------------------------------------------------------------------- */
1286 136 : if( strstr(pszProj4,"wktext") != NULL || bAddProj4Extension )
1287 2 : SetExtension( GetRoot()->GetValue(), "PROJ4", pszProj4 );
1288 :
1289 136 : CSLDestroy( papszNV );
1290 :
1291 136 : return OGRERR_NONE;
1292 : }
1293 :
1294 : /************************************************************************/
1295 : /* LinearToProj4() */
1296 : /************************************************************************/
1297 :
1298 711 : static const char *LinearToProj4( double dfLinearConv,
1299 : const char *pszLinearUnits )
1300 :
1301 : {
1302 711 : if( dfLinearConv == 1.0 )
1303 702 : return "m";
1304 :
1305 9 : else if( dfLinearConv == 1000.0 )
1306 0 : return "km";
1307 :
1308 9 : else if( dfLinearConv == 0.0254 )
1309 0 : return "in";
1310 :
1311 9 : else if( EQUAL(pszLinearUnits,SRS_UL_FOOT)
1312 : || fabs(dfLinearConv - atof(SRS_UL_FOOT_CONV)) < 0.000000001 )
1313 1 : return "ft";
1314 :
1315 8 : else if( EQUAL(pszLinearUnits,"IYARD") || dfLinearConv == 0.9144 )
1316 1 : return "yd";
1317 :
1318 7 : else if( dfLinearConv == 0.914401828803658 )
1319 1 : return "us-yd";
1320 :
1321 6 : else if( dfLinearConv == 0.001 )
1322 0 : return "mm";
1323 :
1324 6 : else if( dfLinearConv == 0.01 )
1325 0 : return "cm";
1326 :
1327 6 : else if( EQUAL(pszLinearUnits,SRS_UL_US_FOOT)
1328 : || fabs(dfLinearConv - atof(SRS_UL_US_FOOT_CONV)) < 0.00000001 )
1329 5 : return "us-ft";
1330 :
1331 1 : else if( EQUAL(pszLinearUnits,SRS_UL_NAUTICAL_MILE) )
1332 0 : return "kmi";
1333 :
1334 1 : else if( EQUAL(pszLinearUnits,"Mile")
1335 : || EQUAL(pszLinearUnits,"IMILE") )
1336 0 : return "mi";
1337 : else
1338 1 : return NULL;
1339 : }
1340 :
1341 :
1342 : /************************************************************************/
1343 : /* OSRExportToProj4() */
1344 : /************************************************************************/
1345 : /**
1346 : * \brief Export coordinate system in PROJ.4 format.
1347 : *
1348 : * This function is the same as OGRSpatialReference::exportToProj4().
1349 : */
1350 126 : OGRErr CPL_STDCALL OSRExportToProj4( OGRSpatialReferenceH hSRS,
1351 : char ** ppszReturn )
1352 :
1353 : {
1354 126 : VALIDATE_POINTER1( hSRS, "OSRExportToProj4", CE_Failure );
1355 :
1356 126 : *ppszReturn = NULL;
1357 :
1358 126 : return ((OGRSpatialReference *) hSRS)->exportToProj4( ppszReturn );
1359 : }
1360 :
1361 : /************************************************************************/
1362 : /* exportToProj4() */
1363 : /************************************************************************/
1364 :
1365 : #define SAFE_PROJ4_STRCAT(szNewStr) do { \
1366 : if(CPLStrlcat(szProj4, szNewStr, sizeof(szProj4)) >= sizeof(szProj4)) { \
1367 : CPLError(CE_Failure, CPLE_AppDefined, "String overflow when formatting proj.4 string"); \
1368 : *ppszProj4 = CPLStrdup(""); \
1369 : return OGRERR_FAILURE; \
1370 : } } while(0);
1371 :
1372 : /**
1373 : * \brief Export coordinate system in PROJ.4 format.
1374 : *
1375 : * Converts the loaded coordinate reference system into PROJ.4 format
1376 : * to the extent possible. The string returned in ppszProj4 should be
1377 : * deallocated by the caller with CPLFree() when no longer needed.
1378 : *
1379 : * LOCAL_CS coordinate systems are not translatable. An empty string
1380 : * will be returned along with OGRERR_NONE.
1381 : *
1382 : * Special processing for Transverse Mercator with GDAL >= 1.10 and PROJ >= 4.8 :
1383 : * if the OSR_USE_ETMERC configuration option is set to YES, the PROJ.4
1384 : * definition built from the SRS will use the 'etmerc' projection method,
1385 : * rather than the default 'tmerc'. This will give better accuracy (at the
1386 : * expense of computational speed) when reprojection occurs near the edges
1387 : * of the validity area for the projection.
1388 : *
1389 : * This method is the equivelent of the C function OSRExportToProj4().
1390 : *
1391 : * @param ppszProj4 pointer to which dynamically allocated PROJ.4 definition
1392 : * will be assigned.
1393 : *
1394 : * @return OGRERR_NONE on success or an error code on failure.
1395 : */
1396 :
1397 1463 : OGRErr OGRSpatialReference::exportToProj4( char ** ppszProj4 ) const
1398 :
1399 : {
1400 : char szProj4[512];
1401 1463 : const char *pszProjection = GetAttrValue("PROJECTION");
1402 1463 : CPLLocaleC oLocaleEnforcer;
1403 :
1404 1463 : szProj4[0] = '\0';
1405 :
1406 1463 : if( GetRoot() == NULL )
1407 : {
1408 1 : *ppszProj4 = CPLStrdup("");
1409 : CPLError( CE_Failure, CPLE_NotSupported,
1410 1 : "No translation for an empty SRS to PROJ.4 format is known.");
1411 1 : return OGRERR_UNSUPPORTED_SRS;
1412 : }
1413 :
1414 : /* -------------------------------------------------------------------- */
1415 : /* Do we have a PROJ.4 override definition? */
1416 : /* -------------------------------------------------------------------- */
1417 : const char *pszPredefProj4 = GetExtension( GetRoot()->GetValue(),
1418 1462 : "PROJ4", NULL );
1419 1462 : if( pszPredefProj4 != NULL )
1420 : {
1421 18 : *ppszProj4 = CPLStrdup( pszPredefProj4 );
1422 18 : return OGRERR_NONE;
1423 : }
1424 :
1425 : /* -------------------------------------------------------------------- */
1426 : /* Get the prime meridian info. */
1427 : /* -------------------------------------------------------------------- */
1428 1444 : const OGR_SRSNode *poPRIMEM = GetAttrNode( "PRIMEM" );
1429 1444 : double dfFromGreenwich = 0.0;
1430 :
1431 1444 : if( poPRIMEM != NULL && poPRIMEM->GetChildCount() >= 2
1432 : && CPLAtof(poPRIMEM->GetChild(1)->GetValue()) != 0.0 )
1433 : {
1434 8 : dfFromGreenwich = CPLAtof(poPRIMEM->GetChild(1)->GetValue());
1435 : }
1436 :
1437 : /* ==================================================================== */
1438 : /* Handle the projection definition. */
1439 : /* ==================================================================== */
1440 :
1441 1444 : if( pszProjection == NULL && IsGeographic() )
1442 : {
1443 735 : sprintf( szProj4+strlen(szProj4), "+proj=longlat " );
1444 : }
1445 709 : else if( IsGeocentric() )
1446 : {
1447 3 : sprintf( szProj4+strlen(szProj4), "+proj=geocent " );
1448 : }
1449 :
1450 706 : else if( pszProjection == NULL && !IsGeographic() )
1451 : {
1452 : // LOCAL_CS, or incompletely initialized coordinate systems.
1453 0 : *ppszProj4 = CPLStrdup("");
1454 0 : return OGRERR_NONE;
1455 : }
1456 706 : else if( EQUAL(pszProjection,SRS_PT_CYLINDRICAL_EQUAL_AREA) )
1457 : {
1458 : sprintf( szProj4+strlen(szProj4),
1459 : "+proj=cea +lon_0=%.16g +lat_ts=%.16g +x_0=%.16g +y_0=%.16g ",
1460 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1461 : GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0),
1462 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1463 6 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1464 : }
1465 :
1466 700 : else if( EQUAL(pszProjection,SRS_PT_BONNE) )
1467 : {
1468 : sprintf( szProj4+strlen(szProj4),
1469 : "+proj=bonne +lon_0=%.16g +lat_1=%.16g +x_0=%.16g +y_0=%.16g ",
1470 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1471 : GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0),
1472 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1473 3 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1474 : }
1475 :
1476 697 : else if( EQUAL(pszProjection,SRS_PT_CASSINI_SOLDNER) )
1477 : {
1478 : sprintf( szProj4+strlen(szProj4),
1479 : "+proj=cass +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1480 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1481 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1482 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1483 2 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1484 : }
1485 :
1486 695 : else if( EQUAL(pszProjection,SRS_PT_NEW_ZEALAND_MAP_GRID) )
1487 : {
1488 : sprintf( szProj4+strlen(szProj4),
1489 : "+proj=nzmg +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1490 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1491 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1492 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1493 2 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1494 : }
1495 :
1496 1214 : else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR) ||
1497 : EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_21) ||
1498 : EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_22) ||
1499 : EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_23) ||
1500 : EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_24) ||
1501 : EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_25) )
1502 : {
1503 : int bNorth;
1504 521 : int nZone = GetUTMZone( &bNorth );
1505 :
1506 521 : if( CSLTestBoolean(CPLGetConfigOption("OSR_USE_ETMERC", "FALSE")) )
1507 : {
1508 : sprintf( szProj4+strlen(szProj4),
1509 : "+proj=etmerc +lat_0=%.16g +lon_0=%.16g +k=%.16g +x_0=%.16g +y_0=%.16g ",
1510 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1511 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1512 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1513 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1514 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1515 : }
1516 520 : else if( nZone != 0 )
1517 : {
1518 508 : if( bNorth )
1519 : sprintf( szProj4+strlen(szProj4), "+proj=utm +zone=%d ",
1520 501 : nZone );
1521 : else
1522 : sprintf( szProj4+strlen(szProj4),"+proj=utm +zone=%d +south ",
1523 7 : nZone );
1524 : }
1525 : else
1526 : sprintf( szProj4+strlen(szProj4),
1527 : "+proj=tmerc +lat_0=%.16g +lon_0=%.16g +k=%.16g +x_0=%.16g +y_0=%.16g ",
1528 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1529 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1530 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1531 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1532 12 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1533 : }
1534 :
1535 172 : else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_SOUTH_ORIENTED) )
1536 : {
1537 : sprintf( szProj4+strlen(szProj4),
1538 : "+proj=tmerc +lat_0=%.16g +lon_0=%.16g +k=%.16g +x_0=%.16g +y_0=%.16g +axis=wsu ",
1539 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1540 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1541 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1542 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1543 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1544 : }
1545 :
1546 171 : else if( EQUAL(pszProjection,SRS_PT_MERCATOR_1SP) )
1547 : {
1548 11 : if( GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0) == 0.0 )
1549 : sprintf( szProj4+strlen(szProj4),
1550 : "+proj=merc +lon_0=%.16g +k=%.16g +x_0=%.16g +y_0=%.16g ",
1551 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1552 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1553 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1554 8 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1555 3 : else if( GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0) == 1.0 )
1556 : sprintf( szProj4+strlen(szProj4),
1557 : "+proj=merc +lon_0=%.16g +lat_ts=%.16g +x_0=%.16g +y_0=%.16g ",
1558 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1559 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1560 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1561 3 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1562 : else
1563 : {
1564 : CPLError( CE_Failure, CPLE_NotSupported,
1565 0 : "Mercator_1SP with scale != 1.0 and latitude of origin != 0, not supported by PROJ.4." );
1566 0 : *ppszProj4 = CPLStrdup("");
1567 0 : return OGRERR_UNSUPPORTED_SRS;
1568 : }
1569 : }
1570 :
1571 160 : else if( EQUAL(pszProjection,SRS_PT_MERCATOR_2SP) )
1572 : {
1573 : sprintf( szProj4+strlen(szProj4),
1574 : "+proj=merc +lon_0=%.16g +lat_ts=%.16g +x_0=%.16g +y_0=%.16g ",
1575 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1576 : GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0),
1577 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1578 10 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1579 : }
1580 :
1581 150 : else if( EQUAL(pszProjection,SRS_PT_OBLIQUE_STEREOGRAPHIC) )
1582 : {
1583 : sprintf( szProj4+strlen(szProj4),
1584 : "+proj=sterea +lat_0=%.16g +lon_0=%.16g +k=%.16g +x_0=%.16g +y_0=%.16g ",
1585 : // "+proj=stere +lat_0=%.16g +lon_0=%.16g +k=%.16g +x_0=%.16g +y_0=%.16g ",
1586 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1587 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1588 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1589 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1590 10 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1591 : }
1592 :
1593 140 : else if( EQUAL(pszProjection,SRS_PT_STEREOGRAPHIC) )
1594 : {
1595 : sprintf( szProj4+strlen(szProj4),
1596 : "+proj=stere +lat_0=%.16g +lon_0=%.16g +k=%.16g +x_0=%.16g +y_0=%.16g ",
1597 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1598 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1599 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1600 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1601 8 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1602 : }
1603 :
1604 132 : else if( EQUAL(pszProjection,SRS_PT_POLAR_STEREOGRAPHIC) )
1605 : {
1606 12 : if( GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0) >= 0.0 )
1607 : sprintf( szProj4+strlen(szProj4),
1608 : "+proj=stere +lat_0=90 +lat_ts=%.16g +lon_0=%.16g "
1609 : "+k=%.16g +x_0=%.16g +y_0=%.16g ",
1610 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,90.0),
1611 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1612 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1613 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1614 6 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1615 : else
1616 : sprintf( szProj4+strlen(szProj4),
1617 : "+proj=stere +lat_0=-90 +lat_ts=%.16g +lon_0=%.16g "
1618 : "+k=%.16g +x_0=%.16g +y_0=%.16g ",
1619 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,-90.0),
1620 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1621 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1622 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1623 6 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1624 : }
1625 :
1626 120 : else if( EQUAL(pszProjection,SRS_PT_EQUIRECTANGULAR) )
1627 : {
1628 : sprintf( szProj4+strlen(szProj4),
1629 : "+proj=eqc +lat_ts=%.16g +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1630 : GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0),
1631 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1632 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1633 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1634 4 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1635 : }
1636 :
1637 116 : else if( EQUAL(pszProjection,SRS_PT_GAUSSSCHREIBERTMERCATOR) )
1638 : {
1639 : sprintf( szProj4+strlen(szProj4),
1640 : "+proj=gstmerc +lat_0=%.16g +lon_0=%.16g"
1641 : " +k_0=%.16g +x_0=%.16g +y_0=%.16g ",
1642 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,-21.116666667),
1643 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,55.53333333309),
1644 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1645 : GetNormProjParm(SRS_PP_FALSE_EASTING,160000.000),
1646 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING,50000.000) );
1647 : }
1648 :
1649 115 : else if( EQUAL(pszProjection,SRS_PT_GNOMONIC) )
1650 : {
1651 : sprintf( szProj4+strlen(szProj4),
1652 : "+proj=gnom +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1653 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1654 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1655 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1656 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1657 : }
1658 :
1659 114 : else if( EQUAL(pszProjection,SRS_PT_ORTHOGRAPHIC) )
1660 : {
1661 : sprintf( szProj4+strlen(szProj4),
1662 : "+proj=ortho +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1663 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1664 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1665 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1666 9 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1667 : }
1668 :
1669 105 : else if( EQUAL(pszProjection,SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA) )
1670 : {
1671 : sprintf( szProj4+strlen(szProj4),
1672 : "+proj=laea +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1673 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1674 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1675 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1676 6 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1677 : }
1678 :
1679 99 : else if( EQUAL(pszProjection,SRS_PT_AZIMUTHAL_EQUIDISTANT) )
1680 : {
1681 : sprintf( szProj4+strlen(szProj4),
1682 : "+proj=aeqd +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1683 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1684 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1685 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1686 13 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1687 : }
1688 :
1689 86 : else if( EQUAL(pszProjection,SRS_PT_EQUIDISTANT_CONIC) )
1690 : {
1691 : sprintf( szProj4+strlen(szProj4),
1692 : "+proj=eqdc +lat_0=%.16g +lon_0=%.16g +lat_1=%.16g +lat_2=%.16g"
1693 : " +x_0=%.16g +y_0=%.16g ",
1694 : GetNormProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0),
1695 : GetNormProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0),
1696 : GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0),
1697 : GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0),
1698 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1699 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1700 : }
1701 :
1702 85 : else if( EQUAL(pszProjection,SRS_PT_MILLER_CYLINDRICAL) )
1703 : {
1704 : sprintf( szProj4+strlen(szProj4),
1705 : "+proj=mill +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g +R_A ",
1706 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1707 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1708 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1709 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1710 : }
1711 :
1712 84 : else if( EQUAL(pszProjection,SRS_PT_MOLLWEIDE) )
1713 : {
1714 : sprintf( szProj4+strlen(szProj4),
1715 : "+proj=moll +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1716 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1717 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1718 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1719 : }
1720 :
1721 83 : else if( EQUAL(pszProjection,SRS_PT_ECKERT_I) )
1722 : {
1723 : sprintf( szProj4+strlen(szProj4),
1724 : "+proj=eck1 +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1725 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1726 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1727 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1728 : }
1729 :
1730 82 : else if( EQUAL(pszProjection,SRS_PT_ECKERT_II) )
1731 : {
1732 : sprintf( szProj4+strlen(szProj4),
1733 : "+proj=eck2 +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1734 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1735 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1736 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1737 : }
1738 :
1739 81 : else if( EQUAL(pszProjection,SRS_PT_ECKERT_III) )
1740 : {
1741 : sprintf( szProj4+strlen(szProj4),
1742 : "+proj=eck3 +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1743 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1744 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1745 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1746 : }
1747 :
1748 80 : else if( EQUAL(pszProjection,SRS_PT_ECKERT_IV) )
1749 : {
1750 : sprintf( szProj4+strlen(szProj4),
1751 : "+proj=eck4 +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1752 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1753 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1754 7 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1755 : }
1756 :
1757 73 : else if( EQUAL(pszProjection,SRS_PT_ECKERT_V) )
1758 : {
1759 : sprintf( szProj4+strlen(szProj4),
1760 : "+proj=eck5 +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1761 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1762 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1763 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1764 : }
1765 :
1766 72 : else if( EQUAL(pszProjection,SRS_PT_ECKERT_VI) )
1767 : {
1768 : sprintf( szProj4+strlen(szProj4),
1769 : "+proj=eck6 +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1770 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1771 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1772 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1773 : }
1774 :
1775 71 : else if( EQUAL(pszProjection,SRS_PT_POLYCONIC) )
1776 : {
1777 : sprintf( szProj4+strlen(szProj4),
1778 : "+proj=poly +lat_0=%.16g +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1779 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1780 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1781 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1782 2 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1783 : }
1784 :
1785 69 : else if( EQUAL(pszProjection,SRS_PT_ALBERS_CONIC_EQUAL_AREA) )
1786 : {
1787 : sprintf( szProj4+strlen(szProj4),
1788 : "+proj=aea +lat_1=%.16g +lat_2=%.16g +lat_0=%.16g +lon_0=%.16g"
1789 : " +x_0=%.16g +y_0=%.16g ",
1790 : GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0),
1791 : GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0),
1792 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1793 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1794 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1795 6 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1796 : }
1797 :
1798 63 : else if( EQUAL(pszProjection,SRS_PT_ROBINSON) )
1799 : {
1800 : sprintf( szProj4+strlen(szProj4),
1801 : "+proj=robin +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1802 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1803 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1804 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1805 : }
1806 :
1807 62 : else if( EQUAL(pszProjection,SRS_PT_VANDERGRINTEN) )
1808 : {
1809 : sprintf( szProj4+strlen(szProj4),
1810 : "+proj=vandg +lon_0=%.16g +x_0=%.16g +y_0=%.16g +R_A ",
1811 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1812 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1813 8 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1814 : }
1815 :
1816 54 : else if( EQUAL(pszProjection,SRS_PT_SINUSOIDAL) )
1817 : {
1818 : sprintf( szProj4+strlen(szProj4),
1819 : "+proj=sinu +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1820 : GetNormProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0),
1821 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1822 7 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1823 : }
1824 :
1825 47 : else if( EQUAL(pszProjection,SRS_PT_GALL_STEREOGRAPHIC) )
1826 : {
1827 : sprintf( szProj4+strlen(szProj4),
1828 : "+proj=gall +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1829 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1830 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1831 2 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1832 : }
1833 :
1834 45 : else if( EQUAL(pszProjection,SRS_PT_GOODE_HOMOLOSINE) )
1835 : {
1836 : sprintf( szProj4+strlen(szProj4),
1837 : "+proj=goode +lon_0=%.16g +x_0=%.16g +y_0=%.16g ",
1838 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1839 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1840 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1841 : }
1842 :
1843 44 : else if( EQUAL(pszProjection,SRS_PT_IGH) )
1844 : {
1845 1 : sprintf( szProj4+strlen(szProj4), "+proj=igh " );
1846 : }
1847 :
1848 43 : else if( EQUAL(pszProjection,SRS_PT_GEOSTATIONARY_SATELLITE) )
1849 : {
1850 : sprintf( szProj4+strlen(szProj4),
1851 : "+proj=geos +lon_0=%.16g +h=%.16g +x_0=%.16g +y_0=%.16g ",
1852 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1853 : GetNormProjParm(SRS_PP_SATELLITE_HEIGHT,35785831.0),
1854 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1855 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1856 : }
1857 :
1858 60 : else if( EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP)
1859 : || EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM) )
1860 : {
1861 : sprintf( szProj4+strlen(szProj4),
1862 : "+proj=lcc +lat_1=%.16g +lat_2=%.16g +lat_0=%.16g +lon_0=%.16g"
1863 : " +x_0=%.16g +y_0=%.16g ",
1864 : GetNormProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0),
1865 : GetNormProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0),
1866 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1867 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1868 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1869 18 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1870 : }
1871 :
1872 24 : else if( EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP) )
1873 : {
1874 : sprintf( szProj4+strlen(szProj4),
1875 : "+proj=lcc +lat_1=%.16g +lat_0=%.16g +lon_0=%.16g"
1876 : " +k_0=%.16g +x_0=%.16g +y_0=%.16g ",
1877 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1878 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1879 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1880 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1881 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1882 5 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1883 : }
1884 :
1885 19 : else if( EQUAL(pszProjection,SRS_PT_HOTINE_OBLIQUE_MERCATOR) )
1886 : {
1887 : /* special case for swiss oblique mercator : see bug 423 */
1888 0 : if( fabs(GetNormProjParm(SRS_PP_AZIMUTH,0.0) - 90.0) < 0.0001
1889 : && fabs(GetNormProjParm(SRS_PP_RECTIFIED_GRID_ANGLE,0.0)-90.0) < 0.0001 )
1890 : {
1891 : sprintf( szProj4+strlen(szProj4),
1892 : "+proj=somerc +lat_0=%.16g +lon_0=%.16g"
1893 : " +k_0=%.16g +x_0=%.16g +y_0=%.16g ",
1894 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1895 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1896 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1897 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1898 0 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1899 : }
1900 : else
1901 : {
1902 : sprintf( szProj4+strlen(szProj4),
1903 : "+proj=omerc +lat_0=%.16g +lonc=%.16g +alpha=%.16g"
1904 : " +k=%.16g +x_0=%.16g +y_0=%.16g +no_uoff ",
1905 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1906 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1907 : GetNormProjParm(SRS_PP_AZIMUTH,0.0),
1908 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1909 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1910 0 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1911 :
1912 : // RSO variant - http://trac.osgeo.org/proj/ticket/62
1913 : // Note that gamma is only supported by PROJ 4.8.0 and later.
1914 0 : if( GetNormProjParm(SRS_PP_RECTIFIED_GRID_ANGLE,1000.0) != 1000.0 )
1915 : {
1916 : sprintf( szProj4+strlen(szProj4), "+gamma=%.16g ",
1917 0 : GetNormProjParm(SRS_PP_RECTIFIED_GRID_ANGLE,1000.0));
1918 : }
1919 : }
1920 : }
1921 :
1922 19 : else if( EQUAL(pszProjection,SRS_PT_HOTINE_OBLIQUE_MERCATOR_AZIMUTH_CENTER))
1923 : {
1924 : /* special case for swiss oblique mercator : see bug 423 */
1925 5 : if( fabs(GetNormProjParm(SRS_PP_AZIMUTH,0.0) - 90.0) < 0.0001
1926 : && fabs(GetNormProjParm(SRS_PP_RECTIFIED_GRID_ANGLE,0.0)-90.0) < 0.0001 )
1927 : {
1928 : sprintf( szProj4+strlen(szProj4),
1929 : "+proj=somerc +lat_0=%.16g +lon_0=%.16g"
1930 : " +k_0=%.16g +x_0=%.16g +y_0=%.16g ",
1931 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1932 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1933 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1934 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1935 3 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1936 : }
1937 : else
1938 : {
1939 : sprintf( szProj4+strlen(szProj4),
1940 : "+proj=omerc +lat_0=%.16g +lonc=%.16g +alpha=%.16g"
1941 : " +k=%.16g +x_0=%.16g +y_0=%.16g ",
1942 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1943 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
1944 : GetNormProjParm(SRS_PP_AZIMUTH,0.0),
1945 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1946 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1947 2 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1948 :
1949 : // RSO variant - http://trac.osgeo.org/proj/ticket/62
1950 : // Note that gamma is only supported by PROJ 4.8.0 and later.
1951 2 : if( GetNormProjParm(SRS_PP_RECTIFIED_GRID_ANGLE,1000.0) != 1000.0 )
1952 : {
1953 : sprintf( szProj4+strlen(szProj4), "+gamma=%.16g ",
1954 2 : GetNormProjParm(SRS_PP_RECTIFIED_GRID_ANGLE,1000.0));
1955 : }
1956 : }
1957 : }
1958 :
1959 14 : else if( EQUAL(pszProjection,
1960 : SRS_PT_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN) )
1961 : {
1962 : sprintf( szProj4+strlen(szProj4),
1963 : "+proj=omerc +lat_0=%.16g"
1964 : " +lon_1=%.16g +lat_1=%.16g +lon_2=%.16g +lat_2=%.16g"
1965 : " +k=%.16g +x_0=%.16g +y_0=%.16g ",
1966 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
1967 : GetNormProjParm(SRS_PP_LATITUDE_OF_POINT_1,0.0),
1968 : GetNormProjParm(SRS_PP_LONGITUDE_OF_POINT_1,0.0),
1969 : GetNormProjParm(SRS_PP_LATITUDE_OF_POINT_2,0.0),
1970 : GetNormProjParm(SRS_PP_LONGITUDE_OF_POINT_2,0.0),
1971 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1972 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1973 0 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1974 : }
1975 :
1976 14 : else if( EQUAL(pszProjection,SRS_PT_KROVAK) )
1977 : {
1978 : sprintf( szProj4+strlen(szProj4),
1979 : "+proj=krovak +lat_0=%.16g +lon_0=%.16g +alpha=%.16g"
1980 : " +k=%.16g +x_0=%.16g +y_0=%.16g ",
1981 : GetNormProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0),
1982 : GetNormProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0),
1983 : GetNormProjParm(SRS_PP_AZIMUTH,0.0),
1984 : GetNormProjParm(SRS_PP_SCALE_FACTOR,1.0),
1985 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
1986 2 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
1987 : }
1988 :
1989 12 : else if( EQUAL(pszProjection,SRS_PT_TWO_POINT_EQUIDISTANT) )
1990 : {
1991 : sprintf( szProj4+strlen(szProj4),
1992 : "+proj=tpeqd +lat_1=%.16g +lon_1=%.16g "
1993 : "+lat_2=%.16g +lon_2=%.16g "
1994 : "+x_0=%.16g +y_0=%.16g ",
1995 : GetNormProjParm(SRS_PP_LATITUDE_OF_1ST_POINT,0.0),
1996 : GetNormProjParm(SRS_PP_LONGITUDE_OF_1ST_POINT,0.0),
1997 : GetNormProjParm(SRS_PP_LATITUDE_OF_2ND_POINT,0.0),
1998 : GetNormProjParm(SRS_PP_LONGITUDE_OF_2ND_POINT,0.0),
1999 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
2000 3 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
2001 : }
2002 :
2003 9 : else if( EQUAL(pszProjection, SRS_PT_IMW_POLYCONIC) )
2004 : {
2005 : sprintf( szProj4+strlen(szProj4),
2006 : "+proj=iwm_p +lat_1=%.16g +lat_2=%.16g +lon_0=%.16g "
2007 : "+x_0=%.16g +y_0=%.16g ",
2008 : GetNormProjParm(SRS_PP_LATITUDE_OF_1ST_POINT, 0.0),
2009 : GetNormProjParm(SRS_PP_LATITUDE_OF_2ND_POINT, 0.0),
2010 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN, 0.0),
2011 : GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
2012 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
2013 : }
2014 :
2015 8 : else if( EQUAL(pszProjection, SRS_PT_WAGNER_I) )
2016 : {
2017 : sprintf( szProj4+strlen(szProj4),
2018 : "+proj=wag1 +x_0=%.16g +y_0=%.16g ",
2019 : GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
2020 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
2021 : }
2022 :
2023 7 : else if( EQUAL(pszProjection, SRS_PT_WAGNER_II) )
2024 : {
2025 : sprintf( szProj4+strlen(szProj4),
2026 : "+proj=wag2 +x_0=%.16g +y_0=%.16g ",
2027 : GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
2028 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
2029 : }
2030 :
2031 6 : else if( EQUAL(pszProjection, SRS_PT_WAGNER_III) )
2032 : {
2033 : sprintf( szProj4+strlen(szProj4),
2034 : "+proj=wag3 +lat_ts=%.16g +x_0=%.16g +y_0=%.16g ",
2035 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN, 0.0),
2036 : GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
2037 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
2038 : }
2039 :
2040 5 : else if( EQUAL(pszProjection, SRS_PT_WAGNER_IV) )
2041 : {
2042 : sprintf( szProj4+strlen(szProj4),
2043 : "+proj=wag4 +x_0=%.16g +y_0=%.16g ",
2044 : GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
2045 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
2046 : }
2047 :
2048 4 : else if( EQUAL(pszProjection, SRS_PT_WAGNER_V) )
2049 : {
2050 : sprintf( szProj4+strlen(szProj4),
2051 : "+proj=wag5 +x_0=%.16g +y_0=%.16g ",
2052 : GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
2053 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
2054 : }
2055 :
2056 3 : else if( EQUAL(pszProjection, SRS_PT_WAGNER_VI) )
2057 : {
2058 : sprintf( szProj4+strlen(szProj4),
2059 : "+proj=wag6 +x_0=%.16g +y_0=%.16g ",
2060 : GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
2061 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
2062 : }
2063 :
2064 2 : else if( EQUAL(pszProjection, SRS_PT_WAGNER_VII) )
2065 : {
2066 : sprintf( szProj4+strlen(szProj4),
2067 : "+proj=wag7 +x_0=%.16g +y_0=%.16g ",
2068 : GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0),
2069 1 : GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0) );
2070 : }
2071 :
2072 : /* Note: This never really gets used currently. See bug 423 */
2073 1 : else if( EQUAL(pszProjection,SRS_PT_SWISS_OBLIQUE_CYLINDRICAL) )
2074 : {
2075 : sprintf( szProj4+strlen(szProj4),
2076 : "+proj=somerc +lat_0=%.16g +lon_0=%.16g"
2077 : " +x_0=%.16g +y_0=%.16g ",
2078 : GetNormProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0),
2079 : GetNormProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0),
2080 : GetNormProjParm(SRS_PP_FALSE_EASTING,0.0),
2081 0 : GetNormProjParm(SRS_PP_FALSE_NORTHING,0.0) );
2082 : }
2083 :
2084 : else
2085 : {
2086 : CPLError( CE_Failure, CPLE_NotSupported,
2087 : "No translation for %s to PROJ.4 format is known.",
2088 1 : pszProjection );
2089 1 : *ppszProj4 = CPLStrdup("");
2090 1 : return OGRERR_UNSUPPORTED_SRS;
2091 : }
2092 :
2093 : /* -------------------------------------------------------------------- */
2094 : /* Handle earth model. For now we just always emit the user */
2095 : /* defined ellipsoid parameters. */
2096 : /* -------------------------------------------------------------------- */
2097 1443 : double dfSemiMajor = GetSemiMajor();
2098 1443 : double dfInvFlattening = GetInvFlattening();
2099 1443 : const char *pszPROJ4Ellipse = NULL;
2100 1443 : const char *pszDatum = GetAttrValue("DATUM");
2101 :
2102 1443 : if( ABS(dfSemiMajor-6378249.145) < 0.01
2103 : && ABS(dfInvFlattening-293.465) < 0.0001 )
2104 : {
2105 0 : pszPROJ4Ellipse = "clrk80"; /* Clark 1880 */
2106 : }
2107 1448 : else if( ABS(dfSemiMajor-6378245.0) < 0.01
2108 : && ABS(dfInvFlattening-298.3) < 0.0001 )
2109 : {
2110 5 : pszPROJ4Ellipse = "krass"; /* Krassovsky */
2111 : }
2112 1444 : else if( ABS(dfSemiMajor-6378388.0) < 0.01
2113 : && ABS(dfInvFlattening-297.0) < 0.0001 )
2114 : {
2115 6 : pszPROJ4Ellipse = "intl"; /* International 1924 */
2116 : }
2117 1432 : else if( ABS(dfSemiMajor-6378160.0) < 0.01
2118 : && ABS(dfInvFlattening-298.25) < 0.0001 )
2119 : {
2120 0 : pszPROJ4Ellipse = "aust_SA"; /* Australian */
2121 : }
2122 1440 : else if( ABS(dfSemiMajor-6377397.155) < 0.01
2123 : && ABS(dfInvFlattening-299.1528128) < 0.0001 )
2124 : {
2125 8 : pszPROJ4Ellipse = "bessel"; /* Bessel 1841 */
2126 : }
2127 1424 : else if( ABS(dfSemiMajor-6377483.865) < 0.01
2128 : && ABS(dfInvFlattening-299.1528128) < 0.0001 )
2129 : {
2130 0 : pszPROJ4Ellipse = "bess_nam"; /* Bessel 1841 (Namibia / Schwarzeck)*/
2131 : }
2132 1426 : else if( ABS(dfSemiMajor-6378160.0) < 0.01
2133 : && ABS(dfInvFlattening-298.247167427) < 0.0001 )
2134 : {
2135 2 : pszPROJ4Ellipse = "GRS67"; /* GRS 1967 */
2136 : }
2137 1725 : else if( ABS(dfSemiMajor-6378137) < 0.01
2138 : && ABS(dfInvFlattening-298.257222101) < 0.000001 )
2139 : {
2140 303 : pszPROJ4Ellipse = "GRS80"; /* GRS 1980 */
2141 : }
2142 1488 : else if( ABS(dfSemiMajor-6378206.4) < 0.01
2143 : && ABS(dfInvFlattening-294.9786982) < 0.0001 )
2144 : {
2145 369 : pszPROJ4Ellipse = "clrk66"; /* Clarke 1866 */
2146 : }
2147 750 : else if( ABS(dfSemiMajor-6377340.189) < 0.01
2148 : && ABS(dfInvFlattening-299.3249646) < 0.0001 )
2149 : {
2150 0 : pszPROJ4Ellipse = "mod_airy"; /* Modified Airy */
2151 : }
2152 755 : else if( ABS(dfSemiMajor-6377563.396) < 0.01
2153 : && ABS(dfInvFlattening-299.3249646) < 0.0001 )
2154 : {
2155 5 : pszPROJ4Ellipse = "airy"; /* Airy */
2156 : }
2157 745 : else if( ABS(dfSemiMajor-6378200) < 0.01
2158 : && ABS(dfInvFlattening-298.3) < 0.0001 )
2159 : {
2160 0 : pszPROJ4Ellipse = "helmert"; /* Helmert 1906 */
2161 : }
2162 745 : else if( ABS(dfSemiMajor-6378155) < 0.01
2163 : && ABS(dfInvFlattening-298.3) < 0.0001 )
2164 : {
2165 0 : pszPROJ4Ellipse = "fschr60m"; /* Modified Fischer 1960 */
2166 : }
2167 745 : else if( ABS(dfSemiMajor-6377298.556) < 0.01
2168 : && ABS(dfInvFlattening-300.8017) < 0.0001 )
2169 : {
2170 0 : pszPROJ4Ellipse = "evrstSS"; /* Everest (Sabah & Sarawak) */
2171 : }
2172 745 : else if( ABS(dfSemiMajor-6378165.0) < 0.01
2173 : && ABS(dfInvFlattening-298.3) < 0.0001 )
2174 : {
2175 0 : pszPROJ4Ellipse = "WGS60";
2176 : }
2177 745 : else if( ABS(dfSemiMajor-6378145.0) < 0.01
2178 : && ABS(dfInvFlattening-298.25) < 0.0001 )
2179 : {
2180 0 : pszPROJ4Ellipse = "WGS66";
2181 : }
2182 763 : else if( ABS(dfSemiMajor-6378135.0) < 0.01
2183 : && ABS(dfInvFlattening-298.26) < 0.0001 )
2184 : {
2185 18 : pszPROJ4Ellipse = "WGS72";
2186 : }
2187 1430 : else if( ABS(dfSemiMajor-6378137.0) < 0.01
2188 : && ABS(dfInvFlattening-298.257223563) < 0.000001 )
2189 : {
2190 703 : pszPROJ4Ellipse = "WGS84";
2191 : }
2192 24 : else if( pszDatum != NULL && EQUAL(pszDatum,"North_American_Datum_1927") )
2193 : {
2194 : // pszPROJ4Ellipse = "clrk66:+datum=nad27"; /* NAD 27 */
2195 0 : pszPROJ4Ellipse = "clrk66";
2196 : }
2197 24 : else if( pszDatum != NULL && EQUAL(pszDatum,"North_American_Datum_1983") )
2198 : {
2199 : // pszPROJ4Ellipse = "GRS80:+datum=nad83"; /* NAD 83 */
2200 0 : pszPROJ4Ellipse = "GRS80";
2201 : }
2202 :
2203 : char szEllipseDef[128];
2204 :
2205 1443 : if( pszPROJ4Ellipse == NULL )
2206 : sprintf( szEllipseDef, "+a=%.16g +b=%.16g ",
2207 24 : GetSemiMajor(), GetSemiMinor() );
2208 : else
2209 : sprintf( szEllipseDef, "+ellps=%s ",
2210 1419 : pszPROJ4Ellipse );
2211 :
2212 : /* -------------------------------------------------------------------- */
2213 : /* Translate the datum. */
2214 : /* -------------------------------------------------------------------- */
2215 1443 : const char *pszPROJ4Datum = NULL;
2216 1443 : const OGR_SRSNode *poTOWGS84 = GetAttrNode( "TOWGS84" );
2217 : char szTOWGS84[256];
2218 1443 : int nEPSGDatum = -1;
2219 : const char *pszAuthority;
2220 1443 : int nEPSGGeogCS = -1;
2221 : const char *pszGeogCSAuthority;
2222 1443 : const char *pszProj4Grids = GetExtension( "DATUM", "PROJ4_GRIDS" );
2223 :
2224 1443 : pszAuthority = GetAuthorityName( "DATUM" );
2225 :
2226 1443 : if( pszAuthority != NULL && EQUAL(pszAuthority,"EPSG") )
2227 1250 : nEPSGDatum = atoi(GetAuthorityCode( "DATUM" ));
2228 :
2229 1443 : pszGeogCSAuthority = GetAuthorityName( "GEOGCS" );
2230 :
2231 1443 : if( pszGeogCSAuthority != NULL && EQUAL(pszGeogCSAuthority,"EPSG") )
2232 1252 : nEPSGGeogCS = atoi(GetAuthorityCode( "GEOGCS" ));
2233 :
2234 1443 : if( pszDatum == NULL )
2235 : /* nothing */;
2236 :
2237 1807 : else if( EQUAL(pszDatum,SRS_DN_NAD27) || nEPSGDatum == 6267 )
2238 364 : pszPROJ4Datum = "NAD27";
2239 :
2240 1209 : else if( EQUAL(pszDatum,SRS_DN_NAD83) || nEPSGDatum == 6269 )
2241 130 : pszPROJ4Datum = "NAD83";
2242 :
2243 1553 : else if( EQUAL(pszDatum,SRS_DN_WGS84) || nEPSGDatum == 6326 )
2244 604 : pszPROJ4Datum = "WGS84";
2245 :
2246 345 : else if( (pszPROJ4Datum = OGRGetProj4Datum(pszDatum, nEPSGDatum)) != NULL )
2247 : {
2248 : /* nothing */
2249 : }
2250 :
2251 1443 : if( pszProj4Grids != NULL )
2252 : {
2253 1 : SAFE_PROJ4_STRCAT( szEllipseDef );
2254 1 : szEllipseDef[0] = '\0';
2255 1 : SAFE_PROJ4_STRCAT( "+nadgrids=" );
2256 1 : SAFE_PROJ4_STRCAT( pszProj4Grids );
2257 1 : SAFE_PROJ4_STRCAT( " " );
2258 1 : pszPROJ4Datum = NULL;
2259 : }
2260 :
2261 1443 : if( pszPROJ4Datum == NULL
2262 : || CSLTestBoolean(CPLGetConfigOption("OVERRIDE_PROJ_DATUM_WITH_TOWGS84", "YES")) )
2263 : {
2264 1443 : if( poTOWGS84 != NULL )
2265 : {
2266 : int iChild;
2267 458 : if( poTOWGS84->GetChildCount() >= 3
2268 : && (poTOWGS84->GetChildCount() < 7
2269 : || (EQUAL(poTOWGS84->GetChild(3)->GetValue(),"")
2270 : && EQUAL(poTOWGS84->GetChild(4)->GetValue(),"")
2271 : && EQUAL(poTOWGS84->GetChild(5)->GetValue(),"")
2272 : && EQUAL(poTOWGS84->GetChild(6)->GetValue(),""))) )
2273 : {
2274 0 : SAFE_PROJ4_STRCAT( szEllipseDef );
2275 0 : szEllipseDef[0] = '\0';
2276 0 : SAFE_PROJ4_STRCAT( "+towgs84=");
2277 0 : for(iChild = 0; iChild < 3; iChild ++)
2278 : {
2279 0 : if (iChild > 0 ) SAFE_PROJ4_STRCAT( "," );
2280 0 : SAFE_PROJ4_STRCAT( poTOWGS84->GetChild(iChild)->GetValue() );
2281 : }
2282 0 : SAFE_PROJ4_STRCAT( " " );
2283 0 : pszPROJ4Datum = NULL;
2284 : }
2285 458 : else if( poTOWGS84->GetChildCount() >= 7)
2286 : {
2287 458 : SAFE_PROJ4_STRCAT( szEllipseDef );
2288 458 : szEllipseDef[0] = '\0';
2289 458 : SAFE_PROJ4_STRCAT( "+towgs84=");
2290 3664 : for(iChild = 0; iChild < 7; iChild ++)
2291 : {
2292 3206 : if (iChild > 0 ) SAFE_PROJ4_STRCAT( "," );
2293 3206 : SAFE_PROJ4_STRCAT( poTOWGS84->GetChild(iChild)->GetValue() );
2294 : }
2295 458 : SAFE_PROJ4_STRCAT( " " );
2296 458 : pszPROJ4Datum = NULL;
2297 : }
2298 : }
2299 :
2300 : // If we don't know the datum, trying looking up TOWGS84 parameters
2301 : // based on the EPSG GCS code.
2302 985 : else if( nEPSGGeogCS != -1 && pszPROJ4Datum == NULL )
2303 : {
2304 : double padfTransform[7];
2305 7 : if( EPSGGetWGS84Transform( nEPSGGeogCS, padfTransform ) )
2306 : {
2307 : sprintf( szTOWGS84, "+towgs84=%.16g,%.16g,%.16g,%.16g,%.16g,%.16g,%.16g",
2308 : padfTransform[0],
2309 : padfTransform[1],
2310 : padfTransform[2],
2311 : padfTransform[3],
2312 : padfTransform[4],
2313 : padfTransform[5],
2314 0 : padfTransform[6] );
2315 0 : SAFE_PROJ4_STRCAT( szEllipseDef );
2316 0 : szEllipseDef[0] = '\0';
2317 :
2318 0 : SAFE_PROJ4_STRCAT( szTOWGS84 );
2319 0 : SAFE_PROJ4_STRCAT( " " );
2320 0 : pszPROJ4Datum = NULL;
2321 : }
2322 : }
2323 : }
2324 :
2325 1443 : if( pszPROJ4Datum != NULL )
2326 : {
2327 854 : SAFE_PROJ4_STRCAT( "+datum=" );
2328 854 : SAFE_PROJ4_STRCAT( pszPROJ4Datum );
2329 854 : SAFE_PROJ4_STRCAT( " " );
2330 : }
2331 : else // The ellipsedef may already have been appended and will now
2332 : // be empty, otherwise append now.
2333 : {
2334 589 : SAFE_PROJ4_STRCAT( szEllipseDef );
2335 589 : szEllipseDef[0] = '\0';
2336 : }
2337 :
2338 : /* -------------------------------------------------------------------- */
2339 : /* Is there prime meridian info to apply? */
2340 : /* -------------------------------------------------------------------- */
2341 1443 : if( poPRIMEM != NULL && poPRIMEM->GetChildCount() >= 2
2342 : && CPLAtof(poPRIMEM->GetChild(1)->GetValue()) != 0.0 )
2343 : {
2344 8 : const char *pszAuthority = GetAuthorityName( "PRIMEM" );
2345 : char szPMValue[128];
2346 8 : int nCode = -1;
2347 :
2348 8 : if( pszAuthority != NULL && EQUAL(pszAuthority,"EPSG") )
2349 7 : nCode = atoi(GetAuthorityCode( "PRIMEM" ));
2350 :
2351 8 : const OGRProj4PM* psProj4PM = NULL;
2352 8 : if (nCode > 0)
2353 7 : psProj4PM = OGRGetProj4PMFromCode(nCode);
2354 8 : if (psProj4PM == NULL)
2355 1 : psProj4PM = OGRGetProj4PMFromVal(dfFromGreenwich);
2356 :
2357 8 : if (psProj4PM != NULL)
2358 : {
2359 8 : strcpy( szPMValue, psProj4PM->pszProj4PMName );
2360 : }
2361 : else
2362 : {
2363 0 : sprintf( szPMValue, "%.16g", dfFromGreenwich );
2364 : }
2365 :
2366 8 : SAFE_PROJ4_STRCAT( "+pm=" );
2367 8 : SAFE_PROJ4_STRCAT( szPMValue );
2368 8 : SAFE_PROJ4_STRCAT( " " );
2369 : }
2370 :
2371 : /* -------------------------------------------------------------------- */
2372 : /* Handle linear units. */
2373 : /* -------------------------------------------------------------------- */
2374 1443 : const char *pszPROJ4Units=NULL;
2375 1443 : char *pszLinearUnits = NULL;
2376 : double dfLinearConv;
2377 :
2378 1443 : dfLinearConv = GetLinearUnits( &pszLinearUnits );
2379 :
2380 1443 : if( strstr(szProj4,"longlat") != NULL )
2381 735 : pszPROJ4Units = NULL;
2382 : else
2383 : {
2384 708 : pszPROJ4Units = LinearToProj4( dfLinearConv, pszLinearUnits );
2385 :
2386 708 : if( pszPROJ4Units == NULL )
2387 : {
2388 : char szLinearConv[128];
2389 1 : sprintf( szLinearConv, "%.16g", dfLinearConv );
2390 1 : SAFE_PROJ4_STRCAT( "+to_meter=" );
2391 1 : SAFE_PROJ4_STRCAT( szLinearConv );
2392 1 : SAFE_PROJ4_STRCAT( " " );
2393 : }
2394 : }
2395 :
2396 1443 : if( pszPROJ4Units != NULL )
2397 : {
2398 707 : SAFE_PROJ4_STRCAT( "+units=");
2399 707 : SAFE_PROJ4_STRCAT( pszPROJ4Units );
2400 707 : SAFE_PROJ4_STRCAT( " " );
2401 : }
2402 :
2403 : /* -------------------------------------------------------------------- */
2404 : /* If we have vertical datum grids, attach them to the proj.4 string.*/
2405 : /* -------------------------------------------------------------------- */
2406 1443 : const char *pszProj4Geoids = GetExtension( "VERT_DATUM", "PROJ4_GRIDS" );
2407 :
2408 1443 : if( pszProj4Geoids != NULL )
2409 : {
2410 2 : SAFE_PROJ4_STRCAT( "+geoidgrids=" );
2411 2 : SAFE_PROJ4_STRCAT( pszProj4Geoids );
2412 2 : SAFE_PROJ4_STRCAT( " " );
2413 : }
2414 :
2415 : /* -------------------------------------------------------------------- */
2416 : /* Handle vertical units, but only if we have them. */
2417 : /* -------------------------------------------------------------------- */
2418 1443 : const OGR_SRSNode *poVERT_CS = GetRoot()->GetNode( "VERT_CS" );
2419 1443 : const OGR_SRSNode *poVUNITS = NULL;
2420 :
2421 1443 : if( poVERT_CS != NULL )
2422 3 : poVUNITS = poVERT_CS->GetNode( "UNIT" );
2423 :
2424 1443 : if( poVUNITS != NULL && poVUNITS->GetChildCount() >= 2 )
2425 : {
2426 3 : pszPROJ4Units = NULL;
2427 :
2428 3 : dfLinearConv = CPLAtof( poVUNITS->GetChild(1)->GetValue() );
2429 :
2430 : pszPROJ4Units = LinearToProj4( dfLinearConv,
2431 3 : poVUNITS->GetChild(0)->GetValue() );
2432 :
2433 3 : if( pszPROJ4Units == NULL )
2434 : {
2435 : char szLinearConv[128];
2436 0 : sprintf( szLinearConv, "%.16g", dfLinearConv );
2437 0 : SAFE_PROJ4_STRCAT( "+vto_meter=" );
2438 0 : SAFE_PROJ4_STRCAT( szLinearConv );
2439 0 : SAFE_PROJ4_STRCAT( " " );
2440 : }
2441 : else
2442 : {
2443 3 : SAFE_PROJ4_STRCAT( "+vunits=");
2444 3 : SAFE_PROJ4_STRCAT( pszPROJ4Units );
2445 3 : SAFE_PROJ4_STRCAT( " " );
2446 : }
2447 : }
2448 :
2449 : /* -------------------------------------------------------------------- */
2450 : /* Add the no_defs flag to ensure that no values from */
2451 : /* proj_def.dat are implicitly used with our definitions. */
2452 : /* -------------------------------------------------------------------- */
2453 1443 : SAFE_PROJ4_STRCAT( "+no_defs " );
2454 :
2455 1443 : *ppszProj4 = CPLStrdup( szProj4 );
2456 :
2457 1443 : return OGRERR_NONE;
2458 : }
2459 :
|