1 : /******************************************************************************
2 : * $Id: ogr_srs_usgs.cpp 24243 2012-04-15 04:36:02Z warmerdam $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: OGRSpatialReference translation to/from USGS georeferencing
6 : * information (used in GCTP package).
7 : * Author: Andrey Kiselev, dron@ak4719.spb.edu
8 : *
9 : ******************************************************************************
10 : * Copyright (c) 2004, Andrey Kiselev <dron@ak4719.spb.edu>
11 : *
12 : * Permission is hereby granted, free of charge, to any person obtaining a
13 : * copy of this software and associated documentation files (the "Software"),
14 : * to deal in the Software without restriction, including without limitation
15 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 : * and/or sell copies of the Software, and to permit persons to whom the
17 : * Software is furnished to do so, subject to the following conditions:
18 : *
19 : * The above copyright notice and this permission notice shall be included
20 : * in all copies or substantial portions of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 : * DEALINGS IN THE SOFTWARE.
29 : ****************************************************************************/
30 :
31 : #include "ogr_spatialref.h"
32 : #include "ogr_p.h"
33 : #include "cpl_conv.h"
34 : #include "cpl_csv.h"
35 :
36 : CPL_CVSID("$Id: ogr_srs_usgs.cpp 24243 2012-04-15 04:36:02Z warmerdam $");
37 :
38 : /************************************************************************/
39 : /* GCTP projection codes. */
40 : /************************************************************************/
41 :
42 : #define GEO 0L // Geographic
43 : #define UTM 1L // Universal Transverse Mercator (UTM)
44 : #define SPCS 2L // State Plane Coordinates
45 : #define ALBERS 3L // Albers Conical Equal Area
46 : #define LAMCC 4L // Lambert Conformal Conic
47 : #define MERCAT 5L // Mercator
48 : #define PS 6L // Polar Stereographic
49 : #define POLYC 7L // Polyconic
50 : #define EQUIDC 8L // Equidistant Conic
51 : #define TM 9L // Transverse Mercator
52 : #define STEREO 10L // Stereographic
53 : #define LAMAZ 11L // Lambert Azimuthal Equal Area
54 : #define AZMEQD 12L // Azimuthal Equidistant
55 : #define GNOMON 13L // Gnomonic
56 : #define ORTHO 14L // Orthographic
57 : #define GVNSP 15L // General Vertical Near-Side Perspective
58 : #define SNSOID 16L // Sinusiodal
59 : #define EQRECT 17L // Equirectangular
60 : #define MILLER 18L // Miller Cylindrical
61 : #define VGRINT 19L // Van der Grinten
62 : #define HOM 20L // (Hotine) Oblique Mercator
63 : #define ROBIN 21L // Robinson
64 : #define SOM 22L // Space Oblique Mercator (SOM)
65 : #define ALASKA 23L // Alaska Conformal
66 : #define GOODE 24L // Interrupted Goode Homolosine
67 : #define MOLL 25L // Mollweide
68 : #define IMOLL 26L // Interrupted Mollweide
69 : #define HAMMER 27L // Hammer
70 : #define WAGIV 28L // Wagner IV
71 : #define WAGVII 29L // Wagner VII
72 : #define OBEQA 30L // Oblated Equal Area
73 : #define ISINUS1 31L // Integerized Sinusoidal Grid (the same as 99)
74 : #define CEA 97L // Cylindrical Equal Area (Grid corners set
75 : // in meters for EASE grid)
76 : #define BCEA 98L // Cylindrical Equal Area (Grid corners set
77 : // in DMS degs for EASE grid)
78 : #define ISINUS 99L // Integerized Sinusoidal Grid
79 : // (added by Raj Gejjagaraguppe ARC for MODIS)
80 :
81 : /************************************************************************/
82 : /* GCTP ellipsoid codes. */
83 : /************************************************************************/
84 :
85 : #define CLARKE1866 0L
86 : #define CLARKE1880 1L
87 : #define BESSEL 2L
88 : #define INTERNATIONAL1967 3L
89 : #define INTERNATIONAL1909 4L
90 : #define WGS72 5L
91 : #define EVEREST 6L
92 : #define WGS66 7L
93 : #define GRS1980 8L
94 : #define AIRY 9L
95 : #define MODIFIED_EVEREST 10L
96 : #define MODIFIED_AIRY 11L
97 : #define WGS84 12L
98 : #define SOUTHEAST_ASIA 13L
99 : #define AUSTRALIAN_NATIONAL 14L
100 : #define KRASSOVSKY 15L
101 : #define HOUGH 16L
102 : #define MERCURY1960 17L
103 : #define MODIFIED_MERCURY 18L
104 : #define SPHERE 19L
105 :
106 : /************************************************************************/
107 : /* Correspondence between GCTP and EPSG ellipsoid codes. */
108 : /************************************************************************/
109 :
110 : static const long aoEllips[] =
111 : {
112 : 7008, // Clarke, 1866 (NAD1927)
113 : 7034, // Clarke, 1880
114 : 7004, // Bessel, 1841
115 : 0,// FIXME: New International, 1967 --- skipped
116 : 7022, // International, 1924 (Hayford, 1909) XXX?
117 : 7043, // WGS, 1972
118 : 7042, // Everest, 1830
119 : 7025, // FIXME: WGS, 1966
120 : 7019, // GRS, 1980 (NAD1983)
121 : 7001, // Airy, 1830
122 : 7018, // Modified Everest
123 : 7002, // Modified Airy
124 : 7030, // WGS, 1984 (GPS)
125 : 0,// FIXME: Southeast Asia --- skipped
126 : 7003, // Australian National, 1965
127 : 7024, // Krassovsky, 1940
128 : 7053, // Hough
129 : 0,// FIXME: Mercury, 1960 --- skipped
130 : 0,// FIXME: Modified Mercury, 1968 --- skipped
131 : 7047, // Sphere, rad 6370997 m (normal sphere)
132 : 7006, // Bessel, 1841 (Namibia)
133 : 7016, // Everest (Sabah & Sarawak)
134 : 7044, // Everest, 1956
135 : 7056, // Everest, Malaysia 1969
136 : 7018, // Everest, Malay & Singapr 1948
137 : 0,// FIXME: Everest, Pakistan --- skipped
138 : 7022, // Hayford (International 1924) XXX?
139 : 7020, // Helmert 1906
140 : 7021, // Indonesian, 1974
141 : 7036, // South American, 1969
142 : 0// FIXME: WGS 60 --- skipped
143 : };
144 :
145 : #define NUMBER_OF_ELLIPSOIDS (int)(sizeof(aoEllips)/sizeof(aoEllips[0]))
146 :
147 : /************************************************************************/
148 : /* OSRImportFromUSGS() */
149 : /************************************************************************/
150 :
151 : /**
152 : * \brief Import coordinate system from USGS projection definition.
153 : *
154 : * This function is the same as OGRSpatialReference::importFromUSGS().
155 : */
156 1 : OGRErr OSRImportFromUSGS( OGRSpatialReferenceH hSRS, long iProjsys,
157 : long iZone, double *padfPrjParams, long iDatum )
158 :
159 : {
160 1 : VALIDATE_POINTER1( hSRS, "OSRImportFromUSGS", CE_Failure );
161 :
162 : return ((OGRSpatialReference *) hSRS)->importFromUSGS( iProjsys, iZone,
163 : padfPrjParams,
164 1 : iDatum );
165 : }
166 :
167 4 : static double OGRSpatialReferenceUSGSUnpackNoOp(double dfVal)
168 : {
169 4 : return dfVal;
170 : }
171 :
172 7 : static double OGRSpatialReferenceUSGSUnpackRadian(double dfVal)
173 : {
174 7 : return (dfVal * 180.0 / M_PI);
175 : }
176 :
177 : /************************************************************************/
178 : /* importFromUSGS() */
179 : /************************************************************************/
180 :
181 : /**
182 : * \brief Import coordinate system from USGS projection definition.
183 : *
184 : * This method will import projection definition in style, used by USGS GCTP
185 : * software. GCTP operates on angles in packed DMS format (see
186 : * CPLDecToPackedDMS() function for details), so all angle values (latitudes,
187 : * longitudes, azimuths, etc.) specified in the padfPrjParams array should
188 : * be in the packed DMS format, unless bAnglesInPackedDMSFormat is set to FALSE.
189 : *
190 : * This function is the equivalent of the C function OSRImportFromUSGS().
191 : * Note that the bAnglesInPackedDMSFormat parameter is only present in the C++
192 : * method. The C function assumes bAnglesInPackedFormat = TRUE.
193 : *
194 : * @param iProjSys Input projection system code, used in GCTP.
195 : *
196 : * @param iZone Input zone for UTM and State Plane projection systems. For
197 : * Southern Hemisphere UTM use a negative zone code. iZone ignored for all
198 : * other projections.
199 : *
200 : * @param padfPrjParams Array of 15 coordinate system parameters. These
201 : * parameters differs for different projections.
202 : *
203 : * <h4>Projection Transformation Package Projection Parameters</h4>
204 : * <pre>
205 : * ----------------------------------------------------------------------------
206 : * | Array Element
207 : * Code & Projection Id |---------------------------------------------------
208 : * | 0 | 1 | 2 | 3 | 4 | 5 |6 | 7
209 : * ----------------------------------------------------------------------------
210 : * 0 Geographic | | | | | | | |
211 : * 1 U T M |Lon/Z |Lat/Z | | | | | |
212 : * 2 State Plane | | | | | | | |
213 : * 3 Albers Equal Area |SMajor|SMinor|STDPR1|STDPR2|CentMer|OriginLat|FE|FN
214 : * 4 Lambert Conformal C |SMajor|SMinor|STDPR1|STDPR2|CentMer|OriginLat|FE|FN
215 : * 5 Mercator |SMajor|SMinor| | |CentMer|TrueScale|FE|FN
216 : * 6 Polar Stereographic |SMajor|SMinor| | |LongPol|TrueScale|FE|FN
217 : * 7 Polyconic |SMajor|SMinor| | |CentMer|OriginLat|FE|FN
218 : * 8 Equid. Conic A |SMajor|SMinor|STDPAR| |CentMer|OriginLat|FE|FN
219 : * Equid. Conic B |SMajor|SMinor|STDPR1|STDPR2|CentMer|OriginLat|FE|FN
220 : * 9 Transverse Mercator |SMajor|SMinor|Factor| |CentMer|OriginLat|FE|FN
221 : * 10 Stereographic |Sphere| | | |CentLon|CenterLat|FE|FN
222 : * 11 Lambert Azimuthal |Sphere| | | |CentLon|CenterLat|FE|FN
223 : * 12 Azimuthal |Sphere| | | |CentLon|CenterLat|FE|FN
224 : * 13 Gnomonic |Sphere| | | |CentLon|CenterLat|FE|FN
225 : * 14 Orthographic |Sphere| | | |CentLon|CenterLat|FE|FN
226 : * 15 Gen. Vert. Near Per |Sphere| |Height| |CentLon|CenterLat|FE|FN
227 : * 16 Sinusoidal |Sphere| | | |CentMer| |FE|FN
228 : * 17 Equirectangular |Sphere| | | |CentMer|TrueScale|FE|FN
229 : * 18 Miller Cylindrical |Sphere| | | |CentMer| |FE|FN
230 : * 19 Van der Grinten |Sphere| | | |CentMer|OriginLat|FE|FN
231 : * 20 Hotin Oblique Merc A |SMajor|SMinor|Factor| | |OriginLat|FE|FN
232 : * Hotin Oblique Merc B |SMajor|SMinor|Factor|AziAng|AzmthPt|OriginLat|FE|FN
233 : * 21 Robinson |Sphere| | | |CentMer| |FE|FN
234 : * 22 Space Oblique Merc A |SMajor|SMinor| |IncAng|AscLong| |FE|FN
235 : * Space Oblique Merc B |SMajor|SMinor|Satnum|Path | | |FE|FN
236 : * 23 Alaska Conformal |SMajor|SMinor| | | | |FE|FN
237 : * 24 Interrupted Goode |Sphere| | | | | | |
238 : * 25 Mollweide |Sphere| | | |CentMer| |FE|FN
239 : * 26 Interrupt Mollweide |Sphere| | | | | | |
240 : * 27 Hammer |Sphere| | | |CentMer| |FE|FN
241 : * 28 Wagner IV |Sphere| | | |CentMer| |FE|FN
242 : * 29 Wagner VII |Sphere| | | |CentMer| |FE|FN
243 : * 30 Oblated Equal Area |Sphere| |Shapem|Shapen|CentLon|CenterLat|FE|FN
244 : * ----------------------------------------------------------------------------
245 : *
246 : * ----------------------------------------------------
247 : * | Array Element |
248 : * Code & Projection Id |---------------------------
249 : * | 8 | 9 | 10 | 11 | 12 |
250 : * ----------------------------------------------------
251 : * 0 Geographic | | | | | |
252 : * 1 U T M | | | | | |
253 : * 2 State Plane | | | | | |
254 : * 3 Albers Equal Area | | | | | |
255 : * 4 Lambert Conformal C | | | | | |
256 : * 5 Mercator | | | | | |
257 : * 6 Polar Stereographic | | | | | |
258 : * 7 Polyconic | | | | | |
259 : * 8 Equid. Conic A |zero | | | | |
260 : * Equid. Conic B |one | | | | |
261 : * 9 Transverse Mercator | | | | | |
262 : * 10 Stereographic | | | | | |
263 : * 11 Lambert Azimuthal | | | | | |
264 : * 12 Azimuthal | | | | | |
265 : * 13 Gnomonic | | | | | |
266 : * 14 Orthographic | | | | | |
267 : * 15 Gen. Vert. Near Per | | | | | |
268 : * 16 Sinusoidal | | | | | |
269 : * 17 Equirectangular | | | | | |
270 : * 18 Miller Cylindrical | | | | | |
271 : * 19 Van der Grinten | | | | | |
272 : * 20 Hotin Oblique Merc A |Long1|Lat1|Long2|Lat2|zero|
273 : * Hotin Oblique Merc B | | | | |one |
274 : * 21 Robinson | | | | | |
275 : * 22 Space Oblique Merc A |PSRev|LRat|PFlag| |zero|
276 : * Space Oblique Merc B | | | | |one |
277 : * 23 Alaska Conformal | | | | | |
278 : * 24 Interrupted Goode | | | | | |
279 : * 25 Mollweide | | | | | |
280 : * 26 Interrupt Mollweide | | | | | |
281 : * 27 Hammer | | | | | |
282 : * 28 Wagner IV | | | | | |
283 : * 29 Wagner VII | | | | | |
284 : * 30 Oblated Equal Area |Angle| | | | |
285 : * ----------------------------------------------------
286 : *
287 : * where
288 : *
289 : * Lon/Z Longitude of any point in the UTM zone or zero. If zero,
290 : * a zone code must be specified.
291 : * Lat/Z Latitude of any point in the UTM zone or zero. If zero, a
292 : * zone code must be specified.
293 : * SMajor Semi-major axis of ellipsoid. If zero, Clarke 1866 in meters
294 : * is assumed.
295 : * SMinor Eccentricity squared of the ellipsoid if less than zero,
296 : * if zero, a spherical form is assumed, or if greater than
297 : * zero, the semi-minor axis of ellipsoid.
298 : * Sphere Radius of reference sphere. If zero, 6370997 meters is used.
299 : * STDPAR Latitude of the standard parallel
300 : * STDPR1 Latitude of the first standard parallel
301 : * STDPR2 Latitude of the second standard parallel
302 : * CentMer Longitude of the central meridian
303 : * OriginLat Latitude of the projection origin
304 : * FE False easting in the same units as the semi-major axis
305 : * FN False northing in the same units as the semi-major axis
306 : * TrueScale Latitude of true scale
307 : * LongPol Longitude down below pole of map
308 : * Factor Scale factor at central meridian (Transverse Mercator) or
309 : * center of projection (Hotine Oblique Mercator)
310 : * CentLon Longitude of center of projection
311 : * CenterLat Latitude of center of projection
312 : * Height Height of perspective point
313 : * Long1 Longitude of first point on center line (Hotine Oblique
314 : * Mercator, format A)
315 : * Long2 Longitude of second point on center line (Hotine Oblique
316 : * Mercator, format A)
317 : * Lat1 Latitude of first point on center line (Hotine Oblique
318 : * Mercator, format A)
319 : * Lat2 Latitude of second point on center line (Hotine Oblique
320 : * Mercator, format A)
321 : * AziAng Azimuth angle east of north of center line (Hotine Oblique
322 : * Mercator, format B)
323 : * AzmthPt Longitude of point on central meridian where azimuth occurs
324 : * (Hotine Oblique Mercator, format B)
325 : * IncAng Inclination of orbit at ascending node, counter-clockwise
326 : * from equator (SOM, format A)
327 : * AscLong Longitude of ascending orbit at equator (SOM, format A)
328 : * PSRev Period of satellite revolution in minutes (SOM, format A)
329 : * LRat Landsat ratio to compensate for confusion at northern end
330 : * of orbit (SOM, format A -- use 0.5201613)
331 : * PFlag End of path flag for Landsat: 0 = start of path,
332 : * 1 = end of path (SOM, format A)
333 : * Satnum Landsat Satellite Number (SOM, format B)
334 : * Path Landsat Path Number (Use WRS-1 for Landsat 1, 2 and 3 and
335 : * WRS-2 for Landsat 4, 5 and 6.) (SOM, format B)
336 : * Shapem Oblated Equal Area oval shape parameter m
337 : * Shapen Oblated Equal Area oval shape parameter n
338 : * Angle Oblated Equal Area oval rotation angle
339 : *
340 : * Array elements 13 and 14 are set to zero. All array elements with blank
341 : * fields are set to zero too.
342 : * </pre>
343 : *
344 : * @param iDatum Input spheroid.<p>
345 : *
346 : * If the datum code is negative, the first two values in the parameter array
347 : * (parm) are used to define the values as follows:
348 : *
349 : * <ul>
350 : *
351 : * <li> If padfPrjParams[0] is a non-zero value and padfPrjParams[1] is
352 : * greater than one, the semimajor axis is set to padfPrjParams[0] and
353 : * the semiminor axis is set to padfPrjParams[1].
354 : *
355 : * <li> If padfPrjParams[0] is nonzero and padfPrjParams[1] is greater than
356 : * zero but less than or equal to one, the semimajor axis is set to
357 : * padfPrjParams[0] and the semiminor axis is computed from the eccentricity
358 : * squared value padfPrjParams[1]:<p>
359 : *
360 : * semiminor = sqrt(1.0 - ES) * semimajor<p>
361 : *
362 : * where<p>
363 : *
364 : * ES = eccentricity squared
365 : *
366 : * <li> If padfPrjParams[0] is nonzero and padfPrjParams[1] is equal to zero,
367 : * the semimajor axis and semiminor axis are set to padfPrjParams[0].
368 : *
369 : * <li> If padfPrjParams[0] equals zero and padfPrjParams[1] is greater than
370 : * zero, the default Clarke 1866 is used to assign values to the semimajor
371 : * axis and semiminor axis.
372 : *
373 : * <li> If padfPrjParams[0] and padfPrjParams[1] equals zero, the semimajor
374 : * axis is set to 6370997.0 and the semiminor axis is set to zero.
375 : *
376 : * </ul>
377 : *
378 : * If a datum code is zero or greater, the semimajor and semiminor axis are
379 : * defined by the datum code as found in the following table:
380 : *
381 : * <h4>Supported Datums</h4>
382 : * <pre>
383 : * 0: Clarke 1866 (default)
384 : * 1: Clarke 1880
385 : * 2: Bessel
386 : * 3: International 1967
387 : * 4: International 1909
388 : * 5: WGS 72
389 : * 6: Everest
390 : * 7: WGS 66
391 : * 8: GRS 1980/WGS 84
392 : * 9: Airy
393 : * 10: Modified Everest
394 : * 11: Modified Airy
395 : * 12: Walbeck
396 : * 13: Southeast Asia
397 : * 14: Australian National
398 : * 15: Krassovsky
399 : * 16: Hough
400 : * 17: Mercury 1960
401 : * 18: Modified Mercury 1968
402 : * 19: Sphere of Radius 6370997 meters
403 : * </pre>
404 : *
405 : * @param nUSGSAngleFormat one of USGS_ANGLE_DECIMALDEGREES, USGS_ANGLE_PACKEDDMS, or USGS_ANGLE_RADIANS (default is USGS_ANGLE_PACKEDDMS).
406 : *
407 : * @return OGRERR_NONE on success or an error code in case of failure.
408 : */
409 :
410 18 : OGRErr OGRSpatialReference::importFromUSGS( long iProjSys, long iZone,
411 : double *padfPrjParams,
412 : long iDatum,
413 : int nUSGSAngleFormat )
414 :
415 : {
416 18 : if( !padfPrjParams )
417 0 : return OGRERR_CORRUPT_DATA;
418 :
419 18 : double (*pfnUnpackAnglesFn)(double) = NULL;
420 :
421 18 : if (nUSGSAngleFormat == USGS_ANGLE_DECIMALDEGREES )
422 3 : pfnUnpackAnglesFn = OGRSpatialReferenceUSGSUnpackNoOp;
423 15 : else if (nUSGSAngleFormat == USGS_ANGLE_RADIANS )
424 9 : pfnUnpackAnglesFn = OGRSpatialReferenceUSGSUnpackRadian;
425 : else
426 6 : pfnUnpackAnglesFn = CPLPackedDMSToDec;
427 :
428 : /* -------------------------------------------------------------------- */
429 : /* Operate on the basis of the projection code. */
430 : /* -------------------------------------------------------------------- */
431 18 : switch ( iProjSys )
432 : {
433 : case GEO:
434 2 : break;
435 :
436 : case UTM:
437 : {
438 3 : int bNorth = TRUE;
439 :
440 3 : if ( !iZone )
441 : {
442 1 : if ( padfPrjParams[2] != 0.0 )
443 1 : iZone = (long) padfPrjParams[2];
444 0 : else if (padfPrjParams[0] != 0.0 && padfPrjParams[1] != 0.0)
445 : {
446 : iZone = (long)(((pfnUnpackAnglesFn(padfPrjParams[0])
447 0 : + 180.0) / 6.0) + 1.0);
448 0 : if ( pfnUnpackAnglesFn(padfPrjParams[0]) < 0 )
449 0 : bNorth = FALSE;
450 : }
451 : }
452 :
453 3 : if ( iZone < 0 )
454 : {
455 0 : iZone = -iZone;
456 0 : bNorth = FALSE;
457 : }
458 3 : SetUTM( iZone, bNorth );
459 : }
460 3 : break;
461 :
462 : case SPCS:
463 : {
464 0 : int bNAD83 = TRUE;
465 :
466 0 : if ( iDatum == 0 )
467 0 : bNAD83 = FALSE;
468 0 : else if ( iDatum != 8 )
469 : CPLError( CE_Warning, CPLE_AppDefined,
470 : "Wrong datum for State Plane projection %d. "
471 0 : "Should be 0 or 8.", (int) iDatum );
472 :
473 0 : SetStatePlane( iZone, bNAD83 );
474 : }
475 0 : break;
476 :
477 : case ALBERS:
478 : SetACEA( pfnUnpackAnglesFn(padfPrjParams[2]),
479 : pfnUnpackAnglesFn(padfPrjParams[3]),
480 : pfnUnpackAnglesFn(padfPrjParams[5]),
481 : pfnUnpackAnglesFn(padfPrjParams[4]),
482 0 : padfPrjParams[6], padfPrjParams[7] );
483 0 : break;
484 :
485 : case LAMCC:
486 : SetLCC( pfnUnpackAnglesFn(padfPrjParams[2]),
487 : pfnUnpackAnglesFn(padfPrjParams[3]),
488 : pfnUnpackAnglesFn(padfPrjParams[5]),
489 : pfnUnpackAnglesFn(padfPrjParams[4]),
490 1 : padfPrjParams[6], padfPrjParams[7] );
491 1 : break;
492 :
493 : case MERCAT:
494 : SetMercator( pfnUnpackAnglesFn(padfPrjParams[5]),
495 : pfnUnpackAnglesFn(padfPrjParams[4]),
496 : 1.0,
497 0 : padfPrjParams[6], padfPrjParams[7] );
498 0 : break;
499 :
500 : case PS:
501 : SetPS( pfnUnpackAnglesFn(padfPrjParams[5]),
502 : pfnUnpackAnglesFn(padfPrjParams[4]),
503 : 1.0,
504 0 : padfPrjParams[6], padfPrjParams[7] );
505 :
506 0 : break;
507 :
508 : case POLYC:
509 : SetPolyconic( pfnUnpackAnglesFn(padfPrjParams[5]),
510 : pfnUnpackAnglesFn(padfPrjParams[4]),
511 0 : padfPrjParams[6], padfPrjParams[7] );
512 0 : break;
513 :
514 : case EQUIDC:
515 1 : if ( padfPrjParams[8] )
516 : {
517 : SetEC( pfnUnpackAnglesFn(padfPrjParams[2]),
518 : pfnUnpackAnglesFn(padfPrjParams[3]),
519 : pfnUnpackAnglesFn(padfPrjParams[5]),
520 : pfnUnpackAnglesFn(padfPrjParams[4]),
521 1 : padfPrjParams[6], padfPrjParams[7] );
522 : }
523 : else
524 : {
525 : SetEC( pfnUnpackAnglesFn(padfPrjParams[2]),
526 : pfnUnpackAnglesFn(padfPrjParams[2]),
527 : pfnUnpackAnglesFn(padfPrjParams[5]),
528 : pfnUnpackAnglesFn(padfPrjParams[4]),
529 0 : padfPrjParams[6], padfPrjParams[7] );
530 : }
531 1 : break;
532 :
533 : case TM:
534 : SetTM( pfnUnpackAnglesFn(padfPrjParams[5]),
535 : pfnUnpackAnglesFn(padfPrjParams[4]),
536 : padfPrjParams[2],
537 3 : padfPrjParams[6], padfPrjParams[7] );
538 3 : break;
539 :
540 : case STEREO:
541 : SetStereographic( pfnUnpackAnglesFn(padfPrjParams[5]),
542 : pfnUnpackAnglesFn(padfPrjParams[4]),
543 : 1.0,
544 0 : padfPrjParams[6], padfPrjParams[7] );
545 0 : break;
546 :
547 : case LAMAZ:
548 : SetLAEA( pfnUnpackAnglesFn(padfPrjParams[5]),
549 : pfnUnpackAnglesFn(padfPrjParams[4]),
550 0 : padfPrjParams[6], padfPrjParams[7] );
551 0 : break;
552 :
553 : case AZMEQD:
554 : SetAE( pfnUnpackAnglesFn(padfPrjParams[5]),
555 : pfnUnpackAnglesFn(padfPrjParams[4]),
556 0 : padfPrjParams[6], padfPrjParams[7] );
557 0 : break;
558 :
559 : case GNOMON:
560 : SetGnomonic( pfnUnpackAnglesFn(padfPrjParams[5]),
561 : pfnUnpackAnglesFn(padfPrjParams[4]),
562 0 : padfPrjParams[6], padfPrjParams[7] );
563 0 : break;
564 :
565 : case ORTHO:
566 : SetOrthographic( pfnUnpackAnglesFn(padfPrjParams[5]),
567 : pfnUnpackAnglesFn(padfPrjParams[4]),
568 0 : padfPrjParams[6], padfPrjParams[7] );
569 0 : break;
570 :
571 : // FIXME: GVNSP --- General Vertical Near-Side Perspective skipped
572 :
573 : case SNSOID:
574 : SetSinusoidal( pfnUnpackAnglesFn(padfPrjParams[4]),
575 7 : padfPrjParams[6], padfPrjParams[7] );
576 7 : break;
577 :
578 : case EQRECT:
579 : SetEquirectangular2( 0.0,
580 : pfnUnpackAnglesFn(padfPrjParams[4]),
581 : pfnUnpackAnglesFn(padfPrjParams[5]),
582 0 : padfPrjParams[6], padfPrjParams[7] );
583 0 : break;
584 :
585 : case MILLER:
586 : SetMC( pfnUnpackAnglesFn(padfPrjParams[5]),
587 : pfnUnpackAnglesFn(padfPrjParams[4]),
588 0 : padfPrjParams[6], padfPrjParams[7] );
589 0 : break;
590 :
591 : case VGRINT:
592 : SetVDG( pfnUnpackAnglesFn(padfPrjParams[4]),
593 0 : padfPrjParams[6], padfPrjParams[7] );
594 0 : break;
595 :
596 : case HOM:
597 0 : if ( padfPrjParams[12] )
598 : {
599 : SetHOM( pfnUnpackAnglesFn(padfPrjParams[5]),
600 : pfnUnpackAnglesFn(padfPrjParams[4]),
601 : pfnUnpackAnglesFn(padfPrjParams[3]),
602 : 0.0, padfPrjParams[2],
603 0 : padfPrjParams[6], padfPrjParams[7] );
604 : }
605 : else
606 : {
607 : SetHOM2PNO( pfnUnpackAnglesFn(padfPrjParams[5]),
608 : pfnUnpackAnglesFn(padfPrjParams[9]),
609 : pfnUnpackAnglesFn(padfPrjParams[8]),
610 : pfnUnpackAnglesFn(padfPrjParams[11]),
611 : pfnUnpackAnglesFn(padfPrjParams[10]),
612 : padfPrjParams[2],
613 0 : padfPrjParams[6], padfPrjParams[7] );
614 : }
615 0 : break;
616 :
617 : case ROBIN:
618 : SetRobinson( pfnUnpackAnglesFn(padfPrjParams[4]),
619 0 : padfPrjParams[6], padfPrjParams[7] );
620 0 : break;
621 :
622 : // FIXME: SOM --- Space Oblique Mercator skipped
623 :
624 : // FIXME: ALASKA --- Alaska Conformal skipped
625 :
626 : // FIXME: GOODE --- Interrupted Goode skipped
627 :
628 : case MOLL:
629 : SetMollweide( pfnUnpackAnglesFn(padfPrjParams[4]),
630 0 : padfPrjParams[6], padfPrjParams[7] );
631 0 : break;
632 :
633 : // FIXME: IMOLL --- Interrupted Mollweide skipped
634 :
635 : // FIXME: HAMMER --- Hammer skipped
636 :
637 : case WAGIV:
638 0 : SetWagner( 4, 0.0, padfPrjParams[6], padfPrjParams[7] );
639 0 : break;
640 :
641 : case WAGVII:
642 0 : SetWagner( 7, 0.0, padfPrjParams[6], padfPrjParams[7] );
643 0 : break;
644 :
645 : // FIXME: OBEQA --- Oblated Equal Area skipped
646 :
647 : // FIXME: ISINUS1 --- Integerized Sinusoidal Grid (the same as 99) skipped
648 :
649 : // FIXME: CEA --- Cylindrical Equal Area skipped (Grid corners set in meters for EASE grid)
650 :
651 : // FIXME: BCEA --- Cylindrical Equal Area skipped (Grid corners set in DMS degs for EASE grid)
652 :
653 : // FIXME: ISINUS --- Integrized Sinusoidal skipped
654 :
655 : default:
656 1 : CPLDebug( "OSR_USGS", "Unsupported projection: %ld", iProjSys );
657 1 : SetLocalCS( CPLString().Printf("GCTP projection number %ld", iProjSys) );
658 : break;
659 :
660 : }
661 :
662 : /* -------------------------------------------------------------------- */
663 : /* Try to translate the datum/spheroid. */
664 : /* -------------------------------------------------------------------- */
665 :
666 18 : if ( !IsLocal() )
667 : {
668 17 : char *pszName = NULL;
669 : double dfSemiMajor, dfInvFlattening;
670 :
671 17 : if ( iDatum < 0 ) // Use specified ellipsoid parameters
672 : {
673 7 : if ( padfPrjParams[0] > 0.0 )
674 : {
675 7 : if ( padfPrjParams[1] > 1.0 )
676 : {
677 0 : if( ABS(padfPrjParams[0] - padfPrjParams[1]) < 0.01 )
678 0 : dfInvFlattening = 0.0;
679 : else
680 : {
681 0 : dfInvFlattening = padfPrjParams[0]
682 0 : / ( padfPrjParams[0] - padfPrjParams[1] );
683 : }
684 : }
685 7 : else if ( padfPrjParams[1] > 0.0 )
686 : {
687 : dfInvFlattening =
688 0 : 1.0 / ( 1.0 - sqrt(1.0 - padfPrjParams[1]) );
689 : }
690 : else
691 7 : dfInvFlattening = 0.0;
692 :
693 : SetGeogCS( "Unknown datum based upon the custom spheroid",
694 : "Not specified (based on custom spheroid)",
695 : "Custom spheroid", padfPrjParams[0], dfInvFlattening,
696 7 : NULL, 0, NULL, 0 );
697 : }
698 0 : else if ( padfPrjParams[1] > 0.0 ) // Clarke 1866
699 : {
700 0 : if ( OSRGetEllipsoidInfo( 7008, &pszName, &dfSemiMajor,
701 : &dfInvFlattening ) == OGRERR_NONE )
702 : {
703 : SetGeogCS( CPLString().Printf(
704 : "Unknown datum based upon the %s ellipsoid",
705 : pszName ),
706 : CPLString().Printf(
707 : "Not specified (based on %s spheroid)",
708 : pszName ),
709 : pszName, dfSemiMajor, dfInvFlattening,
710 0 : NULL, 0.0, NULL, 0.0 );
711 0 : SetAuthority( "SPHEROID", "EPSG", 7008 );
712 : }
713 : }
714 : else // Sphere, rad 6370997 m
715 : {
716 0 : if ( OSRGetEllipsoidInfo( 7047, &pszName, &dfSemiMajor,
717 : &dfInvFlattening ) == OGRERR_NONE )
718 : {
719 : SetGeogCS( CPLString().Printf(
720 : "Unknown datum based upon the %s ellipsoid",
721 : pszName ),
722 : CPLString().Printf(
723 : "Not specified (based on %s spheroid)",
724 : pszName ),
725 : pszName, dfSemiMajor, dfInvFlattening,
726 0 : NULL, 0.0, NULL, 0.0 );
727 0 : SetAuthority( "SPHEROID", "EPSG", 7047 );
728 : }
729 : }
730 :
731 : }
732 20 : else if ( iDatum < NUMBER_OF_ELLIPSOIDS && aoEllips[iDatum] )
733 : {
734 10 : if( OSRGetEllipsoidInfo( aoEllips[iDatum], &pszName,
735 : &dfSemiMajor, &dfInvFlattening ) == OGRERR_NONE )
736 : {
737 : SetGeogCS( CPLString().Printf("Unknown datum based upon the %s ellipsoid",
738 : pszName ),
739 : CPLString().Printf( "Not specified (based on %s spheroid)",
740 : pszName ),
741 : pszName, dfSemiMajor, dfInvFlattening,
742 10 : NULL, 0.0, NULL, 0.0 );
743 10 : SetAuthority( "SPHEROID", "EPSG", aoEllips[iDatum] );
744 : }
745 : else
746 : {
747 : CPLError( CE_Warning, CPLE_AppDefined,
748 : "Failed to lookup datum code %d, likely due to missing GDAL gcs.csv\n"
749 : " file. Falling back to use WGS84.",
750 0 : (int) iDatum );
751 0 : SetWellKnownGeogCS("WGS84" );
752 : }
753 : }
754 : else
755 : {
756 : CPLError( CE_Warning, CPLE_AppDefined,
757 : "Wrong datum code %d. Supported datums 0--%d only.\n"
758 : "Setting WGS84 as a fallback.",
759 0 : (int) iDatum, NUMBER_OF_ELLIPSOIDS );
760 0 : SetWellKnownGeogCS( "WGS84" );
761 : }
762 :
763 17 : if ( pszName )
764 10 : CPLFree( pszName );
765 : }
766 :
767 : /* -------------------------------------------------------------------- */
768 : /* Grid units translation */
769 : /* -------------------------------------------------------------------- */
770 18 : if( IsLocal() || IsProjected() )
771 16 : SetLinearUnits( SRS_UL_METER, 1.0 );
772 :
773 18 : FixupOrdering();
774 :
775 18 : return OGRERR_NONE;
776 : }
777 :
778 : /************************************************************************/
779 : /* OSRExportToUSGS() */
780 : /************************************************************************/
781 : /**
782 : * \brief Export coordinate system in USGS GCTP projection definition.
783 : *
784 : * This function is the same as OGRSpatialReference::exportToUSGS().
785 : */
786 :
787 1 : OGRErr OSRExportToUSGS( OGRSpatialReferenceH hSRS,
788 : long *piProjSys, long *piZone,
789 : double **ppadfPrjParams, long *piDatum )
790 :
791 : {
792 1 : VALIDATE_POINTER1( hSRS, "OSRExportToUSGS", CE_Failure );
793 :
794 1 : *ppadfPrjParams = NULL;
795 :
796 : return ((OGRSpatialReference *) hSRS)->exportToUSGS( piProjSys, piZone,
797 : ppadfPrjParams,
798 1 : piDatum );
799 : }
800 :
801 : /************************************************************************/
802 : /* exportToUSGS() */
803 : /************************************************************************/
804 :
805 : /**
806 : * \brief Export coordinate system in USGS GCTP projection definition.
807 : *
808 : * This method is the equivalent of the C function OSRExportToUSGS().
809 : *
810 : * @param piProjSys Pointer to variable, where the projection system code will
811 : * be returned.
812 : *
813 : * @param piZone Pointer to variable, where the zone for UTM and State Plane
814 : * projection systems will be returned.
815 : *
816 : * @param ppadfPrjParams Pointer to which dynamically allocated array of
817 : * 15 projection parameters will be assigned. See importFromUSGS() for
818 : * the list of parameters. Caller responsible to free this array.
819 : *
820 : * @param piDatum Pointer to variable, where the datum code will
821 : * be returned.
822 : *
823 : * @return OGRERR_NONE on success or an error code on failure.
824 : */
825 :
826 1 : OGRErr OGRSpatialReference::exportToUSGS( long *piProjSys, long *piZone,
827 : double **ppadfPrjParams,
828 : long *piDatum ) const
829 :
830 : {
831 1 : const char *pszProjection = GetAttrValue("PROJECTION");
832 :
833 : /* -------------------------------------------------------------------- */
834 : /* Fill all projection parameters with zero. */
835 : /* -------------------------------------------------------------------- */
836 : int i;
837 :
838 1 : *ppadfPrjParams = (double *)CPLMalloc( 15 * sizeof(double) );
839 16 : for ( i = 0; i < 15; i++ )
840 15 : (*ppadfPrjParams)[i] = 0.0;
841 :
842 1 : *piZone = 0L;
843 :
844 : /* ==================================================================== */
845 : /* Handle the projection definition. */
846 : /* ==================================================================== */
847 1 : if( IsLocal() )
848 0 : *piProjSys = GEO;
849 :
850 1 : else if( pszProjection == NULL )
851 : {
852 : #ifdef DEBUG
853 : CPLDebug( "OSR_USGS",
854 0 : "Empty projection definition, considered as Geographic" );
855 : #endif
856 0 : *piProjSys = GEO;
857 : }
858 :
859 1 : else if( EQUAL(pszProjection, SRS_PT_ALBERS_CONIC_EQUAL_AREA) )
860 : {
861 0 : *piProjSys = ALBERS;
862 0 : (*ppadfPrjParams)[2] = CPLDecToPackedDMS(
863 0 : GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 ) );
864 0 : (*ppadfPrjParams)[3] = CPLDecToPackedDMS(
865 0 : GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 ) );
866 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
867 0 : GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
868 0 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
869 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
870 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
871 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
872 : }
873 :
874 1 : else if( EQUAL(pszProjection, SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP) )
875 : {
876 1 : *piProjSys = LAMCC;
877 1 : (*ppadfPrjParams)[2] = CPLDecToPackedDMS(
878 1 : GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 ) );
879 1 : (*ppadfPrjParams)[3] = CPLDecToPackedDMS(
880 1 : GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 ) );
881 1 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
882 1 : GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
883 1 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
884 1 : GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
885 1 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
886 1 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
887 : }
888 :
889 0 : else if( EQUAL(pszProjection, SRS_PT_MERCATOR_1SP) )
890 : {
891 0 : *piProjSys = MERCAT;
892 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
893 0 : GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
894 0 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
895 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
896 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
897 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
898 : }
899 :
900 0 : else if( EQUAL(pszProjection, SRS_PT_POLAR_STEREOGRAPHIC) )
901 : {
902 0 : *piProjSys = PS;
903 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
904 0 : GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
905 0 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
906 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
907 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
908 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
909 : }
910 :
911 0 : else if( EQUAL(pszProjection, SRS_PT_POLYCONIC) )
912 : {
913 0 : *piProjSys = POLYC;
914 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
915 0 : GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
916 0 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
917 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
918 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
919 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
920 : }
921 :
922 0 : else if( EQUAL(pszProjection, SRS_PT_EQUIDISTANT_CONIC) )
923 : {
924 0 : *piProjSys = EQUIDC;
925 0 : (*ppadfPrjParams)[2] = CPLDecToPackedDMS(
926 0 : GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 ) );
927 0 : (*ppadfPrjParams)[3] = CPLDecToPackedDMS(
928 0 : GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 ) );
929 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
930 0 : GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
931 0 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
932 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
933 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
934 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
935 0 : (*ppadfPrjParams)[8] = 1.0;
936 : }
937 :
938 0 : else if( EQUAL(pszProjection, SRS_PT_TRANSVERSE_MERCATOR) )
939 : {
940 : int bNorth;
941 :
942 0 : *piZone = GetUTMZone( &bNorth );
943 :
944 0 : if( *piZone != 0 )
945 : {
946 0 : *piProjSys = UTM;
947 0 : if( !bNorth )
948 0 : *piZone = - *piZone;
949 : }
950 : else
951 : {
952 0 : *piProjSys = TM;
953 0 : (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
954 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
955 0 : GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
956 0 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
957 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
958 0 : (*ppadfPrjParams)[6] =
959 0 : GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
960 0 : (*ppadfPrjParams)[7] =
961 0 : GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
962 : }
963 : }
964 :
965 0 : else if( EQUAL(pszProjection, SRS_PT_STEREOGRAPHIC) )
966 : {
967 0 : *piProjSys = STEREO;
968 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
969 0 : GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
970 0 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
971 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
972 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
973 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
974 : }
975 :
976 0 : else if( EQUAL(pszProjection, SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA) )
977 : {
978 0 : *piProjSys = LAMAZ;
979 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
980 0 : GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
981 0 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
982 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
983 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
984 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
985 : }
986 :
987 0 : else if( EQUAL(pszProjection, SRS_PT_AZIMUTHAL_EQUIDISTANT) )
988 : {
989 0 : *piProjSys = AZMEQD;
990 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
991 0 : GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 ) );
992 0 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
993 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, 0.0 ) );
994 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
995 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
996 : }
997 :
998 0 : else if( EQUAL(pszProjection, SRS_PT_GNOMONIC) )
999 : {
1000 0 : *piProjSys = GNOMON;
1001 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
1002 0 : GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1003 0 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
1004 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1005 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
1006 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
1007 : }
1008 :
1009 0 : else if( EQUAL(pszProjection, SRS_PT_ORTHOGRAPHIC) )
1010 : {
1011 0 : *piProjSys = ORTHO;
1012 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
1013 0 : GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1014 0 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
1015 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) );
1016 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
1017 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
1018 : }
1019 :
1020 0 : else if( EQUAL(pszProjection, SRS_PT_SINUSOIDAL) )
1021 : {
1022 0 : *piProjSys = SNSOID;
1023 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
1024 0 : GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 ) );
1025 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
1026 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
1027 : }
1028 :
1029 0 : else if( EQUAL(pszProjection, SRS_PT_EQUIRECTANGULAR) )
1030 : {
1031 0 : *piProjSys = EQRECT;
1032 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
1033 0 : GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1034 0 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
1035 0 : GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 ) );
1036 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
1037 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
1038 : }
1039 :
1040 0 : else if( EQUAL(pszProjection, SRS_PT_MILLER_CYLINDRICAL) )
1041 : {
1042 0 : *piProjSys = MILLER;
1043 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
1044 0 : GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 ) );
1045 0 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
1046 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, 0.0 ) );
1047 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
1048 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
1049 : }
1050 :
1051 0 : else if( EQUAL(pszProjection, SRS_PT_VANDERGRINTEN) )
1052 : {
1053 0 : *piProjSys = VGRINT;
1054 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
1055 0 : GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 ) );
1056 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
1057 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
1058 : }
1059 :
1060 0 : else if( EQUAL(pszProjection, SRS_PT_HOTINE_OBLIQUE_MERCATOR) )
1061 : {
1062 0 : *piProjSys = HOM;
1063 0 : (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
1064 0 : (*ppadfPrjParams)[3] = CPLDecToPackedDMS(
1065 0 : GetNormProjParm( SRS_PP_AZIMUTH, 0.0 ) );
1066 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
1067 0 : GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 ) );
1068 0 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
1069 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, 0.0 ) );
1070 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
1071 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
1072 0 : (*ppadfPrjParams)[12] = 1.0;
1073 : }
1074 :
1075 0 : else if( EQUAL(pszProjection,
1076 : SRS_PT_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN) )
1077 : {
1078 0 : *piProjSys = HOM;
1079 0 : (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
1080 0 : (*ppadfPrjParams)[5] = CPLDecToPackedDMS(
1081 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, 0.0 ) );
1082 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
1083 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
1084 0 : (*ppadfPrjParams)[8] = CPLDecToPackedDMS(
1085 0 : GetNormProjParm( SRS_PP_LONGITUDE_OF_POINT_1, 0.0 ) );
1086 0 : (*ppadfPrjParams)[9] = CPLDecToPackedDMS(
1087 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_POINT_1, 0.0 ) );
1088 0 : (*ppadfPrjParams)[10] = CPLDecToPackedDMS(
1089 0 : GetNormProjParm( SRS_PP_LONGITUDE_OF_POINT_2, 0.0 ) );
1090 0 : (*ppadfPrjParams)[11] = CPLDecToPackedDMS(
1091 0 : GetNormProjParm( SRS_PP_LATITUDE_OF_POINT_2, 0.0 ) );
1092 0 : (*ppadfPrjParams)[12] = 0.0;
1093 : }
1094 :
1095 0 : else if( EQUAL(pszProjection, SRS_PT_ROBINSON) )
1096 : {
1097 0 : *piProjSys = ROBIN;
1098 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
1099 0 : GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 ) );
1100 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
1101 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
1102 : }
1103 :
1104 0 : else if( EQUAL(pszProjection, SRS_PT_MOLLWEIDE) )
1105 : {
1106 0 : *piProjSys = MOLL;
1107 0 : (*ppadfPrjParams)[4] = CPLDecToPackedDMS(
1108 0 : GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 ) );
1109 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
1110 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
1111 : }
1112 :
1113 0 : else if( EQUAL(pszProjection, SRS_PT_WAGNER_IV) )
1114 : {
1115 0 : *piProjSys = WAGIV;
1116 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
1117 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
1118 : }
1119 :
1120 0 : else if( EQUAL(pszProjection, SRS_PT_WAGNER_VII) )
1121 : {
1122 0 : *piProjSys = WAGVII;
1123 0 : (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
1124 0 : (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
1125 : }
1126 :
1127 : // Projection unsupported by GCTP
1128 : else
1129 : {
1130 : CPLDebug( "OSR_USGS",
1131 : "Projection \"%s\" unsupported by USGS GCTP. "
1132 0 : "Geographic system will be used.", pszProjection );
1133 0 : *piProjSys = GEO;
1134 : }
1135 :
1136 : /* -------------------------------------------------------------------- */
1137 : /* Translate the datum. */
1138 : /* -------------------------------------------------------------------- */
1139 1 : const char *pszDatum = GetAttrValue( "DATUM" );
1140 :
1141 1 : if ( pszDatum )
1142 : {
1143 1 : if( EQUAL( pszDatum, SRS_DN_NAD27 ) )
1144 1 : *piDatum = CLARKE1866;
1145 :
1146 0 : else if( EQUAL( pszDatum, SRS_DN_NAD83 ) )
1147 0 : *piDatum = GRS1980;
1148 :
1149 0 : else if( EQUAL( pszDatum, SRS_DN_WGS84 ) )
1150 0 : *piDatum = WGS84;
1151 :
1152 : // If not found well known datum, translate ellipsoid
1153 : else
1154 : {
1155 0 : double dfSemiMajor = GetSemiMajor();
1156 0 : double dfInvFlattening = GetInvFlattening();
1157 :
1158 : #ifdef DEBUG
1159 : CPLDebug( "OSR_USGS",
1160 : "Datum \"%s\" unsupported by USGS GCTP. "
1161 0 : "Try to translate ellipsoid definition.", pszDatum );
1162 : #endif
1163 :
1164 0 : for ( i = 0; i < NUMBER_OF_ELLIPSOIDS; i++ )
1165 : {
1166 : double dfSM;
1167 : double dfIF;
1168 :
1169 0 : if ( OSRGetEllipsoidInfo( aoEllips[i], NULL,
1170 : &dfSM, &dfIF ) == OGRERR_NONE
1171 : && CPLIsEqual( dfSemiMajor, dfSM )
1172 : && CPLIsEqual( dfInvFlattening, dfIF ) )
1173 : {
1174 0 : *piDatum = i;
1175 0 : break;
1176 : }
1177 : }
1178 :
1179 0 : if ( i == NUMBER_OF_ELLIPSOIDS ) // Didn't found matches; set
1180 : { // custom ellipsoid parameters
1181 : #ifdef DEBUG
1182 : CPLDebug( "OSR_USGS",
1183 : "Ellipsoid \"%s\" unsupported by USGS GCTP. "
1184 : "Custom ellipsoid definition will be used.",
1185 0 : pszDatum );
1186 : #endif
1187 0 : *piDatum = -1;
1188 0 : (*ppadfPrjParams)[0] = dfSemiMajor;
1189 0 : if ( ABS( dfInvFlattening ) < 0.000000000001 )
1190 : {
1191 0 : (*ppadfPrjParams)[1] = dfSemiMajor;
1192 : }
1193 : else
1194 : {
1195 0 : (*ppadfPrjParams)[1] =
1196 0 : dfSemiMajor * (1.0 - 1.0/dfInvFlattening);
1197 : }
1198 : }
1199 : }
1200 : }
1201 : else
1202 0 : *piDatum = -1;
1203 :
1204 1 : return OGRERR_NONE;
1205 : }
1206 :
|