LTP GCOV extension - code coverage report
Current view: directory - ogr - ogr_srs_pci.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 315
Code covered: 49.8 % Executed lines: 157

       1                 : /******************************************************************************
       2                 :  * $Id: ogr_srs_pci.cpp 18735 2010-02-05 16:07:10Z warmerdam $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  OGRSpatialReference translation to/from PCI georeferencing
       6                 :  *           information.
       7                 :  * Author:   Andrey Kiselev, dron@ak4719.spb.edu
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2003, 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_pci.cpp 18735 2010-02-05 16:07:10Z warmerdam $");
      37                 : 
      38                 : typedef struct 
      39                 : {
      40                 :     const char  *pszPCIDatum;
      41                 :     int         nEPSGCode;
      42                 :     double      dfSemiMajor;
      43                 :     double      dfSemiMinor;
      44                 : } PCIDatums;
      45                 : 
      46                 : static const PCIDatums aoDatums[] =
      47                 : {
      48                 :     { "D-01", 4267, 0, 0 },   // NAD27 (USA, NADCON)
      49                 :     { "D-03", 4267, 0, 0 },   // NAD27 (Canada, NTv1)
      50                 :     { "D-02", 4269, 0, 0 },   // NAD83 (USA, NADCON)
      51                 :     { "D-04", 4269, 0, 0 },   // NAD83 (Canada, NTv1)
      52                 :     { "D000", 4326, 0, 0 },   // WGS 1984
      53                 :     { "D001", 4322, 0, 0 },   // WGS 1972
      54                 :     { "D008", 4296, 0, 0 },   // Sudan
      55                 :     { "D013", 4601, 0, 0 },   // Antigua Island Astro 1943
      56                 :     { "D029", 4202, 0, 0 },   // Australian Geodetic 1966
      57                 :     { "D030", 4203, 0, 0 },   // Australian Geodetic 1984
      58                 :     { "D033", 4216, 0, 0 },   // Bermuda 1957
      59                 :     { "D034", 4165, 0, 0 },   // Bissau
      60                 :     { "D036", 4219, 0, 0 },   // Bukit Rimpah
      61                 :     { "D038", 4221, 0, 0 },   // Campo Inchauspe
      62                 :     { "D040", 4222, 0, 0 },   // Cape
      63                 :     { "D042", 4223, 0, 0 },   // Carthage
      64                 :     { "D044", 4224, 0, 0 },   // Chua Astro
      65                 :     { "D045", 4225, 0, 0 },   // Corrego Alegre
      66                 :     { "D046", 4155, 0, 0 },   // Dabola (Guinea)
      67                 :     { "D066", 4272, 0, 0 },   // Geodetic Datum 1949 (New Zealand)
      68                 :     { "D071", 4255, 0, 0 },   // Herat North (Afghanistan)
      69                 :     { "D077", 4239, 0, 0 },   // Indian 1954 (Thailand, Vietnam)
      70                 :     { "D078", 4240, 0, 0 },   // Indian 1975 (Thailand)
      71                 :     { "D083", 4244, 0, 0 },   // Kandawala (Sri Lanka)
      72                 :     { "D085", 4245, 0, 0 },   // Kertau 1948 (West Malaysia & Singapore)
      73                 :     { "D088", 4250, 0, 0 },   // Leigon (Ghana)
      74                 :     { "D089", 4251, 0, 0 },   // Liberia 1964 (Liberia)
      75                 :     { "D092", 4256, 0, 0 },   // Mahe 1971 (Mahe Island)
      76                 :     { "D093", 4262, 0, 0 },   // Massawa (Ethiopia (Eritrea))
      77                 :     { "D094", 4261, 0, 0 },   // Merchich (Morocco)
      78                 :     { "D098", 4604, 0, 0 },   // Montserrat Island Astro 1958 (Montserrat (Leeward Islands))
      79                 :     { "D110", 4267, 0, 0 },   // NAD27 / Alaska
      80                 :     { "D139", 4282, 0, 0 },   // Pointe Noire 1948 (Congo)
      81                 :     { "D140", 4615, 0, 0 },   // Porto Santo 1936 (Porto Santo, Madeira Islands)
      82                 :     { "D151", 4139, 0, 0 },   // Puerto Rico (Puerto Rico, Virgin Islands)
      83                 :     { "D153", 4287, 0, 0 },   // Qornoq (Greenland (South))
      84                 :     { "D158", 4292, 0, 0 },   // Sapper Hill 1943 (East Falkland Island)
      85                 :     { "D159", 4293, 0, 0 },   // Schwarzeck (Namibia)
      86                 :     { "D160", 4616, 0, 0 },   // Selvagem Grande 1938 (Salvage Islands)
      87                 :     { "D176", 4297, 0, 0 },   // Tananarive Observatory 1925 (Madagascar)
      88                 :     { "D177", 4298, 0, 0 },   // Timbalai 1948 (Brunei, East Malaysia (Sabah, Sarawak))
      89                 :     { "D187", 4309, 0, 0 },   // Yacare (Uruguay)
      90                 :     { "D188", 4311, 0, 0 },   // Zanderij (Suriname)
      91                 :     { "D401", 4124, 0, 0 },   // RT90 (Sweden)
      92                 :     { "D501", 4312, 0, 0 },   // MGI (Hermannskogel, Austria)
      93                 :     { NULL, 0 }
      94                 : };
      95                 : 
      96                 : static const PCIDatums aoEllips[] =
      97                 : {
      98                 :     { "E000", 7008, 0, 0 },     // Clarke, 1866 (NAD1927)
      99                 :     { "E001", 7034, 0, 0 },     // Clarke, 1880
     100                 :     { "E002", 7004, 0, 0 },     // Bessel, 1841
     101                 :     { "E003", 0, 6378157.5,6356772.2 },   // New International, 1967
     102                 :     { "E004", 7022, 0, 0 },     // International, 1924 (Hayford, 1909)
     103                 :     { "E005", 7043, 0, 0 },     // WGS, 1972
     104                 :     { "E006", 7042, 0, 0 },     // Everest, 1830
     105                 :     { "E007", 0, 6378145.,6356759.769356 }, // WGS, 1966
     106                 :     { "E008", 7019, 0, 0 },     // GRS, 1980 (NAD1983)
     107                 :     { "E009", 7001, 0, 0 },     // Airy, 1830
     108                 :     { "E010", 7018, 0, 0 },     // Modified Everest 
     109                 :     { "E011", 7002, 0, 0 },     // Modified Airy
     110                 :     { "E012", 7030, 0, 0 },     // WGS, 1984 (GPS)
     111                 :     { "E013", 0, 6378155.,6356773.3205 }, // Southeast Asia
     112                 :     { "E014", 7003, 0, 0 },     // Australian National, 1965
     113                 :     { "E015", 7024, 0, 0 },     // Krassovsky, 1940
     114                 :     { "E016", 7053, 0, 0 },     // Hough
     115                 :     { "E017", 0, 6378166.,6356784.283666 }, // Mercury, 1960
     116                 :     { "E018", 0, 6378150.,6356768.337303 }, //  Modified Mercury, 1968
     117                 :     { "E019", 7052, 0, 0},      // normal sphere
     118                 :     { "E333", 7046, 0, 0 },     // Bessel 1841 (Japan By Law)
     119                 :     { "E600", 0, 6378144.0,6356759.0 }, // D-PAF (Orbits)
     120                 :     { "E900", 7006, 0, 0 },     // Bessel, 1841 (Namibia)
     121                 :     { "E901", 7044, 0, 0 },     // Everest, 1956
     122                 :     { "E902", 7056, 0, 0 },     // Everest, 1969
     123                 :     { "E903", 7016, 0, 0 },     // Everest (Sabah & Sarawak)
     124                 :     { "E904", 7020, 0, 0 },     // Helmert, 1906
     125                 :     { "E905", 0, 6378136.,6356751.301569 }, // SGS 85
     126                 :     { "E906", 0, 6378165.,6356783.286959 }, // WGS 60
     127                 :     { "E907", 7036, 0, 0 },     // South American, 1969
     128                 :     { "E910", 7041, 0, 0 },     // ATS77
     129                 :     { NULL, 0 }
     130                 : };
     131                 : 
     132                 : /************************************************************************/
     133                 : /*                         OSRImportFromPCI()                           */
     134                 : /************************************************************************/
     135                 : 
     136                 : /**
     137                 :  * \brief Import coordinate system from PCI projection definition.
     138                 :  *
     139                 :  * This function is the same as OGRSpatialReference::importFromPCI().
     140                 :  */
     141                 : 
     142                 : OGRErr OSRImportFromPCI( OGRSpatialReferenceH hSRS, const char *pszProj,
     143               4 :                          const char *pszUnits, double *padfPrjParams )
     144                 : 
     145                 : {
     146               4 :     VALIDATE_POINTER1( hSRS, "OSRImportFromPCI", CE_Failure );
     147                 : 
     148                 :     return ((OGRSpatialReference *) hSRS)->importFromPCI( pszProj,
     149                 :                                                           pszUnits,
     150               4 :                                                           padfPrjParams );
     151                 : }
     152                 : 
     153                 : /************************************************************************/
     154                 : /*                          importFromPCI()                             */
     155                 : /************************************************************************/
     156                 : 
     157                 : /**
     158                 :  * \brief Import coordinate system from PCI projection definition.
     159                 :  *
     160                 :  * PCI software uses 16-character string to specify coordinate system
     161                 :  * and datum/ellipsoid. You should supply at least this string to the
     162                 :  * importFromPCI() function.
     163                 :  *
     164                 :  * This function is the equivalent of the C function OSRImportFromPCI().
     165                 :  *
     166                 :  * @param pszProj NULL terminated string containing the definition. Looks
     167                 :  * like "pppppppppppp Ennn" or "pppppppppppp Dnnn", where "pppppppppppp" is
     168                 :  * a projection code, "Ennn" is an ellipsoid code, "Dnnn" --- a datum code.
     169                 :  *
     170                 :  * @param pszUnits Grid units code ("DEGREE" or "METRE"). If NULL "METRE" will
     171                 :  * be used.
     172                 :  *
     173                 :  * @param padfPrjParams Array of 17 coordinate system parameters:
     174                 :  *
     175                 :  * [0]  Spheroid semi major axis
     176                 :  * [1]  Spheroid semi minor axis
     177                 :  * [2]  Reference Longitude
     178                 :  * [3]  Reference Latitude
     179                 :  * [4]  First Standard Parallel
     180                 :  * [5]  Second Standard Parallel
     181                 :  * [6]  False Easting
     182                 :  * [7]  False Northing
     183                 :  * [8]  Scale Factor
     184                 :  * [9]  Height above sphere surface
     185                 :  * [10] Longitude of 1st point on center line
     186                 :  * [11] Latitude of 1st point on center line
     187                 :  * [12] Longitude of 2nd point on center line
     188                 :  * [13] Latitude of 2nd point on center line
     189                 :  * [14] Azimuth east of north for center line
     190                 :  * [15] Landsat satellite number
     191                 :  * [16] Landsat path number
     192                 :  *
     193                 :  * Particular projection uses different parameters, unused ones may be set to
     194                 :  * zero. If NULL suppliet instead of array pointer default values will be
     195                 :  * used (i.e., zeroes).
     196                 :  *
     197                 :  * @return OGRERR_NONE on success or an error code in case of failure. 
     198                 :  */
     199                 : 
     200                 : OGRErr OGRSpatialReference::importFromPCI( const char *pszProj,
     201                 :                                            const char *pszUnits,
     202               6 :                                            double *padfPrjParams )
     203                 : 
     204                 : {
     205               6 :     Clear();
     206                 : 
     207               6 :     if( pszProj == NULL || CPLStrnlen(pszProj, 16) < 16 )
     208               0 :         return OGRERR_CORRUPT_DATA;
     209                 : 
     210                 : #ifdef DEBUG
     211               6 :     CPLDebug( "OSR_PCI", "Trying to import projection \"%s\"", pszProj );
     212                 : #endif
     213                 : 
     214                 : /* -------------------------------------------------------------------- */
     215                 : /*      Use safe defaults if projection parameters are not supplied.    */
     216                 : /* -------------------------------------------------------------------- */
     217               6 :     int     bProjAllocated = FALSE;
     218                 : 
     219               6 :     if( padfPrjParams == NULL )
     220                 :     {
     221                 :         int     i;
     222                 : 
     223               0 :         padfPrjParams = (double *)CPLMalloc( 17 * sizeof(double) );
     224               0 :         if ( !padfPrjParams )
     225               0 :             return OGRERR_NOT_ENOUGH_MEMORY;
     226               0 :         for ( i = 0; i < 17; i++ )
     227               0 :             padfPrjParams[i] = 0.0;
     228               0 :         bProjAllocated = TRUE;
     229                 :     }
     230                 : 
     231                 : /* -------------------------------------------------------------------- */
     232                 : /*      Extract and "normalize" the earthmodel to look like E001,       */
     233                 : /*      D-02 or D109.                                                   */
     234                 : /* -------------------------------------------------------------------- */
     235                 :     char szEarthModel[5];
     236                 :     const char *pszEM;
     237               6 :     int bIsNAD27 = FALSE;
     238                 : 
     239               6 :     strcpy( szEarthModel, "" );
     240               6 :     pszEM = pszProj + strlen(pszProj) - 1;
     241              30 :     while( pszEM != pszProj )
     242                 :     {
     243              24 :         if( *pszEM == 'e' || *pszEM == 'E' || *pszEM == 'd' || *pszEM == 'D' )
     244                 :         {
     245               6 :             int nCode = atoi(pszEM+1);
     246                 : 
     247               6 :             if( nCode >= -99 && nCode <= 999 )
     248               6 :                 sprintf( szEarthModel, "%c%03d", toupper(*pszEM), nCode );
     249                 : 
     250               6 :             break;
     251                 :         }
     252                 : 
     253              18 :         pszEM--;
     254                 :     }
     255                 : 
     256               6 :     if( EQUAL(pszEM,"E000") 
     257                 :         || EQUAL(pszEM,"D-01")
     258                 :         || EQUAL(pszEM,"D-03")
     259                 :         || EQUAL(pszEM,"D-07")
     260                 :         || EQUAL(pszEM,"D-09")
     261                 :         || EQUAL(pszEM,"D-11")
     262                 :         || EQUAL(pszEM,"D-13")
     263                 :         || EQUAL(pszEM,"D-17") )
     264               2 :         bIsNAD27 = TRUE;
     265                 :     
     266                 : /* -------------------------------------------------------------------- */
     267                 : /*      Operate on the basis of the projection name.                    */
     268                 : /* -------------------------------------------------------------------- */
     269               6 :     if( EQUALN( pszProj, "LONG/LAT", 8 ) )
     270                 :     {
     271                 :     }
     272                 :     
     273               6 :     else if( EQUALN( pszProj, "METER", 5 ) 
     274                 :              || EQUALN( pszProj, "METRE", 5 ) )
     275                 :     {
     276               0 :         SetLocalCS( "METER" );
     277               0 :         SetLinearUnits( "METER", 1.0 );
     278                 :     }
     279                 : 
     280               6 :     else if( EQUALN( pszProj, "FEET", 4 ) 
     281                 :              || EQUALN( pszProj, "FOOT", 4 ) )
     282                 :     {
     283               0 :         SetLocalCS( "FEET" );
     284               0 :         SetLinearUnits( "FEET", atof(SRS_UL_FOOT_CONV) );
     285                 :     }
     286                 : 
     287               6 :     else if( EQUALN( pszProj, "ACEA", 4 ) )
     288                 :     {
     289                 :         SetACEA( padfPrjParams[4], padfPrjParams[5],
     290                 :                  padfPrjParams[3], padfPrjParams[2],
     291               0 :                  padfPrjParams[6], padfPrjParams[7] );
     292                 :     }
     293                 : 
     294               6 :     else if( EQUALN( pszProj, "AE", 2 ) )
     295                 :     {
     296                 :         SetAE( padfPrjParams[3], padfPrjParams[2],
     297               0 :                padfPrjParams[6], padfPrjParams[7] );
     298                 :     }
     299                 : 
     300               6 :     else if( EQUALN( pszProj, "EC", 2 ) )
     301                 :     {
     302                 :         SetEC( padfPrjParams[4], padfPrjParams[5],
     303                 :                padfPrjParams[3], padfPrjParams[2],
     304               1 :                padfPrjParams[6], padfPrjParams[7] );
     305                 :     }
     306                 : 
     307               5 :     else if( EQUALN( pszProj, "ER", 2 ) )
     308                 :     {
     309                 :         // PCI and GCTP don't support natural origin lat. 
     310                 :         SetEquirectangular2( 0.0, padfPrjParams[2],
     311                 :                              padfPrjParams[3], 
     312               0 :                              padfPrjParams[6], padfPrjParams[7] );
     313                 :     }
     314                 : 
     315               5 :     else if( EQUALN( pszProj, "GNO", 3 ) )
     316                 :     {
     317                 :         SetGnomonic( padfPrjParams[3], padfPrjParams[2],
     318               0 :                      padfPrjParams[6], padfPrjParams[7] );
     319                 :     }
     320                 : 
     321                 :     // FIXME: GVNP --- General Vertical Near- Side Perspective skipped
     322                 : 
     323               5 :     else if( EQUALN( pszProj, "LAEA", 4 ) )
     324                 :     {
     325                 :         SetLAEA( padfPrjParams[3], padfPrjParams[2],
     326               0 :                  padfPrjParams[6], padfPrjParams[7] );
     327                 :     }
     328                 : 
     329               5 :     else if( EQUALN( pszProj, "LCC", 3 ) )
     330                 :     {
     331                 :         SetLCC( padfPrjParams[4], padfPrjParams[5],
     332                 :                 padfPrjParams[3], padfPrjParams[2],
     333               0 :                 padfPrjParams[6], padfPrjParams[7] );
     334                 :     }
     335                 : 
     336               5 :     else if( EQUALN( pszProj, "MC", 2 ) )
     337                 :     {
     338                 :         SetMC( padfPrjParams[3], padfPrjParams[2],
     339               0 :                padfPrjParams[6], padfPrjParams[7] );
     340                 :     }
     341                 : 
     342               5 :     else if( EQUALN( pszProj, "MER", 3 ) )
     343                 :     {
     344                 :         SetMercator( padfPrjParams[3], padfPrjParams[2],
     345                 :                      (padfPrjParams[8] != 0.0) ? padfPrjParams[9] : 1.0,
     346               0 :                      padfPrjParams[6], padfPrjParams[7] );
     347                 :     }
     348                 : 
     349               5 :     else if( EQUALN( pszProj, "OG", 2 ) )
     350                 :     {
     351                 :         SetOrthographic( padfPrjParams[3], padfPrjParams[2],
     352               0 :                          padfPrjParams[6], padfPrjParams[7] );
     353                 :     }
     354                 : 
     355                 :     // FIXME: OM --- Oblique Mercator skipped
     356                 : 
     357               5 :     else if( EQUALN( pszProj, "PC", 2 ) )
     358                 :     {
     359                 :         SetPolyconic( padfPrjParams[3], padfPrjParams[2],
     360               0 :                       padfPrjParams[6], padfPrjParams[7] );
     361                 :     }
     362                 : 
     363               5 :     else if( EQUALN( pszProj, "PS", 2 ) )
     364                 :     {
     365                 :         SetPS( padfPrjParams[3], padfPrjParams[2],
     366                 :                (padfPrjParams[8] != 0.0) ? padfPrjParams[9] : 1.0,
     367               0 :                padfPrjParams[6], padfPrjParams[7] );
     368                 :     }
     369                 : 
     370               5 :     else if( EQUALN( pszProj, "ROB", 3 ) )
     371                 :     {
     372                 :         SetRobinson( padfPrjParams[2],
     373               0 :                      padfPrjParams[6], padfPrjParams[7] );
     374                 :     }
     375                 : 
     376               5 :     else if( EQUALN( pszProj, "SG", 2 ) )
     377                 :     {
     378                 :         SetStereographic( padfPrjParams[3], padfPrjParams[2],
     379                 :                           (padfPrjParams[8] != 0.0) ? padfPrjParams[9] : 1.0,
     380               0 :                           padfPrjParams[6], padfPrjParams[7] );
     381                 :     }
     382                 : 
     383               5 :     else if( EQUALN( pszProj, "SIN", 3 ) )
     384                 :     {
     385                 :         SetSinusoidal( padfPrjParams[2],
     386               0 :                        padfPrjParams[6], padfPrjParams[7] );
     387                 :     }
     388                 : 
     389                 :     // FIXME: SOM --- Space Oblique Mercator skipped
     390                 : 
     391               5 :     else if( EQUALN( pszProj, "SPCS", 4 ) )
     392                 :     {
     393                 :         int     iZone;
     394                 : 
     395               0 :         iZone = CPLScanLong( (char *)pszProj + 5, 4 );
     396                 : 
     397               0 :         SetStatePlane( iZone, !bIsNAD27 );
     398                 :     }
     399                 : 
     400               5 :     else if( EQUALN( pszProj, "SPIF", 4 ) )
     401                 :     {
     402                 :         int     iZone;
     403                 : 
     404               0 :         iZone = CPLScanLong( (char *)pszProj + 5, 4 );
     405                 : 
     406               0 :         SetStatePlane( iZone, !bIsNAD27 );
     407                 :         SetLinearUnitsAndUpdateParameters( SRS_UL_FOOT,
     408               0 :                                            atof(SRS_UL_FOOT_CONV) );
     409                 :     }
     410                 : 
     411               5 :     else if( EQUALN( pszProj, "SPAF", 4 ) )
     412                 :     {
     413                 :         int     iZone;
     414                 : 
     415               0 :         iZone = CPLScanLong( (char *)pszProj + 5, 4 );
     416                 : 
     417               0 :         SetStatePlane( iZone, !bIsNAD27 );
     418                 :         SetLinearUnitsAndUpdateParameters( SRS_UL_US_FOOT,
     419               0 :                                            atof(SRS_UL_US_FOOT_CONV) );
     420                 :     }
     421                 : 
     422               5 :     else if( EQUALN( pszProj, "TM", 2 ) )
     423                 :     {
     424                 :         SetTM( padfPrjParams[3], padfPrjParams[2],
     425                 :                (padfPrjParams[8] != 0.0) ? padfPrjParams[9] : 1.0,
     426               0 :                padfPrjParams[6], padfPrjParams[7] );
     427                 :     }
     428                 : 
     429               5 :     else if( EQUALN( pszProj, "UTM", 3 ) )
     430                 :     {
     431               5 :         int     iZone, bNorth = TRUE;
     432                 : 
     433               5 :         iZone = CPLScanLong( (char *)pszProj + 4, 5 );;
     434               5 :         if ( iZone < 0 )
     435                 :         {
     436               0 :             iZone = -iZone;
     437               0 :             bNorth = FALSE;
     438                 :         }
     439                 : 
     440                 :         // Check for a zone letter. PCI uses, accidentally, MGRS
     441                 :         // type row lettering in its UTM projection
     442               5 :         char byZoneID = 0;
     443                 : 
     444               5 :         if( strlen(pszProj) > 10 && pszProj[10] != ' ' )
     445               2 :             byZoneID = pszProj[10];
     446                 : 
     447                 :         // Determine if the MGRS zone falls above or below the equator
     448               5 :         if (byZoneID != 0 )
     449                 :         {
     450                 :             CPLDebug("OSR_PCI", "Found MGRS zone in UTM projection string: %c",
     451               2 :                 byZoneID);
     452                 : 
     453               3 :             if (byZoneID >= 'N' && byZoneID <= 'X')
     454                 :             {
     455               1 :                 bNorth = TRUE;
     456                 :             }
     457               1 :             else if (byZoneID >= 'C' && byZoneID <= 'M')
     458                 :             {
     459               1 :                 bNorth = FALSE;
     460                 :             }
     461                 :             else
     462                 :             {
     463                 :                 // yikes, most likely we got something that was not really
     464                 :                 // an MGRS zone code so we ignore it.
     465                 :             }
     466                 :         }
     467                 :         
     468               5 :         SetUTM( iZone, bNorth );
     469                 :     }
     470                 : 
     471               0 :     else if( EQUALN( pszProj, "VDG", 3 ) )
     472                 :     {
     473                 :         SetVDG( padfPrjParams[2],
     474               0 :                 padfPrjParams[6], padfPrjParams[7] );
     475                 :     }
     476                 : 
     477                 :     else
     478                 :     {
     479               0 :         CPLDebug( "OSR_PCI", "Unsupported projection: %s", pszProj );
     480               0 :         SetLocalCS( pszProj );
     481                 :     }
     482                 : 
     483                 : /* ==================================================================== */
     484                 : /*      Translate the datum/spheroid.                                   */
     485                 : /* ==================================================================== */
     486                 : 
     487                 : /* -------------------------------------------------------------------- */
     488                 : /*      We have an earthmodel string, look it up in the datum list.     */
     489                 : /* -------------------------------------------------------------------- */
     490               6 :     if( strlen(szEarthModel) > 0 
     491                 :         && (poRoot == NULL || IsProjected() || IsGeographic()) )
     492                 :     {
     493               6 :         const PCIDatums   *paoDatum = aoDatums;
     494                 : 
     495                 :         // Search for matching datum
     496             159 :         while ( paoDatum->pszPCIDatum )
     497                 :         {
     498             150 :             if( EQUALN( szEarthModel, paoDatum->pszPCIDatum, 4 ) )
     499                 :             {
     500               3 :                 OGRSpatialReference oGCS;
     501               3 :                 oGCS.importFromEPSG( paoDatum->nEPSGCode );
     502               3 :                 CopyGeogCSFrom( &oGCS );
     503               3 :                 break;
     504                 :             }
     505             147 :             paoDatum++;
     506                 :         }
     507                 : 
     508                 : /* -------------------------------------------------------------------- */
     509                 : /*      If not, look in the ellipsoid list.                             */
     510                 : /* -------------------------------------------------------------------- */
     511               6 :         if ( !paoDatum->pszPCIDatum )  // No matching; search for ellipsoids
     512                 :         {
     513               3 :             paoDatum = aoEllips;
     514                 : 
     515                 : #ifdef DEBUG
     516                 :             CPLDebug( "OSR_PCI",
     517                 :                       "Cannot found matching datum definition, "
     518               3 :                       "search for ellipsoids." );
     519                 : #endif
     520                 : 
     521              21 :             while ( paoDatum->pszPCIDatum )
     522                 :             {
     523              18 :                 if( EQUALN( szEarthModel, paoDatum->pszPCIDatum, 4 ) 
     524                 :                     && paoDatum->nEPSGCode != 0 )
     525                 :                 {
     526               3 :                     char    *pszName = NULL;
     527                 :                     double  dfSemiMajor;
     528                 :                     double  dfInvFlattening;
     529                 :                     
     530               3 :                     if ( OSRGetEllipsoidInfo( paoDatum->nEPSGCode, &pszName,
     531                 :                             &dfSemiMajor, &dfInvFlattening ) == OGRERR_NONE )
     532                 :                     {
     533                 :                         SetGeogCS( CPLString().Printf(
     534                 :                                        "Unknown datum based upon the %s ellipsoid",
     535                 :                                        pszName ),
     536                 :                                    CPLString().Printf(
     537                 :                                        "Not specified (based on %s spheroid)",
     538                 :                                        pszName ),
     539                 :                                    pszName, dfSemiMajor, dfInvFlattening,
     540               3 :                                    NULL, 0.0, NULL, 0.0 );
     541               3 :                         SetAuthority( "SPHEROID", "EPSG", paoDatum->nEPSGCode );
     542                 : 
     543               3 :                         if ( pszName )
     544               3 :                             CPLFree( pszName );
     545                 :                     }
     546                 : 
     547               3 :                     break;
     548                 :                 }
     549              15 :                 else if( EQUALN( szEarthModel, paoDatum->pszPCIDatum, 4 ) )
     550                 :                 {
     551                 :                     double      dfInvFlattening;
     552                 : 
     553               0 :                     if ( CPLIsEqual(paoDatum->dfSemiMajor, paoDatum->dfSemiMinor) )
     554               0 :                         dfInvFlattening = 0.0;
     555                 :                     else
     556                 :                         dfInvFlattening = paoDatum->dfSemiMajor 
     557               0 :                             / (paoDatum->dfSemiMajor-paoDatum->dfSemiMinor);
     558                 : 
     559                 :                     SetGeogCS( "Unknown datum based upon the custom spheroid",
     560                 :                                "Not specified (based on custom spheroid)",
     561                 :                                CPLString().Printf( "PCI Ellipse %s", 
     562                 :                                                    szEarthModel),
     563                 :                                paoDatum->dfSemiMajor, dfInvFlattening,
     564               0 :                                NULL, 0, NULL, 0 );
     565               0 :                     break;
     566                 :                 }
     567              15 :                 paoDatum++;
     568                 :             }
     569                 :         }
     570                 : 
     571                 : /* -------------------------------------------------------------------- */
     572                 : /*      Custom spheroid.                                                */
     573                 : /* -------------------------------------------------------------------- */
     574               6 :         if ( !paoDatum->pszPCIDatum )      // Didn't found matches
     575                 :         {
     576                 : #ifdef DEBUG
     577                 :             CPLDebug( "OSR_PCI",
     578               0 :                       "Cannot found matching ellipsoid definition." );
     579                 : #endif
     580                 : 
     581               0 :             if( EQUALN( pszProj + 12, "E999", 4 ) 
     582                 :                 || padfPrjParams[0] != 0.0 )
     583                 :             {
     584                 :                 double      dfInvFlattening;
     585                 : 
     586               0 :                 if( ABS(padfPrjParams[0] - padfPrjParams[1]) < 0.01 )
     587                 :                 {
     588               0 :                     dfInvFlattening = 0.0;
     589                 :                 }
     590                 :                 else
     591                 :                 {
     592                 :                     dfInvFlattening =
     593               0 :                         padfPrjParams[0]/(padfPrjParams[0]-padfPrjParams[1]);
     594                 :                 }
     595                 : 
     596                 :                 SetGeogCS( "Unknown datum based upon the custom spheroid",
     597                 :                            "Not specified (based on custom spheroid)",
     598                 :                            "Custom spheroid",
     599                 :                            padfPrjParams[0], dfInvFlattening,
     600               0 :                            NULL, 0, NULL, 0 );
     601                 :             }
     602                 :             else
     603                 :             {
     604                 :                 // If we don't know, default to WGS84
     605                 :                 // so there is something there.
     606               0 :                 SetWellKnownGeogCS( "WGS84" );
     607                 : #ifdef DEBUG
     608               0 :                 CPLDebug( "OSR_PCI", "Setting WGS84 as a fallback." );
     609                 : #endif
     610                 : 
     611                 :             }
     612                 :         }
     613                 :     }
     614                 : 
     615                 : /* -------------------------------------------------------------------- */
     616                 : /*      Grid units translation                                          */
     617                 : /* -------------------------------------------------------------------- */
     618               6 :     if( (IsLocal() || IsProjected()) && pszUnits )
     619                 :     {
     620               4 :         if( EQUAL( pszUnits, "METRE" ) )
     621               4 :             SetLinearUnits( SRS_UL_METER, 1.0 );
     622               0 :         else if( EQUAL( pszUnits, "DEGREE" ) )
     623               0 :             SetAngularUnits( SRS_UA_DEGREE, atof(SRS_UA_DEGREE_CONV) );
     624                 :         else
     625               0 :             SetLinearUnits( SRS_UL_METER, 1.0 );
     626                 :     }
     627                 : 
     628               6 :     FixupOrdering();
     629                 : 
     630               6 :     if ( bProjAllocated && padfPrjParams )
     631               0 :         CPLFree( padfPrjParams );
     632                 : 
     633               6 :     return OGRERR_NONE;
     634                 : }
     635                 : 
     636                 : /************************************************************************/
     637                 : /*                          OSRExportToPCI()                            */
     638                 : /************************************************************************/
     639                 : /** 
     640                 :  * \brief Export coordinate system in PCI projection definition.
     641                 :  *
     642                 :  * This function is the same as OGRSpatialReference::exportToPCI().
     643                 :  */
     644                 : OGRErr OSRExportToPCI( OGRSpatialReferenceH hSRS,
     645                 :                        char **ppszProj, char **ppszUnits,
     646               1 :                        double **ppadfPrjParams )
     647                 : 
     648                 : {
     649               1 :     VALIDATE_POINTER1( hSRS, "OSRExportToPCI", CE_Failure );
     650                 : 
     651               1 :     *ppszProj = NULL;
     652               1 :     *ppszUnits = NULL;
     653               1 :     *ppadfPrjParams = NULL;
     654                 : 
     655                 :     return ((OGRSpatialReference *) hSRS)->exportToPCI( ppszProj, ppszUnits,
     656               1 :                                                         ppadfPrjParams );
     657                 : }
     658                 : 
     659                 : /************************************************************************/
     660                 : /*                           exportToPCI()                              */
     661                 : /************************************************************************/
     662                 : 
     663                 : /**
     664                 :  * \brief Export coordinate system in PCI projection definition.
     665                 :  *
     666                 :  * Converts the loaded coordinate reference system into PCI projection
     667                 :  * definition to the extent possible. The strings returned in ppszProj,
     668                 :  * ppszUnits and ppadfPrjParams array should be deallocated by the caller
     669                 :  * with CPLFree() when no longer needed.
     670                 :  *
     671                 :  * LOCAL_CS coordinate systems are not translatable.  An empty string
     672                 :  * will be returned along with OGRERR_NONE.  
     673                 :  *
     674                 :  * This method is the equivelent of the C function OSRExportToPCI().
     675                 :  *
     676                 :  * @param ppszProj pointer to which dynamically allocated PCI projection
     677                 :  * definition will be assigned.
     678                 :  * 
     679                 :  * @param ppszUnits pointer to which dynamically allocated units definition 
     680                 :  * will be assigned.
     681                 :  *
     682                 :  * @param ppadfPrjParams pointer to which dynamically allocated array of
     683                 :  * 17 projection parameters will be assigned. See importFromPCI() for the list
     684                 :  * of parameters.
     685                 :  * 
     686                 :  * @return OGRERR_NONE on success or an error code on failure. 
     687                 :  */
     688                 : 
     689                 : OGRErr OGRSpatialReference::exportToPCI( char **ppszProj, char **ppszUnits,
     690              43 :                                          double **ppadfPrjParams ) const
     691                 : 
     692                 : {
     693              43 :     const char  *pszProjection = GetAttrValue("PROJECTION");
     694                 : 
     695                 : /* -------------------------------------------------------------------- */
     696                 : /*      Fill all projection parameters with zero.                       */
     697                 : /* -------------------------------------------------------------------- */
     698                 :     int         i;
     699                 : 
     700              43 :     *ppadfPrjParams = (double *)CPLMalloc( 17 * sizeof(double) );
     701             774 :     for ( i = 0; i < 17; i++ )
     702             731 :         (*ppadfPrjParams)[i] = 0.0;
     703                 :    
     704                 : /* -------------------------------------------------------------------- */
     705                 : /*      Get the prime meridian info.                                    */
     706                 : /* -------------------------------------------------------------------- */
     707              43 :     const OGR_SRSNode *poPRIMEM = GetAttrNode( "PRIMEM" );
     708              43 :     double dfFromGreenwich = 0.0;
     709                 : 
     710              43 :     if( poPRIMEM != NULL && poPRIMEM->GetChildCount() >= 2 
     711                 :         && atof(poPRIMEM->GetChild(1)->GetValue()) != 0.0 )
     712                 :     {
     713               0 :         dfFromGreenwich = atof(poPRIMEM->GetChild(1)->GetValue());
     714                 :     }
     715                 : 
     716                 : /* ==================================================================== */
     717                 : /*      Handle the projection definition.                               */
     718                 : /* ==================================================================== */
     719                 :     char        szProj[17];
     720                 : 
     721              43 :     if( IsLocal() )
     722                 :     {
     723               0 :         if( GetLinearUnits() > 0.30479999 && GetLinearUnits() < 0.3048010 )
     724               0 :             CPLPrintStringFill( szProj, "FEET", 17 );
     725                 :         else
     726               0 :             CPLPrintStringFill( szProj, "METER", 17 );
     727                 :     }
     728                 : 
     729              43 :     else if( pszProjection == NULL )
     730                 :     {
     731                 : #ifdef DEBUG
     732                 :         CPLDebug( "OSR_PCI",
     733              41 :                   "Empty projection definition, considered as LONG/LAT" );
     734                 : #endif
     735              41 :         CPLPrintStringFill( szProj, "LONG/LAT", 17 );
     736                 :     }
     737                 : 
     738               2 :     else if( EQUAL(pszProjection, SRS_PT_ALBERS_CONIC_EQUAL_AREA) )
     739                 :     {
     740               0 :         CPLPrintStringFill( szProj, "ACEA", 16 );
     741               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     742                 :         (*ppadfPrjParams)[3] =
     743               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     744                 :         (*ppadfPrjParams)[4] =
     745               0 :             GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 );
     746                 :         (*ppadfPrjParams)[5] =
     747               0 :             GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 );
     748               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     749               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     750                 :     }
     751                 : 
     752               2 :     else if( EQUAL(pszProjection, SRS_PT_AZIMUTHAL_EQUIDISTANT) )
     753                 :     {
     754               0 :         CPLPrintStringFill( szProj, "AE", 16 );
     755               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     756                 :         (*ppadfPrjParams)[3] =
     757               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     758               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     759               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     760                 :     }
     761                 : 
     762               2 :     else if( EQUAL(pszProjection, SRS_PT_EQUIDISTANT_CONIC) )
     763                 :     {
     764               0 :         CPLPrintStringFill( szProj, "EC", 16 );
     765                 :         (*ppadfPrjParams)[2] =
     766               0 :             GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 );
     767                 :         (*ppadfPrjParams)[3] =
     768               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, 0.0 );
     769                 :         (*ppadfPrjParams)[4] =
     770               0 :             GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 );
     771                 :         (*ppadfPrjParams)[5] =
     772               0 :             GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 );
     773               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     774               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     775                 :     }
     776                 : 
     777               2 :     else if( EQUAL(pszProjection, SRS_PT_EQUIRECTANGULAR) )
     778                 :     {
     779               0 :         CPLPrintStringFill( szProj, "ER", 16 );
     780               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     781                 :         (*ppadfPrjParams)[3] =
     782               0 :             GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 );
     783               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     784               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     785                 :     }
     786                 : 
     787               2 :     else if( EQUAL(pszProjection, SRS_PT_GNOMONIC) )
     788                 :     {
     789               0 :         CPLPrintStringFill( szProj, "GNO", 16 );
     790               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     791                 :         (*ppadfPrjParams)[3] =
     792               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     793               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     794               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     795                 :     }
     796                 : 
     797               2 :     else if( EQUAL(pszProjection, SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA) )
     798                 :     {
     799               0 :         CPLPrintStringFill( szProj, "LAEA", 16 );
     800               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     801                 :         (*ppadfPrjParams)[3] =
     802               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     803               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     804               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     805                 :     }
     806                 : 
     807               2 :     else if( EQUAL(pszProjection, SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP) )
     808                 :     {
     809               1 :         CPLPrintStringFill( szProj, "LCC", 16 );
     810               1 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     811                 :         (*ppadfPrjParams)[3] =
     812               1 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     813                 :         (*ppadfPrjParams)[4] =
     814               1 :             GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 );
     815                 :         (*ppadfPrjParams)[5] =
     816               1 :             GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 );
     817               1 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     818               1 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     819                 :     }
     820                 : 
     821               1 :     else if( EQUAL(pszProjection, SRS_PT_MILLER_CYLINDRICAL) )
     822                 :     {
     823               0 :         CPLPrintStringFill( szProj, "MC", 16 );
     824               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     825                 :         (*ppadfPrjParams)[3] =
     826               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     827               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     828               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     829                 :     }
     830                 : 
     831               1 :     else if( EQUAL(pszProjection, SRS_PT_MERCATOR_1SP) )
     832                 :     {
     833               0 :         CPLPrintStringFill( szProj, "MER", 16 );
     834               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     835                 :         (*ppadfPrjParams)[3] =
     836               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     837               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     838               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     839               0 :         (*ppadfPrjParams)[8] = GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
     840                 :     }
     841                 : 
     842               1 :     else if( EQUAL(pszProjection, SRS_PT_ORTHOGRAPHIC) )
     843                 :     {
     844               0 :         CPLPrintStringFill( szProj, "OG", 16 );
     845               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     846                 :         (*ppadfPrjParams)[3] =
     847               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     848               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     849               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     850                 :     }
     851                 : 
     852               1 :     else if( EQUAL(pszProjection, SRS_PT_POLYCONIC) )
     853                 :     {
     854               0 :         CPLPrintStringFill( szProj, "PC", 16 );
     855               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     856                 :         (*ppadfPrjParams)[3] =
     857               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     858               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     859               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     860                 :     }
     861                 : 
     862               1 :     else if( EQUAL(pszProjection, SRS_PT_POLAR_STEREOGRAPHIC) )
     863                 :     {
     864               0 :         CPLPrintStringFill( szProj, "PS", 16 );
     865               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     866                 :         (*ppadfPrjParams)[3] =
     867               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     868               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     869               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     870               0 :         (*ppadfPrjParams)[8] = GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
     871                 :     }
     872                 : 
     873               1 :     else if( EQUAL(pszProjection, SRS_PT_ROBINSON) )
     874                 :     {
     875               0 :         CPLPrintStringFill( szProj, "ROB", 16 );
     876               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     877               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     878               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     879                 :     }
     880                 : 
     881               1 :     else if( EQUAL(pszProjection, SRS_PT_STEREOGRAPHIC) )
     882                 :     {
     883               0 :         CPLPrintStringFill( szProj, "SG", 16 );
     884               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     885                 :         (*ppadfPrjParams)[3] =
     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               0 :         (*ppadfPrjParams)[8] = GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
     890                 :     }
     891                 : 
     892               1 :     else if( EQUAL(pszProjection, SRS_PT_SINUSOIDAL) )
     893                 :     {
     894               0 :         CPLPrintStringFill( szProj, "SIN", 16 );
     895                 :         (*ppadfPrjParams)[2] =
     896               0 :             GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 );
     897               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     898               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     899                 :     }
     900                 : 
     901               1 :     else if( EQUAL(pszProjection, SRS_PT_TRANSVERSE_MERCATOR) )
     902                 :     {
     903                 :         int bNorth;
     904               1 :         int nZone = GetUTMZone( &bNorth );
     905                 : 
     906               1 :         if( nZone != 0 )
     907                 :         {
     908               1 :             CPLPrintStringFill( szProj, "UTM", 16 );
     909               1 :             if( bNorth )
     910               1 :                 CPLPrintInt32( szProj + 5, nZone, 4 );
     911                 :             else
     912               0 :                 CPLPrintInt32( szProj + 5, -nZone, 4 );
     913                 :         }            
     914                 :         else
     915                 :         {
     916               0 :             CPLPrintStringFill( szProj, "TM", 16 );
     917                 :             (*ppadfPrjParams)[2] =
     918               0 :                 GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     919                 :             (*ppadfPrjParams)[3] =
     920               0 :                 GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     921               0 :             (*ppadfPrjParams)[6] = GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0);
     922               0 :             (*ppadfPrjParams)[7] = GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0);
     923               0 :             (*ppadfPrjParams)[8] = GetNormProjParm(SRS_PP_SCALE_FACTOR, 1.0);
     924                 :         }
     925                 :     }
     926                 : 
     927               0 :     else if( EQUAL(pszProjection, SRS_PT_VANDERGRINTEN) )
     928                 :     {
     929               0 :         CPLPrintStringFill( szProj, "VDG", 16 );
     930               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     931               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     932               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     933                 :     }
     934                 : 
     935                 :     // Projection unsupported by PCI
     936                 :     else
     937                 :     {
     938                 :         CPLDebug( "OSR_PCI",
     939                 :                   "Projection \"%s\" unsupported by PCI. "
     940               0 :                   "PIXEL value will be used.", pszProjection );
     941               0 :         CPLPrintStringFill( szProj, "PIXEL", 16 );
     942                 :     }
     943                 :     
     944                 : /* -------------------------------------------------------------------- */
     945                 : /*      Translate the datum.                                            */
     946                 : /* -------------------------------------------------------------------- */
     947              43 :     const char  *pszDatum = GetAttrValue( "DATUM" );
     948                 : 
     949              43 :     if( pszDatum == NULL || strlen(pszDatum) == 0 )
     950                 :         /* do nothing */;
     951              43 :     else if( EQUAL( pszDatum, SRS_DN_NAD27 ) )
     952               1 :         CPLPrintStringFill( szProj + 12, "D-01", 4 );
     953                 : 
     954              42 :     else if( EQUAL( pszDatum, SRS_DN_NAD83 ) )
     955               0 :         CPLPrintStringFill( szProj + 12, "D-02", 4 );
     956                 : 
     957              42 :     else if( EQUAL( pszDatum, SRS_DN_WGS84 ) )
     958              41 :         CPLPrintStringFill( szProj + 12, "D000", 4 );
     959                 : 
     960                 :     // If not found well known datum, translate ellipsoid
     961                 :     else
     962                 :     {
     963               1 :         double      dfSemiMajor = GetSemiMajor();
     964               1 :         double      dfInvFlattening = GetInvFlattening();
     965                 : 
     966               1 :         const PCIDatums   *paoDatum = aoEllips;
     967                 : 
     968                 : #ifdef DEBUG
     969                 :         CPLDebug( "OSR_PCI",
     970                 :                   "Datum \"%s\" unsupported by PCI. "
     971               1 :                   "Try to translate ellipsoid definition.", pszDatum );
     972                 : #endif
     973                 :         
     974               2 :         while ( paoDatum->pszPCIDatum )
     975                 :         {
     976                 :             double  dfSM;
     977                 :             double  dfIF;
     978                 : 
     979               1 :             if ( OSRGetEllipsoidInfo( paoDatum->nEPSGCode, NULL,
     980                 :                                       &dfSM, &dfIF ) == OGRERR_NONE
     981                 :                  && CPLIsEqual( dfSemiMajor, dfSM )
     982                 :                  && CPLIsEqual( dfInvFlattening, dfIF ) )
     983                 :             {
     984               1 :                 CPLPrintStringFill( szProj + 12, paoDatum->pszPCIDatum, 4 );
     985               1 :                 break;
     986                 :             }
     987                 : 
     988               0 :             paoDatum++;
     989                 :         }
     990                 : 
     991               1 :         if ( !paoDatum->pszPCIDatum )       // Didn't found matches; set
     992                 :         {                                   // custom ellipsoid parameters
     993                 : #ifdef DEBUG
     994                 :             CPLDebug( "OSR_PCI",
     995                 :                       "Ellipsoid \"%s\" unsupported by PCI. "
     996               0 :                       "Custom PCI ellipsoid will be used.", pszDatum );
     997                 : #endif
     998               0 :             CPLPrintStringFill( szProj + 12, "E999", 4 );
     999               0 :             (*ppadfPrjParams)[0] = dfSemiMajor;
    1000               0 :             if ( ABS( dfInvFlattening ) < 0.000000000001 )
    1001                 :             {
    1002               0 :                 (*ppadfPrjParams)[1] = dfSemiMajor;
    1003                 :             }
    1004                 :             else
    1005                 :             {
    1006                 :                 (*ppadfPrjParams)[1] =
    1007               0 :                     dfSemiMajor * (1.0 - 1.0/dfInvFlattening);
    1008                 :             }
    1009                 :         }
    1010                 :     }
    1011                 : 
    1012                 : /* -------------------------------------------------------------------- */
    1013                 : /*      Translate the linear units.                                     */
    1014                 : /* -------------------------------------------------------------------- */
    1015                 :     const char  *pszUnits;
    1016                 :         
    1017              43 :     if( EQUALN( szProj, "LONG/LAT", 8 ) )
    1018              41 :         pszUnits = "DEGREE";
    1019                 :     else
    1020               2 :         pszUnits = "METRE";
    1021                 : 
    1022                 : /* -------------------------------------------------------------------- */
    1023                 : /*      Report results.                                                 */
    1024                 : /* -------------------------------------------------------------------- */
    1025              43 :     szProj[16] = '\0';
    1026              43 :     *ppszProj = CPLStrdup( szProj );
    1027                 : 
    1028              43 :     *ppszUnits = CPLStrdup( pszUnits );
    1029                 : 
    1030              43 :     return OGRERR_NONE;
    1031                 : }
    1032                 : 

Generated by: LTP GCOV extension version 1.5