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