LTP GCOV extension - code coverage report
Current view: directory - ogr - ogr_srs_panorama.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 223
Code covered: 34.1 % Executed lines: 76

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

Generated by: LTP GCOV extension version 1.5