1 : /******************************************************************************
2 : * $Id: ogr_srs_panorama.cpp 25019 2012-09-30 13:25:39Z rouault $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: OGRSpatialReference translation to/from "Panorama" GIS
6 : * georeferencing information (also know as GIS "Integration").
7 : * Author: Andrey Kiselev, dron@ak4719.spb.edu
8 : *
9 : ******************************************************************************
10 : * Copyright (c) 2005, 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_panorama.cpp 25019 2012-09-30 13:25:39Z rouault $");
37 :
38 : #define TO_DEGREES 57.2957795130823208766
39 : #define TO_RADIANS 0.017453292519943295769
40 :
41 : // XXX: this macro computes zone number from the central meridian parameter.
42 : // Note, that "Panorama" parameters are set in radians.
43 : // In degrees it means formulae:
44 : //
45 : // zone = (central_meridian + 3) / 6
46 : //
47 : #define TO_ZONE(x) (((x) + 0.05235987755982989) / 0.1047197551196597 + 0.5)
48 :
49 : /************************************************************************/
50 : /* "Panorama" projection codes. */
51 : /************************************************************************/
52 :
53 : #define PAN_PROJ_NONE -1L
54 : #define PAN_PROJ_TM 1L // Gauss-Kruger (Transverse Mercator)
55 : #define PAN_PROJ_LCC 2L // Lambert Conformal Conic 2SP
56 : #define PAN_PROJ_STEREO 5L // Stereographic
57 : #define PAN_PROJ_AE 6L // Azimuthal Equidistant (Postel)
58 : #define PAN_PROJ_MERCAT 8L // Mercator
59 : #define PAN_PROJ_POLYC 10L // Polyconic
60 : #define PAN_PROJ_PS 13L // Polar Stereographic
61 : #define PAN_PROJ_GNOMON 15L // Gnomonic
62 : #define PAN_PROJ_UTM 17L // Universal Transverse Mercator (UTM)
63 : #define PAN_PROJ_WAG1 18L // Wagner I (Kavraisky VI)
64 : #define PAN_PROJ_MOLL 19L // Mollweide
65 : #define PAN_PROJ_EC 20L // Equidistant Conic
66 : #define PAN_PROJ_LAEA 24L // Lambert Azimuthal Equal Area
67 : #define PAN_PROJ_EQC 27L // Equirectangular
68 : #define PAN_PROJ_CEA 28L // Cylindrical Equal Area (Lambert)
69 : #define PAN_PROJ_IMWP 29L // International Map of the World Polyconic
70 :
71 : /************************************************************************/
72 : /* "Panorama" datum codes. */
73 : /************************************************************************/
74 :
75 : #define PAN_DATUM_NONE -1L
76 : #define PAN_DATUM_PULKOVO42 1L // Pulkovo 1942
77 : #define PAN_DATUM_WGS84 2L // WGS84
78 :
79 : /************************************************************************/
80 : /* "Panorama" ellipsod codes. */
81 : /************************************************************************/
82 :
83 : #define PAN_ELLIPSOID_NONE -1L
84 : #define PAN_ELLIPSOID_KRASSOVSKY 1L // Krassovsky, 1940
85 : #define PAN_ELLIPSOID_WGS72 2L // WGS, 1972
86 : #define PAN_ELLIPSOID_INT1924 3L // International, 1924 (Hayford, 1909)
87 : #define PAN_ELLIPSOID_CLARCKE1880 4L // Clarke, 1880
88 : #define PAN_ELLIPSOID_CLARCKE1866 5L // Clarke, 1866 (NAD1927)
89 : #define PAN_ELLIPSOID_EVEREST1830 6L // Everest, 1830
90 : #define PAN_ELLIPSOID_BESSEL1841 7L // Bessel, 1841
91 : #define PAN_ELLIPSOID_AIRY1830 8L // Airy, 1830
92 : #define PAN_ELLIPSOID_WGS84 9L // WGS, 1984 (GPS)
93 :
94 : /************************************************************************/
95 : /* Correspondence between "Panorama" and EPSG datum codes. */
96 : /************************************************************************/
97 :
98 : static const long aoDatums[] =
99 : {
100 : 0,
101 : 4284, // Pulkovo, 1942
102 : 4326, // WGS, 1984,
103 : 4277, // OSGB 1936 (British National Grid)
104 : 0,
105 : 0,
106 : 0,
107 : 0,
108 : 0,
109 : 4200 // Pulkovo, 1995
110 : };
111 :
112 : #define NUMBER_OF_DATUMS (long)(sizeof(aoDatums)/sizeof(aoDatums[0]))
113 :
114 : /************************************************************************/
115 : /* Correspondence between "Panorama" and EPSG ellipsoid codes. */
116 : /************************************************************************/
117 :
118 : static const long aoEllips[] =
119 : {
120 : 0,
121 : 7024, // Krassovsky, 1940
122 : 7043, // WGS, 1972
123 : 7022, // International, 1924 (Hayford, 1909)
124 : 7034, // Clarke, 1880
125 : 7008, // Clarke, 1866 (NAD1927)
126 : 7015, // Everest, 1830
127 : 7004, // Bessel, 1841
128 : 7001, // Airy, 1830
129 : 7030 // WGS, 1984 (GPS)
130 : };
131 :
132 : #define NUMBER_OF_ELLIPSOIDS (sizeof(aoEllips)/sizeof(aoEllips[0]))
133 :
134 : /************************************************************************/
135 : /* OSRImportFromPanorama() */
136 : /************************************************************************/
137 :
138 0 : OGRErr OSRImportFromPanorama( OGRSpatialReferenceH hSRS,
139 : long iProjSys, long iDatum, long iEllips,
140 : double *padfPrjParams )
141 :
142 : {
143 0 : VALIDATE_POINTER1( hSRS, "OSRImportFromPanorama", CE_Failure );
144 :
145 : return ((OGRSpatialReference *) hSRS)->importFromPanorama( iProjSys,
146 : iDatum,iEllips,
147 0 : padfPrjParams );
148 : }
149 :
150 : /************************************************************************/
151 : /* importFromPanorama() */
152 : /************************************************************************/
153 :
154 : /**
155 : * Import coordinate system from "Panorama" GIS projection definition.
156 : *
157 : * This method will import projection definition in style, used by
158 : * "Panorama" GIS.
159 : *
160 : * This function is the equivalent of the C function OSRImportFromPanorama().
161 : *
162 : * @param iProjSys Input projection system code, used in GIS "Panorama".
163 : *
164 : * <h4>Supported Projections</h4>
165 : * <pre>
166 : * 1: Gauss-Kruger (Transverse Mercator)
167 : * 2: Lambert Conformal Conic 2SP
168 : * 5: Stereographic
169 : * 6: Azimuthal Equidistant (Postel)
170 : * 8: Mercator
171 : * 10: Polyconic
172 : * 13: Polar Stereographic
173 : * 15: Gnomonic
174 : * 17: Universal Transverse Mercator (UTM)
175 : * 18: Wagner I (Kavraisky VI)
176 : * 19: Mollweide
177 : * 20: Equidistant Conic
178 : * 24: Lambert Azimuthal Equal Area
179 : * 27: Equirectangular
180 : * 28: Cylindrical Equal Area (Lambert)
181 : * 29: International Map of the World Polyconic
182 : * </pre>
183 : *
184 : * @param iDatum Input coordinate system.
185 : *
186 : * <h4>Supported Datums</h4>
187 : * <pre>
188 : * 1: Pulkovo, 1942
189 : * 2: WGS, 1984
190 : * 3: OSGB 1936 (British National Grid)
191 : * 9: Pulkovo, 1995
192 : * </pre>
193 : *
194 : * @param iEllips Input spheroid.
195 : *
196 : * <h4>Supported Spheroids</h4>
197 : * <pre>
198 : * 1: Krassovsky, 1940
199 : * 2: WGS, 1972
200 : * 3: International, 1924 (Hayford, 1909)
201 : * 4: Clarke, 1880
202 : * 5: Clarke, 1866 (NAD1927)
203 : * 6: Everest, 1830
204 : * 7: Bessel, 1841
205 : * 8: Airy, 1830
206 : * 9: WGS, 1984 (GPS)
207 : * </pre>
208 : *
209 : * @param padfPrjParams Array of 8 coordinate system parameters:
210 : *
211 : * <pre>
212 : * [0] Latitude of the first standard parallel (radians)
213 : * [1] Latitude of the second standard parallel (radians)
214 : * [2] Latitude of center of projection (radians)
215 : * [3] Longitude of center of projection (radians)
216 : * [4] Scaling factor
217 : * [5] False Easting
218 : * [6] False Northing
219 : * [7] Zone number
220 : * </pre>
221 : *
222 : * Particular projection uses different parameters, unused ones may be set to
223 : * zero. If NULL supplied instead of array pointer default values will be used
224 : * (i.e., zeroes).
225 : *
226 : * @return OGRERR_NONE on success or an error code in case of failure.
227 : */
228 :
229 15 : OGRErr OGRSpatialReference::importFromPanorama( long iProjSys, long iDatum,
230 : long iEllips,
231 : double *padfPrjParams )
232 :
233 : {
234 15 : Clear();
235 :
236 : /* -------------------------------------------------------------------- */
237 : /* Use safe defaults if projection parameters are not supplied. */
238 : /* -------------------------------------------------------------------- */
239 15 : int bProjAllocated = FALSE;
240 :
241 15 : if( padfPrjParams == NULL )
242 : {
243 : int i;
244 :
245 0 : padfPrjParams = (double *)CPLMalloc( 8 * sizeof(double) );
246 0 : if ( !padfPrjParams )
247 0 : return OGRERR_NOT_ENOUGH_MEMORY;
248 0 : for ( i = 0; i < 7; i++ )
249 0 : padfPrjParams[i] = 0.0;
250 0 : bProjAllocated = TRUE;
251 : }
252 :
253 : /* -------------------------------------------------------------------- */
254 : /* Operate on the basis of the projection code. */
255 : /* -------------------------------------------------------------------- */
256 15 : switch ( iProjSys )
257 : {
258 : case PAN_PROJ_NONE:
259 7 : break;
260 :
261 : case PAN_PROJ_UTM:
262 : {
263 : long nZone;
264 :
265 5 : if ( padfPrjParams[7] == 0.0 )
266 5 : nZone = (long)TO_ZONE(padfPrjParams[3]);
267 : else
268 0 : nZone = (long) padfPrjParams[7];
269 :
270 : // XXX: no way to determine south hemisphere. Always assume
271 : // nothern hemisphere.
272 5 : SetUTM( nZone, TRUE );
273 : }
274 5 : break;
275 :
276 : case PAN_PROJ_WAG1:
277 : SetWagner( 1, 0.0,
278 0 : padfPrjParams[5], padfPrjParams[6] );
279 0 : break;
280 :
281 : case PAN_PROJ_MERCAT:
282 0 : SetMercator( TO_DEGREES * padfPrjParams[0],
283 0 : TO_DEGREES * padfPrjParams[3],
284 : padfPrjParams[4],
285 0 : padfPrjParams[5], padfPrjParams[6] );
286 0 : break;
287 :
288 : case PAN_PROJ_PS:
289 0 : SetPS( TO_DEGREES * padfPrjParams[2],
290 0 : TO_DEGREES * padfPrjParams[3],
291 : padfPrjParams[4],
292 0 : padfPrjParams[5], padfPrjParams[6] );
293 0 : break;
294 :
295 : case PAN_PROJ_POLYC:
296 0 : SetPolyconic( TO_DEGREES * padfPrjParams[2],
297 0 : TO_DEGREES * padfPrjParams[3],
298 0 : padfPrjParams[5], padfPrjParams[6] );
299 0 : break;
300 :
301 : case PAN_PROJ_EC:
302 0 : SetEC( TO_DEGREES * padfPrjParams[0],
303 0 : TO_DEGREES * padfPrjParams[1],
304 0 : TO_DEGREES * padfPrjParams[2],
305 0 : TO_DEGREES * padfPrjParams[3],
306 0 : padfPrjParams[5], padfPrjParams[6] );
307 0 : break;
308 :
309 : case PAN_PROJ_LCC:
310 0 : SetLCC( TO_DEGREES * padfPrjParams[0],
311 0 : TO_DEGREES * padfPrjParams[1],
312 0 : TO_DEGREES * padfPrjParams[2],
313 0 : TO_DEGREES * padfPrjParams[3],
314 0 : padfPrjParams[5], padfPrjParams[6] );
315 0 : break;
316 :
317 : case PAN_PROJ_TM:
318 : {
319 : // XXX: we need zone number to compute false easting
320 : // parameter, because usually it is not contained in the
321 : // "Panorama" projection definition.
322 : // FIXME: what to do with negative values?
323 : long nZone;
324 : double dfCenterLong;
325 :
326 3 : if ( padfPrjParams[7] == 0.0 )
327 : {
328 0 : nZone = (long)TO_ZONE(padfPrjParams[3]);
329 0 : dfCenterLong = TO_DEGREES * padfPrjParams[3];
330 : }
331 : else
332 : {
333 3 : nZone = (long) padfPrjParams[7];
334 3 : dfCenterLong = 6 * nZone - 3;
335 : }
336 :
337 3 : padfPrjParams[5] = nZone * 1000000.0 + 500000.0;
338 3 : padfPrjParams[4] = 1.0;
339 3 : SetTM( TO_DEGREES * padfPrjParams[2],
340 : dfCenterLong,
341 : padfPrjParams[4],
342 6 : padfPrjParams[5], padfPrjParams[6] );
343 : }
344 3 : break;
345 :
346 : case PAN_PROJ_STEREO:
347 0 : SetStereographic( TO_DEGREES * padfPrjParams[2],
348 0 : TO_DEGREES * padfPrjParams[3],
349 : padfPrjParams[4],
350 0 : padfPrjParams[5], padfPrjParams[6] );
351 0 : break;
352 :
353 : case PAN_PROJ_AE:
354 0 : SetAE( TO_DEGREES * padfPrjParams[0],
355 0 : TO_DEGREES * padfPrjParams[3],
356 0 : padfPrjParams[5], padfPrjParams[6] );
357 0 : break;
358 :
359 : case PAN_PROJ_GNOMON:
360 0 : SetGnomonic( TO_DEGREES * padfPrjParams[2],
361 0 : TO_DEGREES * padfPrjParams[3],
362 0 : padfPrjParams[5], padfPrjParams[6] );
363 0 : break;
364 :
365 : case PAN_PROJ_MOLL:
366 0 : SetMollweide( TO_DEGREES * padfPrjParams[3],
367 0 : padfPrjParams[5], padfPrjParams[6] );
368 0 : break;
369 :
370 : case PAN_PROJ_LAEA:
371 0 : SetLAEA( TO_DEGREES * padfPrjParams[0],
372 0 : TO_DEGREES * padfPrjParams[3],
373 0 : padfPrjParams[5], padfPrjParams[6] );
374 0 : break;
375 :
376 : case PAN_PROJ_EQC:
377 0 : SetEquirectangular( TO_DEGREES * padfPrjParams[0],
378 0 : TO_DEGREES * padfPrjParams[3],
379 0 : padfPrjParams[5], padfPrjParams[6] );
380 0 : break;
381 :
382 : case PAN_PROJ_CEA:
383 0 : SetCEA( TO_DEGREES * padfPrjParams[0],
384 0 : TO_DEGREES * padfPrjParams[3],
385 0 : padfPrjParams[5], padfPrjParams[6] );
386 0 : break;
387 :
388 : case PAN_PROJ_IMWP:
389 0 : SetIWMPolyconic( TO_DEGREES * padfPrjParams[0],
390 0 : TO_DEGREES * padfPrjParams[1],
391 0 : TO_DEGREES * padfPrjParams[3],
392 0 : padfPrjParams[5], padfPrjParams[6] );
393 0 : break;
394 :
395 : default:
396 0 : CPLDebug( "OSR_Panorama", "Unsupported projection: %ld", iProjSys );
397 : SetLocalCS( CPLString().Printf("\"Panorama\" projection number %ld",
398 0 : iProjSys) );
399 : break;
400 :
401 : }
402 :
403 : /* -------------------------------------------------------------------- */
404 : /* Try to translate the datum/spheroid. */
405 : /* -------------------------------------------------------------------- */
406 :
407 15 : if ( !IsLocal() )
408 : {
409 22 : if ( iDatum > 0 && iDatum < NUMBER_OF_DATUMS && aoDatums[iDatum] )
410 : {
411 7 : OGRSpatialReference oGCS;
412 7 : oGCS.importFromEPSG( aoDatums[iDatum] );
413 7 : CopyGeogCSFrom( &oGCS );
414 : }
415 :
416 16 : else if ( iEllips > 0
417 : && iEllips < (long)NUMBER_OF_ELLIPSOIDS
418 4 : && aoEllips[iEllips] )
419 : {
420 4 : char *pszName = NULL;
421 : double dfSemiMajor, dfInvFlattening;
422 :
423 4 : if ( OSRGetEllipsoidInfo( aoEllips[iEllips], &pszName,
424 : &dfSemiMajor, &dfInvFlattening ) == OGRERR_NONE )
425 : {
426 : SetGeogCS( CPLString().Printf(
427 : "Unknown datum based upon the %s ellipsoid",
428 : pszName ),
429 : CPLString().Printf(
430 : "Not specified (based on %s spheroid)", pszName ),
431 : pszName, dfSemiMajor, dfInvFlattening,
432 4 : NULL, 0.0, NULL, 0.0 );
433 4 : SetAuthority( "SPHEROID", "EPSG", aoEllips[iEllips] );
434 : }
435 : else
436 : {
437 : CPLError( CE_Warning, CPLE_AppDefined,
438 : "Failed to lookup ellipsoid code %ld, likely due to"
439 : " missing GDAL gcs.csv\n"
440 0 : " file. Falling back to use Pulkovo 42.", iEllips );
441 0 : SetWellKnownGeogCS( "EPSG:4284" );
442 : }
443 :
444 4 : if ( pszName )
445 4 : CPLFree( pszName );
446 : }
447 :
448 : else
449 : {
450 : CPLError( CE_Warning, CPLE_AppDefined,
451 : "Wrong datum code %ld. Supported datums are 1--%ld only.\n"
452 : "Falling back to use Pulkovo 42.",
453 4 : iDatum, NUMBER_OF_DATUMS - 1 );
454 4 : SetWellKnownGeogCS( "EPSG:4284" );
455 : }
456 : }
457 :
458 : /* -------------------------------------------------------------------- */
459 : /* Grid units translation */
460 : /* -------------------------------------------------------------------- */
461 15 : if( IsLocal() || IsProjected() )
462 8 : SetLinearUnits( SRS_UL_METER, 1.0 );
463 :
464 15 : FixupOrdering();
465 :
466 15 : if ( bProjAllocated && padfPrjParams )
467 0 : CPLFree( padfPrjParams );
468 :
469 15 : return OGRERR_NONE;
470 : }
471 :
472 : /************************************************************************/
473 : /* OSRExportToPanorama() */
474 : /************************************************************************/
475 :
476 0 : OGRErr OSRExportToPanorama( OGRSpatialReferenceH hSRS,
477 : long *piProjSys, long *piDatum, long *piEllips,
478 : long *piZone, double *padfPrjParams )
479 :
480 : {
481 0 : VALIDATE_POINTER1( hSRS, "OSRExportToPanorama", CE_Failure );
482 0 : VALIDATE_POINTER1( piProjSys, "OSRExportToPanorama", CE_Failure );
483 0 : VALIDATE_POINTER1( piDatum, "OSRExportToPanorama", CE_Failure );
484 0 : VALIDATE_POINTER1( piEllips, "OSRExportToPanorama", CE_Failure );
485 0 : VALIDATE_POINTER1( padfPrjParams, "OSRExportToPanorama", CE_Failure );
486 :
487 : return ((OGRSpatialReference *) hSRS)->exportToPanorama( piProjSys,
488 : piDatum, piEllips,
489 : piZone,
490 0 : padfPrjParams );
491 : }
492 :
493 : /************************************************************************/
494 : /* exportToPanorama() */
495 : /************************************************************************/
496 :
497 : /**
498 : * Export coordinate system in "Panorama" GIS projection definition.
499 : *
500 : * This method is the equivalent of the C function OSRExportToPanorama().
501 : *
502 : * @param piProjSys Pointer to variable, where the projection system code will
503 : * be returned.
504 : *
505 : * @param piDatum Pointer to variable, where the coordinate system code will
506 : * be returned.
507 : *
508 : * @param piEllips Pointer to variable, where the spheroid code will be
509 : * returned.
510 : *
511 : * @param piZone Pointer to variable, where the zone for UTM projection
512 : * system will be returned.
513 : *
514 : * @param padfPrjParams an existing 7 double buffer into which the
515 : * projection parameters will be placed. See importFromPanorama()
516 : * for the list of parameters.
517 : *
518 : * @return OGRERR_NONE on success or an error code on failure.
519 : */
520 :
521 6 : OGRErr OGRSpatialReference::exportToPanorama( long *piProjSys, long *piDatum,
522 : long *piEllips, long *piZone,
523 : double *padfPrjParams ) const
524 :
525 : {
526 6 : CPLAssert( padfPrjParams );
527 :
528 6 : const char *pszProjection = GetAttrValue("PROJECTION");
529 :
530 : /* -------------------------------------------------------------------- */
531 : /* Fill all projection parameters with zero. */
532 : /* -------------------------------------------------------------------- */
533 : int i;
534 :
535 6 : *piDatum = 0L;
536 6 : *piEllips = 0L;
537 6 : *piZone = 0L;
538 48 : for ( i = 0; i < 7; i++ )
539 42 : padfPrjParams[i] = 0.0;
540 :
541 : /* ==================================================================== */
542 : /* Handle the projection definition. */
543 : /* ==================================================================== */
544 6 : if( IsLocal() )
545 0 : *piProjSys = PAN_PROJ_NONE;
546 :
547 6 : else if( pszProjection == NULL )
548 : {
549 : #ifdef DEBUG
550 : CPLDebug( "OSR_Panorama",
551 5 : "Empty projection definition, considered as Geographic" );
552 : #endif
553 5 : *piProjSys = PAN_PROJ_NONE;
554 : }
555 :
556 1 : else if( EQUAL(pszProjection, SRS_PT_MERCATOR_1SP) )
557 : {
558 0 : *piProjSys = PAN_PROJ_MERCAT;
559 0 : padfPrjParams[3] =
560 0 : TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
561 : padfPrjParams[0] =
562 0 : TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
563 0 : padfPrjParams[4] = GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
564 0 : padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
565 0 : padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
566 : }
567 :
568 1 : else if( EQUAL(pszProjection, SRS_PT_POLAR_STEREOGRAPHIC) )
569 : {
570 0 : *piProjSys = PAN_PROJ_PS;
571 0 : padfPrjParams[3] =
572 0 : TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
573 0 : padfPrjParams[2] =
574 0 : TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
575 0 : padfPrjParams[4] = GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
576 0 : padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
577 0 : padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
578 : }
579 :
580 1 : else if( EQUAL(pszProjection, SRS_PT_POLYCONIC) )
581 : {
582 0 : *piProjSys = PAN_PROJ_POLYC;
583 0 : padfPrjParams[3] =
584 0 : TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
585 0 : padfPrjParams[2] =
586 0 : TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
587 0 : padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
588 0 : padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
589 : }
590 :
591 1 : else if( EQUAL(pszProjection, SRS_PT_EQUIDISTANT_CONIC) )
592 : {
593 0 : *piProjSys = PAN_PROJ_EC;
594 : padfPrjParams[0] =
595 0 : TO_RADIANS * GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 );
596 0 : padfPrjParams[1] =
597 0 : TO_RADIANS * GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 );
598 0 : padfPrjParams[3] =
599 0 : TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
600 0 : padfPrjParams[2] =
601 0 : TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
602 0 : padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
603 0 : padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
604 : }
605 :
606 1 : else if( EQUAL(pszProjection, SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP) )
607 : {
608 0 : *piProjSys = PAN_PROJ_LCC;
609 : padfPrjParams[0] =
610 0 : TO_RADIANS * GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 );
611 0 : padfPrjParams[1] =
612 0 : TO_RADIANS * GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 );
613 0 : padfPrjParams[3] =
614 0 : TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
615 0 : padfPrjParams[2] =
616 0 : TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
617 0 : padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
618 0 : padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
619 : }
620 :
621 1 : else if( EQUAL(pszProjection, SRS_PT_TRANSVERSE_MERCATOR) )
622 : {
623 : int bNorth;
624 :
625 1 : *piZone = GetUTMZone( &bNorth );
626 :
627 1 : if( *piZone != 0 )
628 : {
629 1 : *piProjSys = PAN_PROJ_UTM;
630 1 : if( !bNorth )
631 0 : *piZone = - *piZone;
632 : }
633 : else
634 : {
635 0 : *piProjSys = PAN_PROJ_TM;
636 0 : padfPrjParams[3] =
637 0 : TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
638 0 : padfPrjParams[2] =
639 0 : TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
640 0 : padfPrjParams[4] =
641 0 : GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
642 0 : padfPrjParams[5] =
643 0 : GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
644 0 : padfPrjParams[6] =
645 0 : GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
646 : }
647 : }
648 :
649 0 : else if( EQUAL(pszProjection, SRS_PT_WAGNER_I) )
650 : {
651 0 : *piProjSys = PAN_PROJ_WAG1;
652 0 : padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
653 0 : padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
654 : }
655 :
656 0 : else if( EQUAL(pszProjection, SRS_PT_STEREOGRAPHIC) )
657 : {
658 0 : *piProjSys = PAN_PROJ_STEREO;
659 0 : padfPrjParams[3] =
660 0 : TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
661 0 : padfPrjParams[2] =
662 0 : TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
663 0 : padfPrjParams[4] = GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
664 0 : padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
665 0 : padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
666 : }
667 :
668 0 : else if( EQUAL(pszProjection, SRS_PT_AZIMUTHAL_EQUIDISTANT) )
669 : {
670 0 : *piProjSys = PAN_PROJ_AE;
671 0 : padfPrjParams[3] =
672 0 : TO_RADIANS * GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 );
673 : padfPrjParams[0] =
674 0 : TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, 0.0 );
675 0 : padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
676 0 : padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
677 : }
678 :
679 0 : else if( EQUAL(pszProjection, SRS_PT_GNOMONIC) )
680 : {
681 0 : *piProjSys = PAN_PROJ_GNOMON;
682 0 : padfPrjParams[3] =
683 0 : TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
684 0 : padfPrjParams[2] =
685 0 : TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
686 0 : padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
687 0 : padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
688 : }
689 :
690 0 : else if( EQUAL(pszProjection, SRS_PT_MOLLWEIDE) )
691 : {
692 0 : *piProjSys = PAN_PROJ_MOLL;
693 0 : padfPrjParams[3] =
694 0 : TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
695 0 : padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
696 0 : padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
697 : }
698 :
699 0 : else if( EQUAL(pszProjection, SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA) )
700 : {
701 0 : *piProjSys = PAN_PROJ_LAEA;
702 0 : padfPrjParams[3] =
703 0 : TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
704 : padfPrjParams[0] =
705 0 : TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
706 0 : padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
707 0 : padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
708 : }
709 :
710 0 : else if( EQUAL(pszProjection, SRS_PT_EQUIRECTANGULAR) )
711 : {
712 0 : *piProjSys = PAN_PROJ_EQC;
713 0 : padfPrjParams[3] =
714 0 : TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
715 : padfPrjParams[0] =
716 0 : TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
717 0 : padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
718 0 : padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
719 : }
720 :
721 0 : else if( EQUAL(pszProjection, SRS_PT_CYLINDRICAL_EQUAL_AREA) )
722 : {
723 0 : *piProjSys = PAN_PROJ_CEA;
724 0 : padfPrjParams[3] =
725 0 : TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
726 0 : padfPrjParams[2] =
727 0 : TO_RADIANS * GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 );
728 0 : padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
729 0 : padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
730 : }
731 :
732 0 : else if( EQUAL(pszProjection, SRS_PT_IMW_POLYCONIC) )
733 : {
734 0 : *piProjSys = PAN_PROJ_IMWP;
735 0 : padfPrjParams[3] =
736 0 : TO_RADIANS * GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
737 : padfPrjParams[0] =
738 0 : TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_1ST_POINT, 0.0 );
739 0 : padfPrjParams[1] =
740 0 : TO_RADIANS * GetNormProjParm( SRS_PP_LATITUDE_OF_2ND_POINT, 0.0 );
741 0 : padfPrjParams[5] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
742 0 : padfPrjParams[6] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
743 : }
744 :
745 : // Projection unsupported by "Panorama" GIS
746 : else
747 : {
748 : CPLDebug( "OSR_Panorama",
749 : "Projection \"%s\" unsupported by \"Panorama\" GIS. "
750 0 : "Geographic system will be used.", pszProjection );
751 0 : *piProjSys = PAN_PROJ_NONE;
752 : }
753 :
754 : /* -------------------------------------------------------------------- */
755 : /* Translate the datum. */
756 : /* -------------------------------------------------------------------- */
757 6 : const char *pszDatum = GetAttrValue( "DATUM" );
758 :
759 6 : if ( pszDatum == NULL )
760 : {
761 0 : *piDatum = PAN_DATUM_NONE;
762 0 : *piEllips = PAN_ELLIPSOID_NONE;
763 : }
764 6 : else if ( EQUAL( pszDatum, "Pulkovo_1942" ) )
765 : {
766 0 : *piDatum = PAN_DATUM_PULKOVO42;
767 0 : *piEllips = PAN_ELLIPSOID_KRASSOVSKY;
768 : }
769 6 : else if( EQUAL( pszDatum, SRS_DN_WGS84 ) )
770 : {
771 5 : *piDatum = PAN_DATUM_WGS84;
772 5 : *piEllips = PAN_ELLIPSOID_WGS84;
773 : }
774 :
775 : // If not found well known datum, translate ellipsoid
776 : else
777 : {
778 1 : double dfSemiMajor = GetSemiMajor();
779 1 : double dfInvFlattening = GetInvFlattening();
780 : size_t i;
781 :
782 : #ifdef DEBUG
783 : CPLDebug( "OSR_Panorama",
784 : "Datum \"%s\" unsupported by \"Panorama\" GIS. "
785 1 : "Trying to translate an ellipsoid definition.", pszDatum );
786 : #endif
787 :
788 6 : for ( i = 0; i < NUMBER_OF_ELLIPSOIDS; i++ )
789 : {
790 6 : if ( aoEllips[i] )
791 : {
792 5 : double dfSM = 0.0;
793 5 : double dfIF = 1.0;
794 :
795 5 : if ( OSRGetEllipsoidInfo( aoEllips[i], NULL,
796 : &dfSM, &dfIF ) == OGRERR_NONE
797 : && CPLIsEqual(dfSemiMajor, dfSM)
798 : && CPLIsEqual(dfInvFlattening, dfIF) )
799 : {
800 1 : *piEllips = i;
801 1 : break;
802 : }
803 : }
804 : }
805 :
806 1 : if ( i == NUMBER_OF_ELLIPSOIDS ) // Didn't found matches.
807 : {
808 : #ifdef DEBUG
809 : CPLDebug( "OSR_Panorama",
810 : "Ellipsoid \"%s\" unsupported by \"Panorama\" GIS.",
811 0 : pszDatum );
812 : #endif
813 0 : *piDatum = PAN_DATUM_NONE;
814 0 : *piEllips = PAN_ELLIPSOID_NONE;
815 : }
816 : }
817 :
818 6 : return OGRERR_NONE;
819 : }
820 :
|