LCOV - code coverage report
Current view: directory - ogr - ogr_srs_pci.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 342 155 45.3 %
Date: 2010-01-09 Functions: 4 4 100.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogr_srs_pci.cpp 18388 2009-12-26 21:41:14Z 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 18388 2009-12-26 21:41:14Z 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               1 : OGRErr OSRImportFromPCI( OGRSpatialReferenceH hSRS, const char *pszProj,
     143                 :                          const char *pszUnits, double *padfPrjParams )
     144                 : 
     145                 : {
     146               1 :     VALIDATE_POINTER1( hSRS, "OSRImportFromPCI", CE_Failure );
     147                 : 
     148                 :     return ((OGRSpatialReference *) hSRS)->importFromPCI( pszProj,
     149                 :                                                           pszUnits,
     150               1 :                                                           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               3 : OGRErr OGRSpatialReference::importFromPCI( const char *pszProj,
     201                 :                                            const char *pszUnits,
     202                 :                                            double *padfPrjParams )
     203                 : 
     204                 : {
     205               3 :     Clear();
     206                 : 
     207               3 :     if( pszProj == NULL || CPLStrnlen(pszProj, 16) < 16 )
     208               0 :         return OGRERR_CORRUPT_DATA;
     209                 : 
     210                 : #ifdef DEBUG
     211                 :     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               3 :     int     bProjAllocated = FALSE;
     218                 : 
     219               3 :     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               3 :     int bIsNAD27 = FALSE;
     238                 : 
     239               3 :     strcpy( szEarthModel, "" );
     240               3 :     pszEM = pszProj + strlen(pszProj) - 1;
     241              15 :     while( pszEM != pszProj )
     242                 :     {
     243              12 :         if( *pszEM == 'e' || *pszEM == 'E' || *pszEM == 'd' || *pszEM == 'D' )
     244                 :         {
     245               3 :             int nCode = atoi(pszEM+1);
     246                 : 
     247               3 :             if( nCode >= -99 && nCode <= 999 )
     248               3 :                 sprintf( szEarthModel, "%c%03d", toupper(*pszEM), nCode );
     249                 : 
     250               3 :             break;
     251                 :         }
     252                 : 
     253               9 :         pszEM--;
     254                 :     }
     255                 : 
     256               3 :     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               3 :     if( EQUALN( pszProj, "LONG/LAT", 8 ) )
     270                 :     {
     271                 :     }
     272                 :     
     273               3 :     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               3 :     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               3 :     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               3 :     else if( EQUALN( pszProj, "AE", 2 ) )
     295                 :     {
     296                 :         SetAE( padfPrjParams[3], padfPrjParams[2],
     297               0 :                padfPrjParams[6], padfPrjParams[7] );
     298                 :     }
     299                 : 
     300               3 :     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               2 :     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               2 :     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               2 :     else if( EQUALN( pszProj, "LAEA", 4 ) )
     324                 :     {
     325                 :         SetLAEA( padfPrjParams[3], padfPrjParams[2],
     326               0 :                  padfPrjParams[6], padfPrjParams[7] );
     327                 :     }
     328                 : 
     329               2 :     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               2 :     else if( EQUALN( pszProj, "MC", 2 ) )
     337                 :     {
     338                 :         SetMC( padfPrjParams[3], padfPrjParams[2],
     339               0 :                padfPrjParams[6], padfPrjParams[7] );
     340                 :     }
     341                 : 
     342               2 :     else if( EQUALN( pszProj, "MER", 3 ) )
     343                 :     {
     344                 :         SetMercator( padfPrjParams[3], padfPrjParams[2],
     345               0 :                      (padfPrjParams[8] != 0.0) ? padfPrjParams[9] : 1.0,
     346               0 :                      padfPrjParams[6], padfPrjParams[7] );
     347                 :     }
     348                 : 
     349               2 :     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               2 :     else if( EQUALN( pszProj, "PC", 2 ) )
     358                 :     {
     359                 :         SetPolyconic( padfPrjParams[3], padfPrjParams[2],
     360               0 :                       padfPrjParams[6], padfPrjParams[7] );
     361                 :     }
     362                 : 
     363               2 :     else if( EQUALN( pszProj, "PS", 2 ) )
     364                 :     {
     365                 :         SetPS( padfPrjParams[3], padfPrjParams[2],
     366               0 :                (padfPrjParams[8] != 0.0) ? padfPrjParams[9] : 1.0,
     367               0 :                padfPrjParams[6], padfPrjParams[7] );
     368                 :     }
     369                 : 
     370               2 :     else if( EQUALN( pszProj, "ROB", 3 ) )
     371                 :     {
     372                 :         SetRobinson( padfPrjParams[2],
     373               0 :                      padfPrjParams[6], padfPrjParams[7] );
     374                 :     }
     375                 : 
     376               2 :     else if( EQUALN( pszProj, "SG", 2 ) )
     377                 :     {
     378                 :         SetStereographic( padfPrjParams[3], padfPrjParams[2],
     379               0 :                           (padfPrjParams[8] != 0.0) ? padfPrjParams[9] : 1.0,
     380               0 :                           padfPrjParams[6], padfPrjParams[7] );
     381                 :     }
     382                 : 
     383               2 :     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               2 :     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               2 :     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               2 :     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               2 :     else if( EQUALN( pszProj, "TM", 2 ) )
     423                 :     {
     424                 :         SetTM( padfPrjParams[3], padfPrjParams[2],
     425               0 :                (padfPrjParams[8] != 0.0) ? padfPrjParams[9] : 1.0,
     426               0 :                padfPrjParams[6], padfPrjParams[7] );
     427                 :     }
     428                 : 
     429               2 :     else if( EQUALN( pszProj, "UTM", 3 ) )
     430                 :     {
     431               2 :         int     iZone, bNorth = TRUE;
     432                 : 
     433               2 :         iZone = CPLScanLong( (char *)pszProj + 4, 5 );;
     434               2 :         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               2 :         char byZoneID = 0;
     443               2 :         int nZoneOffset = 0;
     444                 : 
     445                 :         // Iterate through the remaining characters in the projection
     446                 :         // string. We should see something like "UTM    55 G D000"
     447               6 :         for (int i = 9; i < 16; i++)
     448                 :         {
     449               8 :             if (pszProj[i] == ' ' && nZoneOffset == 0)
     450                 :             {
     451               2 :                 nZoneOffset = i + 1;
     452                 :             }
     453               4 :             else if (pszProj[i] == ' ' && i - nZoneOffset == 1)
     454                 :             {
     455               2 :                 byZoneID = pszProj[nZoneOffset];
     456               2 :                 break;
     457                 :             }
     458               2 :             else if (i - nZoneOffset > 1)
     459                 :             {
     460               0 :                 break;
     461                 :             }
     462                 :         }
     463                 : 
     464                 :         // Determine if the MGRS zone falls above or below the equator
     465               2 :         if (byZoneID != 0)
     466                 :         {
     467                 : #ifdef DEBUG
     468                 :             CPLDebug("OSR_PCI", "Found MGRS zone in UTM projection string: %c",
     469                 :                 byZoneID);
     470                 : #endif
     471               2 :             if (byZoneID >= 'N' && byZoneID <= 'X')
     472                 :             {
     473               0 :                 bNorth = TRUE;
     474                 :             }
     475                 :             else
     476                 :             {
     477               2 :                 bNorth = FALSE;
     478                 :             }
     479                 :         }
     480                 :         
     481               2 :         SetUTM( iZone, bNorth );
     482                 :     }
     483                 : 
     484               0 :     else if( EQUALN( pszProj, "VDG", 3 ) )
     485                 :     {
     486                 :         SetVDG( padfPrjParams[2],
     487               0 :                 padfPrjParams[6], padfPrjParams[7] );
     488                 :     }
     489                 : 
     490                 :     else
     491                 :     {
     492               0 :         CPLDebug( "OSR_PCI", "Unsupported projection: %s", pszProj );
     493               0 :         SetLocalCS( pszProj );
     494                 :     }
     495                 : 
     496                 : /* ==================================================================== */
     497                 : /*      Translate the datum/spheroid.                                   */
     498                 : /* ==================================================================== */
     499                 : 
     500                 : /* -------------------------------------------------------------------- */
     501                 : /*      We have an earthmodel string, look it up in the datum list.     */
     502                 : /* -------------------------------------------------------------------- */
     503               3 :     if( strlen(szEarthModel) > 0 
     504                 :         && (poRoot == NULL || IsProjected() || IsGeographic()) )
     505                 :     {
     506               3 :         const PCIDatums   *paoDatum = aoDatums;
     507                 : 
     508                 :         // Search for matching datum
     509             141 :         while ( paoDatum->pszPCIDatum )
     510                 :         {
     511             135 :             if( EQUALN( szEarthModel, paoDatum->pszPCIDatum, 4 ) )
     512                 :             {
     513               0 :                 OGRSpatialReference oGCS;
     514               0 :                 oGCS.importFromEPSG( paoDatum->nEPSGCode );
     515               0 :                 CopyGeogCSFrom( &oGCS );
     516               0 :                 break;
     517                 :             }
     518             135 :             paoDatum++;
     519                 :         }
     520                 : 
     521                 : /* -------------------------------------------------------------------- */
     522                 : /*      If not, look in the ellipsoid list.                             */
     523                 : /* -------------------------------------------------------------------- */
     524               3 :         if ( !paoDatum->pszPCIDatum )  // No matching; search for ellipsoids
     525                 :         {
     526               3 :             paoDatum = aoEllips;
     527                 : 
     528                 : #ifdef DEBUG
     529                 :             CPLDebug( "OSR_PCI",
     530                 :                       "Cannot found matching datum definition, "
     531                 :                       "search for ellipsoids." );
     532                 : #endif
     533                 : 
     534              21 :             while ( paoDatum->pszPCIDatum )
     535                 :             {
     536              18 :                 if( EQUALN( szEarthModel, paoDatum->pszPCIDatum, 4 ) 
     537                 :                     && paoDatum->nEPSGCode != 0 )
     538                 :                 {
     539               3 :                     char    *pszName = NULL;
     540                 :                     double  dfSemiMajor;
     541                 :                     double  dfInvFlattening;
     542                 :                     
     543               3 :                     if ( OSRGetEllipsoidInfo( paoDatum->nEPSGCode, &pszName,
     544                 :                             &dfSemiMajor, &dfInvFlattening ) == OGRERR_NONE )
     545                 :                     {
     546                 :                         SetGeogCS( CPLString().Printf(
     547                 :                                        "Unknown datum based upon the %s ellipsoid",
     548                 :                                        pszName ),
     549                 :                                    CPLString().Printf(
     550                 :                                        "Not specified (based on %s spheroid)",
     551                 :                                        pszName ),
     552                 :                                    pszName, dfSemiMajor, dfInvFlattening,
     553               3 :                                    NULL, 0.0, NULL, 0.0 );
     554               3 :                         SetAuthority( "SPHEROID", "EPSG", paoDatum->nEPSGCode );
     555                 : 
     556               3 :                         if ( pszName )
     557               3 :                             CPLFree( pszName );
     558                 :                     }
     559                 : 
     560               3 :                     break;
     561                 :                 }
     562              15 :                 else if( EQUALN( szEarthModel, paoDatum->pszPCIDatum, 4 ) )
     563                 :                 {
     564                 :                     double      dfInvFlattening;
     565                 : 
     566               0 :                     if ( CPLIsEqual(paoDatum->dfSemiMajor, paoDatum->dfSemiMinor) )
     567               0 :                         dfInvFlattening = 0.0;
     568                 :                     else
     569                 :                         dfInvFlattening = paoDatum->dfSemiMajor 
     570               0 :                             / (paoDatum->dfSemiMajor-paoDatum->dfSemiMinor);
     571                 : 
     572                 :                     SetGeogCS( "Unknown datum based upon the custom spheroid",
     573                 :                                "Not specified (based on custom spheroid)",
     574                 :                                CPLString().Printf( "PCI Ellipse %s", 
     575                 :                                                    szEarthModel),
     576                 :                                paoDatum->dfSemiMajor, dfInvFlattening,
     577               0 :                                NULL, 0, NULL, 0 );
     578               0 :                     break;
     579                 :                 }
     580              15 :                 paoDatum++;
     581                 :             }
     582                 :         }
     583                 : 
     584                 : /* -------------------------------------------------------------------- */
     585                 : /*      Custom spheroid.                                                */
     586                 : /* -------------------------------------------------------------------- */
     587               3 :         if ( !paoDatum->pszPCIDatum )      // Didn't found matches
     588                 :         {
     589                 : #ifdef DEBUG
     590                 :             CPLDebug( "OSR_PCI",
     591                 :                       "Cannot found matching ellipsoid definition." );
     592                 : #endif
     593                 : 
     594               0 :             if( EQUALN( pszProj + 12, "E999", 4 ) 
     595               0 :                 || padfPrjParams[0] != 0.0 )
     596                 :             {
     597                 :                 double      dfInvFlattening;
     598                 : 
     599               0 :                 if( ABS(padfPrjParams[0] - padfPrjParams[1]) < 0.01 )
     600                 :                 {
     601               0 :                     dfInvFlattening = 0.0;
     602                 :                 }
     603                 :                 else
     604                 :                 {
     605                 :                     dfInvFlattening =
     606               0 :                         padfPrjParams[0]/(padfPrjParams[0]-padfPrjParams[1]);
     607                 :                 }
     608                 : 
     609                 :                 SetGeogCS( "Unknown datum based upon the custom spheroid",
     610                 :                            "Not specified (based on custom spheroid)",
     611                 :                            "Custom spheroid",
     612                 :                            padfPrjParams[0], dfInvFlattening,
     613               0 :                            NULL, 0, NULL, 0 );
     614                 :             }
     615                 :             else
     616                 :             {
     617                 :                 // If we don't know, default to WGS84
     618                 :                 // so there is something there.
     619               0 :                 SetWellKnownGeogCS( "WGS84" );
     620                 : #ifdef DEBUG
     621                 :                 CPLDebug( "OSR_PCI", "Setting WGS84 as a fallback." );
     622                 : #endif
     623                 : 
     624                 :             }
     625                 :         }
     626                 :     }
     627                 : 
     628                 : /* -------------------------------------------------------------------- */
     629                 : /*      Grid units translation                                          */
     630                 : /* -------------------------------------------------------------------- */
     631               3 :     if( (IsLocal() || IsProjected()) && pszUnits )
     632                 :     {
     633               1 :         if( EQUAL( pszUnits, "METRE" ) )
     634               1 :             SetLinearUnits( SRS_UL_METER, 1.0 );
     635               0 :         else if( EQUAL( pszUnits, "DEGREE" ) )
     636               0 :             SetAngularUnits( SRS_UA_DEGREE, atof(SRS_UA_DEGREE_CONV) );
     637                 :         else
     638               0 :             SetLinearUnits( SRS_UL_METER, 1.0 );
     639                 :     }
     640                 : 
     641               3 :     FixupOrdering();
     642                 : 
     643               3 :     if ( bProjAllocated && padfPrjParams )
     644               0 :         CPLFree( padfPrjParams );
     645                 : 
     646               3 :     return OGRERR_NONE;
     647                 : }
     648                 : 
     649                 : /************************************************************************/
     650                 : /*                          OSRExportToPCI()                            */
     651                 : /************************************************************************/
     652                 : /** 
     653                 :  * \brief Export coordinate system in PCI projection definition.
     654                 :  *
     655                 :  * This function is the same as OGRSpatialReference::exportToPCI().
     656                 :  */
     657               1 : OGRErr OSRExportToPCI( OGRSpatialReferenceH hSRS,
     658                 :                        char **ppszProj, char **ppszUnits,
     659                 :                        double **ppadfPrjParams )
     660                 : 
     661                 : {
     662               1 :     VALIDATE_POINTER1( hSRS, "OSRExportToPCI", CE_Failure );
     663                 : 
     664               1 :     *ppszProj = NULL;
     665               1 :     *ppszUnits = NULL;
     666               1 :     *ppadfPrjParams = NULL;
     667                 : 
     668                 :     return ((OGRSpatialReference *) hSRS)->exportToPCI( ppszProj, ppszUnits,
     669               1 :                                                         ppadfPrjParams );
     670                 : }
     671                 : 
     672                 : /************************************************************************/
     673                 : /*                           exportToPCI()                              */
     674                 : /************************************************************************/
     675                 : 
     676                 : /**
     677                 :  * \brief Export coordinate system in PCI projection definition.
     678                 :  *
     679                 :  * Converts the loaded coordinate reference system into PCI projection
     680                 :  * definition to the extent possible. The strings returned in ppszProj,
     681                 :  * ppszUnits and ppadfPrjParams array should be deallocated by the caller
     682                 :  * with CPLFree() when no longer needed.
     683                 :  *
     684                 :  * LOCAL_CS coordinate systems are not translatable.  An empty string
     685                 :  * will be returned along with OGRERR_NONE.  
     686                 :  *
     687                 :  * This method is the equivelent of the C function OSRExportToPCI().
     688                 :  *
     689                 :  * @param ppszProj pointer to which dynamically allocated PCI projection
     690                 :  * definition will be assigned.
     691                 :  * 
     692                 :  * @param ppszUnits pointer to which dynamically allocated units definition 
     693                 :  * will be assigned.
     694                 :  *
     695                 :  * @param ppadfPrjParams pointer to which dynamically allocated array of
     696                 :  * 17 projection parameters will be assigned. See importFromPCI() for the list
     697                 :  * of parameters.
     698                 :  * 
     699                 :  * @return OGRERR_NONE on success or an error code on failure. 
     700                 :  */
     701                 : 
     702              17 : OGRErr OGRSpatialReference::exportToPCI( char **ppszProj, char **ppszUnits,
     703                 :                                          double **ppadfPrjParams ) const
     704                 : 
     705                 : {
     706              17 :     const char  *pszProjection = GetAttrValue("PROJECTION");
     707                 : 
     708                 : /* -------------------------------------------------------------------- */
     709                 : /*      Fill all projection parameters with zero.                       */
     710                 : /* -------------------------------------------------------------------- */
     711                 :     int         i;
     712                 : 
     713              17 :     *ppadfPrjParams = (double *)CPLMalloc( 17 * sizeof(double) );
     714             306 :     for ( i = 0; i < 17; i++ )
     715             289 :         (*ppadfPrjParams)[i] = 0.0;
     716                 :    
     717                 : /* -------------------------------------------------------------------- */
     718                 : /*      Get the prime meridian info.                                    */
     719                 : /* -------------------------------------------------------------------- */
     720              17 :     const OGR_SRSNode *poPRIMEM = GetAttrNode( "PRIMEM" );
     721              17 :     double dfFromGreenwich = 0.0;
     722                 : 
     723              17 :     if( poPRIMEM != NULL && poPRIMEM->GetChildCount() >= 2 
     724                 :         && atof(poPRIMEM->GetChild(1)->GetValue()) != 0.0 )
     725                 :     {
     726               0 :         dfFromGreenwich = atof(poPRIMEM->GetChild(1)->GetValue());
     727                 :     }
     728                 : 
     729                 : /* ==================================================================== */
     730                 : /*      Handle the projection definition.                               */
     731                 : /* ==================================================================== */
     732                 :     char        szProj[17];
     733                 : 
     734              17 :     if( IsLocal() )
     735                 :     {
     736               0 :         if( GetLinearUnits() > 0.30479999 && GetLinearUnits() < 0.3048010 )
     737               0 :             CPLPrintStringFill( szProj, "FEET", 17 );
     738                 :         else
     739               0 :             CPLPrintStringFill( szProj, "METER", 17 );
     740                 :     }
     741                 : 
     742              17 :     else if( pszProjection == NULL )
     743                 :     {
     744                 : #ifdef DEBUG
     745                 :         CPLDebug( "OSR_PCI",
     746                 :                   "Empty projection definition, considered as LONG/LAT" );
     747                 : #endif
     748              15 :         CPLPrintStringFill( szProj, "LONG/LAT", 17 );
     749                 :     }
     750                 : 
     751               2 :     else if( EQUAL(pszProjection, SRS_PT_ALBERS_CONIC_EQUAL_AREA) )
     752                 :     {
     753               0 :         CPLPrintStringFill( szProj, "ACEA", 16 );
     754               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     755               0 :         (*ppadfPrjParams)[3] =
     756               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     757               0 :         (*ppadfPrjParams)[4] =
     758               0 :             GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 );
     759               0 :         (*ppadfPrjParams)[5] =
     760               0 :             GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 );
     761               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     762               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     763                 :     }
     764                 : 
     765               2 :     else if( EQUAL(pszProjection, SRS_PT_AZIMUTHAL_EQUIDISTANT) )
     766                 :     {
     767               0 :         CPLPrintStringFill( szProj, "AE", 16 );
     768               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     769               0 :         (*ppadfPrjParams)[3] =
     770               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     771               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     772               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     773                 :     }
     774                 : 
     775               2 :     else if( EQUAL(pszProjection, SRS_PT_EQUIDISTANT_CONIC) )
     776                 :     {
     777               0 :         CPLPrintStringFill( szProj, "EC", 16 );
     778               0 :         (*ppadfPrjParams)[2] =
     779               0 :             GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 );
     780               0 :         (*ppadfPrjParams)[3] =
     781               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, 0.0 );
     782               0 :         (*ppadfPrjParams)[4] =
     783               0 :             GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 );
     784               0 :         (*ppadfPrjParams)[5] =
     785               0 :             GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 );
     786               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     787               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     788                 :     }
     789                 : 
     790               2 :     else if( EQUAL(pszProjection, SRS_PT_EQUIRECTANGULAR) )
     791                 :     {
     792               0 :         CPLPrintStringFill( szProj, "ER", 16 );
     793               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     794               0 :         (*ppadfPrjParams)[3] =
     795               0 :             GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 );
     796               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     797               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     798                 :     }
     799                 : 
     800               2 :     else if( EQUAL(pszProjection, SRS_PT_GNOMONIC) )
     801                 :     {
     802               0 :         CPLPrintStringFill( szProj, "GNO", 16 );
     803               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     804               0 :         (*ppadfPrjParams)[3] =
     805               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     806               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     807               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     808                 :     }
     809                 : 
     810               2 :     else if( EQUAL(pszProjection, SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA) )
     811                 :     {
     812               0 :         CPLPrintStringFill( szProj, "LAEA", 16 );
     813               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     814               0 :         (*ppadfPrjParams)[3] =
     815               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     816               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     817               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     818                 :     }
     819                 : 
     820               2 :     else if( EQUAL(pszProjection, SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP) )
     821                 :     {
     822               1 :         CPLPrintStringFill( szProj, "LCC", 16 );
     823               1 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     824               1 :         (*ppadfPrjParams)[3] =
     825               1 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     826               1 :         (*ppadfPrjParams)[4] =
     827               1 :             GetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, 0.0 );
     828               1 :         (*ppadfPrjParams)[5] =
     829               1 :             GetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, 0.0 );
     830               1 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     831               1 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     832                 :     }
     833                 : 
     834               1 :     else if( EQUAL(pszProjection, SRS_PT_MILLER_CYLINDRICAL) )
     835                 :     {
     836               0 :         CPLPrintStringFill( szProj, "MC", 16 );
     837               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     838               0 :         (*ppadfPrjParams)[3] =
     839               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     840               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     841               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     842                 :     }
     843                 : 
     844               1 :     else if( EQUAL(pszProjection, SRS_PT_MERCATOR_1SP) )
     845                 :     {
     846               0 :         CPLPrintStringFill( szProj, "MER", 16 );
     847               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     848               0 :         (*ppadfPrjParams)[3] =
     849               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     850               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     851               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     852               0 :         (*ppadfPrjParams)[8] = GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
     853                 :     }
     854                 : 
     855               1 :     else if( EQUAL(pszProjection, SRS_PT_ORTHOGRAPHIC) )
     856                 :     {
     857               0 :         CPLPrintStringFill( szProj, "OG", 16 );
     858               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     859               0 :         (*ppadfPrjParams)[3] =
     860               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     861               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     862               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     863                 :     }
     864                 : 
     865               1 :     else if( EQUAL(pszProjection, SRS_PT_POLYCONIC) )
     866                 :     {
     867               0 :         CPLPrintStringFill( szProj, "PC", 16 );
     868               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     869               0 :         (*ppadfPrjParams)[3] =
     870               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     871               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     872               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     873                 :     }
     874                 : 
     875               1 :     else if( EQUAL(pszProjection, SRS_PT_POLAR_STEREOGRAPHIC) )
     876                 :     {
     877               0 :         CPLPrintStringFill( szProj, "PS", 16 );
     878               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     879               0 :         (*ppadfPrjParams)[3] =
     880               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     881               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     882               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     883               0 :         (*ppadfPrjParams)[8] = GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
     884                 :     }
     885                 : 
     886               1 :     else if( EQUAL(pszProjection, SRS_PT_ROBINSON) )
     887                 :     {
     888               0 :         CPLPrintStringFill( szProj, "ROB", 16 );
     889               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     890               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     891               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     892                 :     }
     893                 : 
     894               1 :     else if( EQUAL(pszProjection, SRS_PT_STEREOGRAPHIC) )
     895                 :     {
     896               0 :         CPLPrintStringFill( szProj, "SG", 16 );
     897               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     898               0 :         (*ppadfPrjParams)[3] =
     899               0 :             GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     900               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     901               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     902               0 :         (*ppadfPrjParams)[8] = GetNormProjParm( SRS_PP_SCALE_FACTOR, 1.0 );
     903                 :     }
     904                 : 
     905               1 :     else if( EQUAL(pszProjection, SRS_PT_SINUSOIDAL) )
     906                 :     {
     907               0 :         CPLPrintStringFill( szProj, "SIN", 16 );
     908               0 :         (*ppadfPrjParams)[2] =
     909               0 :             GetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, 0.0 );
     910               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     911               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     912                 :     }
     913                 : 
     914               1 :     else if( EQUAL(pszProjection, SRS_PT_TRANSVERSE_MERCATOR) )
     915                 :     {
     916                 :         int bNorth;
     917               1 :         int nZone = GetUTMZone( &bNorth );
     918                 : 
     919               1 :         if( nZone != 0 )
     920                 :         {
     921               1 :             CPLPrintStringFill( szProj, "UTM", 16 );
     922               1 :             if( bNorth )
     923               0 :                 CPLPrintInt32( szProj + 5, nZone, 4 );
     924                 :             else
     925               1 :                 CPLPrintInt32( szProj + 5, -nZone, 4 );
     926                 :         }            
     927                 :         else
     928                 :         {
     929               0 :             CPLPrintStringFill( szProj, "TM", 16 );
     930               0 :             (*ppadfPrjParams)[2] =
     931               0 :                 GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     932               0 :             (*ppadfPrjParams)[3] =
     933               0 :                 GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 );
     934               0 :             (*ppadfPrjParams)[6] = GetNormProjParm(SRS_PP_FALSE_EASTING, 0.0);
     935               0 :             (*ppadfPrjParams)[7] = GetNormProjParm(SRS_PP_FALSE_NORTHING, 0.0);
     936               0 :             (*ppadfPrjParams)[8] = GetNormProjParm(SRS_PP_SCALE_FACTOR, 1.0);
     937                 :         }
     938                 :     }
     939                 : 
     940               0 :     else if( EQUAL(pszProjection, SRS_PT_VANDERGRINTEN) )
     941                 :     {
     942               0 :         CPLPrintStringFill( szProj, "VDG", 16 );
     943               0 :         (*ppadfPrjParams)[2] = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 0.0 );
     944               0 :         (*ppadfPrjParams)[6] = GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 );
     945               0 :         (*ppadfPrjParams)[7] = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0 );
     946                 :     }
     947                 : 
     948                 :     // Projection unsupported by PCI
     949                 :     else
     950                 :     {
     951                 :         CPLDebug( "OSR_PCI",
     952                 :                   "Projection \"%s\" unsupported by PCI. "
     953               0 :                   "PIXEL value will be used.", pszProjection );
     954               0 :         CPLPrintStringFill( szProj, "PIXEL", 16 );
     955                 :     }
     956                 :     
     957                 : /* -------------------------------------------------------------------- */
     958                 : /*      Translate the datum.                                            */
     959                 : /* -------------------------------------------------------------------- */
     960              17 :     const char  *pszDatum = GetAttrValue( "DATUM" );
     961                 : 
     962              17 :     if( pszDatum == NULL || strlen(pszDatum) == 0 )
     963                 :         /* do nothing */;
     964              17 :     else if( EQUAL( pszDatum, SRS_DN_NAD27 ) )
     965               1 :         CPLPrintStringFill( szProj + 12, "D-01", 4 );
     966                 : 
     967              16 :     else if( EQUAL( pszDatum, SRS_DN_NAD83 ) )
     968               0 :         CPLPrintStringFill( szProj + 12, "D-02", 4 );
     969                 : 
     970              16 :     else if( EQUAL( pszDatum, SRS_DN_WGS84 ) )
     971              15 :         CPLPrintStringFill( szProj + 12, "D000", 4 );
     972                 : 
     973                 :     // If not found well known datum, translate ellipsoid
     974                 :     else
     975                 :     {
     976               1 :         double      dfSemiMajor = GetSemiMajor();
     977               1 :         double      dfInvFlattening = GetInvFlattening();
     978                 : 
     979               1 :         const PCIDatums   *paoDatum = aoEllips;
     980                 : 
     981                 : #ifdef DEBUG
     982                 :         CPLDebug( "OSR_PCI",
     983                 :                   "Datum \"%s\" unsupported by PCI. "
     984                 :                   "Try to translate ellipsoid definition.", pszDatum );
     985                 : #endif
     986                 :         
     987               2 :         while ( paoDatum->pszPCIDatum )
     988                 :         {
     989                 :             double  dfSM;
     990                 :             double  dfIF;
     991                 : 
     992               1 :             if ( OSRGetEllipsoidInfo( paoDatum->nEPSGCode, NULL,
     993                 :                                       &dfSM, &dfIF ) == OGRERR_NONE
     994                 :                  && CPLIsEqual( dfSemiMajor, dfSM )
     995                 :                  && CPLIsEqual( dfInvFlattening, dfIF ) )
     996                 :             {
     997               1 :                 CPLPrintStringFill( szProj + 12, paoDatum->pszPCIDatum, 4 );
     998               1 :                 break;
     999                 :             }
    1000                 : 
    1001               0 :             paoDatum++;
    1002                 :         }
    1003                 : 
    1004               1 :         if ( !paoDatum->pszPCIDatum )       // Didn't found matches; set
    1005                 :         {                                   // custom ellipsoid parameters
    1006                 : #ifdef DEBUG
    1007                 :             CPLDebug( "OSR_PCI",
    1008                 :                       "Ellipsoid \"%s\" unsupported by PCI. "
    1009                 :                       "Custom PCI ellipsoid will be used.", pszDatum );
    1010                 : #endif
    1011               0 :             CPLPrintStringFill( szProj + 12, "E999", 4 );
    1012               0 :             (*ppadfPrjParams)[0] = dfSemiMajor;
    1013               0 :             if ( ABS( dfInvFlattening ) < 0.000000000001 )
    1014                 :             {
    1015               0 :                 (*ppadfPrjParams)[1] = dfSemiMajor;
    1016                 :             }
    1017                 :             else
    1018                 :             {
    1019               0 :                 (*ppadfPrjParams)[1] =
    1020               0 :                     dfSemiMajor * (1.0 - 1.0/dfInvFlattening);
    1021                 :             }
    1022                 :         }
    1023                 :     }
    1024                 : 
    1025                 : /* -------------------------------------------------------------------- */
    1026                 : /*      Translate the linear units.                                     */
    1027                 : /* -------------------------------------------------------------------- */
    1028                 :     const char  *pszUnits;
    1029                 :         
    1030              17 :     if( EQUALN( szProj, "LONG/LAT", 8 ) )
    1031              15 :         pszUnits = "DEGREE";
    1032                 :     else
    1033               2 :         pszUnits = "METRE";
    1034                 : 
    1035                 : /* -------------------------------------------------------------------- */
    1036                 : /*      Report results.                                                 */
    1037                 : /* -------------------------------------------------------------------- */
    1038              17 :     szProj[16] = '\0';
    1039              17 :     *ppszProj = CPLStrdup( szProj );
    1040                 : 
    1041              17 :     *ppszUnits = CPLStrdup( pszUnits );
    1042                 : 
    1043              17 :     return OGRERR_NONE;
    1044                 : }
    1045                 : 

Generated by: LCOV version 1.7