LTP GCOV extension - code coverage report
Current view: directory - ogr/ogrsf_frmts/mitab - mitab_coordsys.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 559
Code covered: 28.6 % Executed lines: 160

       1                 : /**********************************************************************
       2                 :  * $Id: mitab_coordsys.cpp,v 1.36 2007/11/21 21:15:45 dmorissette Exp $
       3                 :  *
       4                 :  * Name:     mitab_coordsys.cpp
       5                 :  * Project:  MapInfo TAB Read/Write library
       6                 :  * Language: C++
       7                 :  * Purpose:  Implementation translation between MIF CoordSys format, and
       8                 :  *           and OGRSpatialRef format.
       9                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
      10                 :  *
      11                 :  **********************************************************************
      12                 :  * Copyright (c) 1999-2001, Frank Warmerdam
      13                 :  *
      14                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      15                 :  * copy of this software and associated documentation files (the "Software"),
      16                 :  * to deal in the Software without restriction, including without limitation
      17                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      18                 :  * and/or sell copies of the Software, and to permit persons to whom the
      19                 :  * Software is furnished to do so, subject to the following conditions:
      20                 :  * 
      21                 :  * The above copyright notice and this permission notice shall be included
      22                 :  * in all copies or substantial portions of the Software.
      23                 :  * 
      24                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      25                 :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      26                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      27                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      28                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      29                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
      30                 :  * DEALINGS IN THE SOFTWARE.
      31                 :  **********************************************************************
      32                 :  *
      33                 :  * $Log: mitab_coordsys.cpp,v $
      34                 :  * Revision 1.36  2007/11/21 21:15:45  dmorissette
      35                 :  * Fix asDatumInfoList[] and asSpheroidInfoList[] defns/refs (bug 1826)
      36                 :  *
      37                 :  * Revision 1.35  2007/06/21 13:23:43  fwarmerdam
      38                 :  * Fixed support for predefined datums with non-greenwich prime meridians
      39                 :  *
      40                 :  * Revision 1.34  2006/03/10 19:50:45  fwarmerdam
      41                 :  * Coordsys false easting and northing are in the units of the coordsys, not
      42                 :  * necessarily meters.  Adjusted mitab_coordsys.cpp to reflect this.
      43                 :  * http://bugzilla.remotesensing.org/show_bug.cgi?id=1113
      44                 :  *
      45                 :  * Revision 1.33  2005/09/29 20:13:57  dmorissette
      46                 :  * MITABCoordSys2SpatialRef() patches from Anthony D (bug 1155):
      47                 :  * Improved support for modified TM projections 21-24.
      48                 :  * Added support for affine parameters (inside #ifdef MITAB_AFFINE_PARAMS since
      49                 :  * affine params cannot be stored directly in OGRSpatialReference)
      50                 :  *
      51                 :  * Revision 1.32  2005/08/07 21:00:38  fwarmerdam
      52                 :  * Initialize adfDatumParm[] to avoid warnings with gcc 4.
      53                 :  *
      54                 :  * Revision 1.31  2005/05/12 22:07:52  dmorissette
      55                 :  * Improved handling of Danish modified TM proj#21-24 (hss, bugs 976,1010)
      56                 :  *
      57                 :  * Revision 1.30  2005/03/22 23:24:54  dmorissette
      58                 :  * Added support for datum id in .MAP header (bug 910)
      59                 :  *
      60                 :  * Revision 1.29  2004/06/03 19:36:53  fwarmerdam
      61                 :  * fixed memory leak processing non-earth coordsys
      62                 :  *
      63                 :  * Revision 1.28  2003/03/21 14:20:42  warmerda
      64                 :  * fixed up regional mercator handling, was screwing up transverse mercator
      65                 :  *
      66                 :  * Revision 1.27  2003/01/09 17:33:26  warmerda
      67                 :  * fixed ellipsoid extraction for datum 999/9999
      68                 :  *
      69                 :  * Revision 1.26  2002/12/12 20:12:18  warmerda
      70                 :  * fixed signs of rotational parameters for TOWGS84 in WKT
      71                 :  *
      72                 :  * Revision 1.25  2002/10/15 14:33:30  warmerda
      73                 :  * Added untested support in mitab_spatialref.cpp, and mitab_coordsys.cpp for
      74                 :  * projections Regional Mercator (26), Polyconic (27), Azimuthal Equidistant -
      75                 :  * All origin latitudes (28), and Lambert Azimuthal Equal Area - any aspect (29).
      76                 :  *
      77                 :  * Revision 1.24  2002/09/23 13:16:04  warmerda
      78                 :  * fixed leak in MITABExtractCoordSysBounds()
      79                 :  *
      80                 :  * Revision 1.23  2002/04/01 19:49:24  warmerda
      81                 :  * added support for cassini/soldner - proj 30
      82                 :  *
      83                 :  * Revision 1.22  2002/03/01 19:00:15  warmerda
      84                 :  * False Easting/Northing should be in the linear units of measure in MapInfo,
      85                 :  * but in OGRSpatialReference/WKT they are always in meters.  Convert accordingly.
      86                 :  *
      87                 :  * Revision 1.21  2001/04/04 21:43:19  warmerda
      88                 :  * added code to set WGS84 values
      89                 :  *
      90                 :  * Revision 1.20  2001/01/23 21:23:42  daniel
      91                 :  * Added projection bounds lookup table, called from TABFile::SetProjInfo()
      92                 :  *
      93                 :  * Revision 1.19  2001/01/22 16:00:53  warmerda
      94                 :  * reworked swiss projection support
      95                 :  *
      96                 :  * Revision 1.18  2001/01/19 21:56:18  warmerda
      97                 :  * added untested support for Swiss Oblique Mercator
      98                 :  **********************************************************************/
      99                 : 
     100                 : #include "mitab.h"
     101                 : #include "mitab_utils.h"
     102                 : 
     103                 : extern MapInfoDatumInfo asDatumInfoList[];
     104                 : extern MapInfoSpheroidInfo asSpheroidInfoList[];
     105                 : 
     106                 : /************************************************************************/
     107                 : /*                             GetMIFParm()                             */
     108                 : /************************************************************************/
     109                 : 
     110              22 : static double GetMIFParm( char ** papszFields, int iField, double dfDefault )
     111                 : 
     112                 : {
     113              22 :     if( iField >= CSLCount(papszFields) )
     114               0 :         return dfDefault;
     115                 :     else
     116              22 :         return atof(papszFields[iField]);
     117                 : }
     118                 : 
     119                 : /************************************************************************/
     120                 : /*                      MITABCoordSys2SpatialRef()                      */
     121                 : /*                                                                      */
     122                 : /*      Convert a MIF COORDSYS string into a new OGRSpatialReference    */
     123                 : /*      object.                                                         */
     124                 : /************************************************************************/
     125                 : 
     126               4 : OGRSpatialReference *MITABCoordSys2SpatialRef( const char * pszCoordSys )
     127                 : 
     128                 : {
     129                 :     char        **papszFields;
     130                 :     OGRSpatialReference *poSR;
     131                 : 
     132                 : #ifdef MITAB_AFFINE_PARAMS  // See MITAB bug 1155
     133                 :     // Encom 2003
     134                 :     int nAffineUnits = 7;
     135                 :     double dAffineParams[6];
     136                 : #endif
     137                 : 
     138               4 :     if( pszCoordSys == NULL )
     139               0 :         return NULL;
     140                 :     
     141                 : /* -------------------------------------------------------------------- */
     142                 : /*      Parse the passed string into words.                             */
     143                 : /* -------------------------------------------------------------------- */
     144               4 :     while(*pszCoordSys == ' ') pszCoordSys++;  // Eat leading spaces
     145               4 :     if( EQUALN(pszCoordSys,"CoordSys",8) )
     146               2 :         pszCoordSys += 9;
     147                 :     
     148               4 :     papszFields = CSLTokenizeStringComplex( pszCoordSys, " ,", TRUE, FALSE );
     149                 : 
     150                 : #ifdef MITAB_AFFINE_PARAMS  // See MITAB bug 1155
     151                 : /* -------------------------------------------------------------------- */
     152                 : /*      Store and then clip off Affine information. - Encom 2003        */
     153                 : /* -------------------------------------------------------------------- */
     154                 :     int         iAffine = CSLFindString( papszFields, "Affine" );
     155                 :     int         nAffineIndex = 0;
     156                 :     int         nAffineFlag = 0;
     157                 : 
     158                 :     while( iAffine != -1 && papszFields[iAffine] != NULL )
     159                 :     {
     160                 :         nAffineFlag = 1;
     161                 :         if (nAffineIndex<2)
     162                 :         {
     163                 :             // Ignore "Affine Units"
     164                 :         }
     165                 :         else if (nAffineIndex==2)
     166                 :         {
     167                 :             // Convert units to integer (TBD)
     168                 :             nAffineUnits = TABUnitIdFromString(papszFields[iAffine]);
     169                 :             if (nAffineUnits==-1) nAffineUnits = 7; // metres is default
     170                 :         }
     171                 :         else if (nAffineIndex<=8)
     172                 :         {
     173                 :             // Store affine params
     174                 :             dAffineParams[nAffineIndex-3] = atof(papszFields[iAffine]);
     175                 :         }
     176                 :         nAffineIndex++;
     177                 : 
     178                 :         CPLFree( papszFields[iAffine] );
     179                 :         papszFields[iAffine] = NULL;
     180                 :         iAffine++;
     181                 :     }
     182                 : #endif // MITAB_AFFINE_PARAMS
     183                 : 
     184                 : /* -------------------------------------------------------------------- */
     185                 : /*      Clip off Bounds information.                                    */
     186                 : /* -------------------------------------------------------------------- */
     187               4 :     int         iBounds = CSLFindString( papszFields, "Bounds" );
     188                 : 
     189              14 :     while( iBounds != -1 && papszFields[iBounds] != NULL )
     190                 :     {
     191               6 :         CPLFree( papszFields[iBounds] );
     192               6 :         papszFields[iBounds] = NULL;
     193               6 :         iBounds++;
     194                 :     }
     195                 : 
     196                 : /* -------------------------------------------------------------------- */
     197                 : /*      Create a spatialreference object to operate on.                 */
     198                 : /* -------------------------------------------------------------------- */
     199               4 :     poSR = new OGRSpatialReference;
     200                 : 
     201                 : #ifdef MITAB_AFFINE_PARAMS  // See MITAB bug 1155
     202                 :     // Encom 2003
     203                 :     if (nAffineFlag)
     204                 :     {
     205                 :         poSR->nAffineFlag = 1;
     206                 :         poSR->nAffineUnit = nAffineUnits;
     207                 :         poSR->dAffineParamA = dAffineParams[0];
     208                 :         poSR->dAffineParamB = dAffineParams[1];
     209                 :         poSR->dAffineParamC = dAffineParams[2];
     210                 :         poSR->dAffineParamD = dAffineParams[3];
     211                 :         poSR->dAffineParamE = dAffineParams[4];
     212                 :         poSR->dAffineParamF = dAffineParams[5];
     213                 :     }
     214                 :     else
     215                 :     {
     216                 :         poSR->nAffineFlag = 0; // Encom 2005
     217                 :     }
     218                 : #endif
     219                 : 
     220                 : /* -------------------------------------------------------------------- */
     221                 : /*      Fetch the projection.                                           */
     222                 : /* -------------------------------------------------------------------- */
     223                 :     char        **papszNextField;
     224               4 :     int nProjection = 0;
     225                 : 
     226               8 :     if( CSLCount( papszFields ) >= 3
     227                 :         && EQUAL(papszFields[0],"Earth")
     228                 :         && EQUAL(papszFields[1],"Projection") )
     229                 :     {
     230               4 :         nProjection = atoi(papszFields[2]);
     231               4 :         papszNextField = papszFields + 3;
     232                 :     }
     233               0 :     else if (CSLCount( papszFields ) >= 2
     234                 :              && EQUAL(papszFields[0],"NonEarth") )
     235                 :     {
     236                 :         // NonEarth Units "..." Bounds (x, y) (x, y)
     237               0 :         nProjection = 0;
     238               0 :         papszNextField = papszFields + 2;
     239                 : 
     240               0 :         if( papszNextField[0] != NULL && EQUAL(papszNextField[0],"Units") )
     241               0 :             papszNextField++;
     242                 :     }
     243                 :     else
     244                 :     {
     245                 :         // Invalid projection string ???
     246               0 :         if (CSLCount(papszFields) > 0)
     247                 :             CPLError(CE_Warning, CPLE_IllegalArg,
     248               0 :                      "Failed parsing CoordSys: '%s'", pszCoordSys);
     249               0 :         CSLDestroy(papszFields);
     250               0 :         return NULL;
     251                 :     }
     252                 : 
     253                 : /* -------------------------------------------------------------------- */
     254                 : /*      Fetch the datum information.                                    */
     255                 : /* -------------------------------------------------------------------- */
     256               4 :     int         nDatum = 0;
     257               4 :     double      adfDatumParm[8] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
     258               4 :     int         nEllipsoid=0;
     259                 : 
     260               4 :     if( nProjection != 0 && CSLCount(papszNextField) > 0 )
     261                 :     {
     262               4 :         nDatum = atoi(papszNextField[0]);
     263               4 :         papszNextField++;
     264                 :     }
     265                 : 
     266               4 :     if( (nDatum == 999 || nDatum == 9999)
     267                 :         && CSLCount(papszNextField) >= 4 )
     268                 :     {
     269               0 :         nEllipsoid = atoi(papszNextField[0]);
     270               0 :         adfDatumParm[0] = atof(papszNextField[1]);
     271               0 :         adfDatumParm[1] = atof(papszNextField[2]);
     272               0 :         adfDatumParm[2] = atof(papszNextField[3]);
     273               0 :         papszNextField += 4;
     274                 :     }
     275                 : 
     276               4 :     if( nDatum == 9999
     277                 :         && CSLCount(papszNextField) >= 5 )
     278                 :     {
     279               0 :         adfDatumParm[3] = atof(papszNextField[0]);
     280               0 :         adfDatumParm[4] = atof(papszNextField[1]);
     281               0 :         adfDatumParm[5] = atof(papszNextField[2]);
     282               0 :         adfDatumParm[6] = atof(papszNextField[3]);
     283               0 :         adfDatumParm[7] = atof(papszNextField[4]);
     284               0 :         papszNextField += 5;
     285                 :     }
     286                 : 
     287                 : /* -------------------------------------------------------------------- */
     288                 : /*      Fetch the units string.                                         */
     289                 : /* -------------------------------------------------------------------- */
     290               4 :     const char  *pszMIFUnits = NULL;
     291               4 :     const char  *pszUnitsName = NULL;
     292               4 :     double dfUnitsConv = 1.0;
     293                 :     
     294               4 :     if( CSLCount(papszNextField) > 0 )
     295                 :     {
     296               4 :         pszMIFUnits = papszNextField[0];
     297               4 :         papszNextField++;
     298                 :     }
     299                 : 
     300               4 :     if( nProjection == 1 || pszMIFUnits == NULL )
     301                 :         /* do nothing */;
     302               4 :     else if( EQUAL(pszMIFUnits,"km") )
     303                 :     {
     304               0 :         pszUnitsName = "Kilometer"; 
     305               0 :         dfUnitsConv = 1000.0;
     306                 :     }
     307               4 :     else if( EQUAL(pszMIFUnits, "in" ) )
     308                 :     {
     309               0 :         pszUnitsName = "IINCH"; 
     310               0 :         dfUnitsConv = 0.0254; 
     311                 :     }
     312               4 :     else if( EQUAL(pszMIFUnits, "ft" ) )
     313                 :     {
     314               0 :         pszUnitsName = SRS_UL_FOOT;
     315               0 :         dfUnitsConv = atof(SRS_UL_FOOT_CONV);
     316                 :     }
     317               4 :     else if( EQUAL(pszMIFUnits, "yd" ) )
     318                 :     {
     319               0 :         pszUnitsName = "IYARD";
     320               0 :         dfUnitsConv = 0.9144;
     321                 :     }
     322               4 :     else if( EQUAL(pszMIFUnits, "mm" ) )
     323                 :     {
     324               0 :         pszUnitsName = "Millimeter";
     325               0 :         dfUnitsConv = 0.001;
     326                 :     }
     327               4 :     else if( EQUAL(pszMIFUnits, "cm" ) )
     328                 :     {
     329               0 :         pszUnitsName = "Centimeter";
     330               0 :         dfUnitsConv = 0.01;
     331                 :     }
     332               4 :     else if( EQUAL(pszMIFUnits, "m" ) )
     333                 :     {
     334               4 :         pszUnitsName = SRS_UL_METER;
     335               4 :         dfUnitsConv = 1.0;
     336                 :     }   
     337               0 :     else if( EQUAL(pszMIFUnits, "survey foot" )
     338                 :              || EQUAL(pszMIFUnits, "survey ft" ) )
     339                 :     {
     340               0 :         pszUnitsName = SRS_UL_US_FOOT;
     341               0 :         dfUnitsConv = atof(SRS_UL_US_FOOT_CONV);
     342                 :     }   
     343               0 :     else if( EQUAL(pszMIFUnits, "nmi" ) )
     344                 :     {
     345               0 :         pszUnitsName = SRS_UL_NAUTICAL_MILE;
     346               0 :         dfUnitsConv = atof(SRS_UL_NAUTICAL_MILE_CONV);
     347                 :     }   
     348               0 :     else if( EQUAL(pszMIFUnits, "li" ) )
     349                 :     {
     350               0 :         pszUnitsName = SRS_UL_LINK;
     351               0 :         dfUnitsConv = atof(SRS_UL_LINK_CONV);
     352                 :     }
     353               0 :     else if( EQUAL(pszMIFUnits, "ch" ) )
     354                 :     {
     355               0 :         pszUnitsName = SRS_UL_CHAIN;
     356               0 :         dfUnitsConv = atof(SRS_UL_CHAIN_CONV);
     357                 :     }   
     358               0 :     else if( EQUAL(pszMIFUnits, "rd" ) )
     359                 :     {
     360               0 :         pszUnitsName = SRS_UL_ROD;
     361               0 :         dfUnitsConv = atof(SRS_UL_ROD);
     362                 :     }   
     363               0 :     else if( EQUAL(pszMIFUnits, "mi" ) )
     364                 :     {
     365               0 :         pszUnitsName = "Mile";
     366               0 :         dfUnitsConv = 1609.344;
     367                 :     }
     368                 : 
     369                 : /* -------------------------------------------------------------------- */
     370                 : /*      Handle the PROJCS style projections, but add the datum          */
     371                 : /*      later.                                                          */
     372                 : /*                                                                      */
     373                 : /*      Note that per GDAL bug 1113 the false easting and north are     */
     374                 : /*      in local units, not necessarily meters.                         */
     375                 : /* -------------------------------------------------------------------- */
     376               4 :     switch( nProjection )
     377                 :     {
     378                 :         /*--------------------------------------------------------------
     379                 :          * NonEarth ... we return with an empty SpatialRef.  Eventually
     380                 :          * we might want to include the units, but not for now.
     381                 :          *
     382                 :          * __TODO__ Changed to return NULL because returning an empty
     383                 :          * SpatialRef caused confusion between Latlon and NonEarth since
     384                 :          * empty SpatialRefs do have a GEOGCS set and makes them look like
     385                 :          * Lat/Lon SpatialRefs.
     386                 :          *
     387                 :          * Ideally we would like to return a SpatialRef whith no GEGOCS
     388                 :          *-------------------------------------------------------------*/
     389                 :       case 0:
     390               0 :         poSR->SetLocalCS( "Nonearth" );
     391               0 :         break;
     392                 : 
     393                 :         /*--------------------------------------------------------------
     394                 :          * lat/long .. just add the GEOGCS later.
     395                 :          *-------------------------------------------------------------*/
     396                 :       case 1:
     397               0 :         break;
     398                 : 
     399                 :         /*--------------------------------------------------------------
     400                 :          * Cylindrical Equal Area
     401                 :          *-------------------------------------------------------------*/
     402                 :       case 2:
     403                 :         poSR->SetCEA( GetMIFParm( papszNextField, 1, 0.0 ),
     404                 :                       GetMIFParm( papszNextField, 0, 0.0 ),
     405                 :                       GetMIFParm( papszNextField, 2, 0.0 ),
     406               0 :                       GetMIFParm( papszNextField, 3, 0.0 ) );
     407               0 :         break;
     408                 : 
     409                 :         /*--------------------------------------------------------------
     410                 :          * Lambert Conic Conformal
     411                 :          *-------------------------------------------------------------*/
     412                 :       case 3:
     413                 :         poSR->SetLCC( GetMIFParm( papszNextField, 2, 0.0 ),
     414                 :                       GetMIFParm( papszNextField, 3, 0.0 ),
     415                 :                       GetMIFParm( papszNextField, 1, 0.0 ),
     416                 :                       GetMIFParm( papszNextField, 0, 0.0 ),
     417                 :                       GetMIFParm( papszNextField, 4, 0.0 ),
     418               2 :                       GetMIFParm( papszNextField, 5, 0.0 ) );
     419               2 :         break;
     420                 : 
     421                 :         /*--------------------------------------------------------------
     422                 :          * Lambert Azimuthal Equal Area
     423                 :          *-------------------------------------------------------------*/
     424                 :       case 4: 
     425                 :       case 29:
     426                 :         poSR->SetLAEA( GetMIFParm( papszNextField, 1, 0.0 ),
     427                 :                        GetMIFParm( papszNextField, 0, 0.0 ),
     428               0 :                        0.0, 0.0 );
     429               0 :         break;
     430                 : 
     431                 :         /*--------------------------------------------------------------
     432                 :          * Azimuthal Equidistant 
     433                 :          *-------------------------------------------------------------*/
     434                 :       case 5:  /* polar aspect only */
     435                 :       case 28: /* all aspects */
     436                 :         poSR->SetAE( GetMIFParm( papszNextField, 1, 0.0 ),
     437                 :                      GetMIFParm( papszNextField, 0, 0.0 ),
     438               0 :                      0.0, 0.0 );
     439               0 :         break;
     440                 : 
     441                 :         /*--------------------------------------------------------------
     442                 :          * Equidistant Conic
     443                 :          *-------------------------------------------------------------*/
     444                 :       case 6:
     445                 :         poSR->SetEC( GetMIFParm( papszNextField, 2, 0.0 ),
     446                 :                      GetMIFParm( papszNextField, 3, 0.0 ),
     447                 :                      GetMIFParm( papszNextField, 1, 0.0 ),
     448                 :                      GetMIFParm( papszNextField, 0, 0.0 ),
     449                 :                      GetMIFParm( papszNextField, 4, 0.0 ),
     450               0 :                      GetMIFParm( papszNextField, 5, 0.0 ) );
     451               0 :         break;
     452                 : 
     453                 :         /*--------------------------------------------------------------
     454                 :          * Hotine Oblique Mercator
     455                 :          *-------------------------------------------------------------*/
     456                 :       case 7:
     457                 :         poSR->SetHOM( GetMIFParm( papszNextField, 1, 0.0 ),
     458                 :                       GetMIFParm( papszNextField, 0, 0.0 ),
     459                 :                       GetMIFParm( papszNextField, 2, 0.0 ),
     460                 :                       90.0,
     461                 :                       GetMIFParm( papszNextField, 3, 1.0 ),
     462                 :                       GetMIFParm( papszNextField, 4, 0.0 ),
     463               0 :                       GetMIFParm( papszNextField, 5, 0.0 ) );
     464               0 :         break;
     465                 : 
     466                 :         /*--------------------------------------------------------------
     467                 :          * Transverse Mercator
     468                 :          *-------------------------------------------------------------*/
     469                 :       case 8:
     470                 :         poSR->SetTM( GetMIFParm( papszNextField, 1, 0.0 ),
     471                 :                      GetMIFParm( papszNextField, 0, 0.0 ),
     472                 :                      GetMIFParm( papszNextField, 2, 1.0 ),
     473                 :                      GetMIFParm( papszNextField, 3, 0.0 ),
     474               2 :                      GetMIFParm( papszNextField, 4, 0.0 ) );
     475               2 :         break;
     476                 : 
     477                 :         /*----------------------------------------------------------------
     478                 :          * Transverse Mercator,(modified for Danish System 34 Jylland-Fyn)
     479                 :          *---------------------------------------------------------------*/
     480                 :       case 21:
     481                 :         poSR->SetTMVariant( SRS_PT_TRANSVERSE_MERCATOR_MI_21,
     482                 :                             GetMIFParm( papszNextField, 1, 0.0 ),
     483                 :                             GetMIFParm( papszNextField, 0, 0.0 ),
     484                 :                             GetMIFParm( papszNextField, 2, 1.0 ),
     485                 :                             GetMIFParm( papszNextField, 3, 0.0 ),
     486               0 :                             GetMIFParm( papszNextField, 4, 0.0 ));
     487               0 :         break;
     488                 : 
     489                 :         /*--------------------------------------------------------------
     490                 :          * Transverse Mercator,(modified for Danish System 34 Sjaelland)
     491                 :          *-------------------------------------------------------------*/
     492                 :       case 22:
     493                 :         poSR->SetTMVariant( SRS_PT_TRANSVERSE_MERCATOR_MI_22,
     494                 :                             GetMIFParm( papszNextField, 1, 0.0 ),
     495                 :                             GetMIFParm( papszNextField, 0, 0.0 ),
     496                 :                             GetMIFParm( papszNextField, 2, 1.0 ),
     497                 :                             GetMIFParm( papszNextField, 3, 0.0 ),
     498               0 :                             GetMIFParm( papszNextField, 4, 0.0 ));
     499               0 :         break;
     500                 : 
     501                 :         /*----------------------------------------------------------------
     502                 :          * Transverse Mercator,(modified for Danish System 34/45 Bornholm)
     503                 :          *---------------------------------------------------------------*/
     504                 :       case 23:
     505                 :         poSR->SetTMVariant( SRS_PT_TRANSVERSE_MERCATOR_MI_23,
     506                 :                             GetMIFParm( papszNextField, 1, 0.0 ),
     507                 :                             GetMIFParm( papszNextField, 0, 0.0 ),
     508                 :                             GetMIFParm( papszNextField, 2, 1.0 ),
     509                 :                             GetMIFParm( papszNextField, 3, 0.0 ),
     510               0 :                             GetMIFParm( papszNextField, 4, 0.0 ));
     511               0 :         break;
     512                 : 
     513                 :         /*--------------------------------------------------------------
     514                 :          * Transverse Mercator,(modified for Finnish KKJ)
     515                 :          *-------------------------------------------------------------*/
     516                 :       case 24:
     517                 :         poSR->SetTMVariant( SRS_PT_TRANSVERSE_MERCATOR_MI_24,
     518                 :                             GetMIFParm( papszNextField, 1, 0.0 ),
     519                 :                             GetMIFParm( papszNextField, 0, 0.0 ),
     520                 :                             GetMIFParm( papszNextField, 2, 1.0 ),
     521                 :                             GetMIFParm( papszNextField, 3, 0.0 ),
     522               0 :                             GetMIFParm( papszNextField, 4, 0.0 ));
     523               0 :         break;
     524                 : 
     525                 :         /*--------------------------------------------------------------
     526                 :          * Albers Conic Equal Area
     527                 :          *-------------------------------------------------------------*/
     528                 :       case 9:
     529                 :         poSR->SetACEA( GetMIFParm( papszNextField, 2, 0.0 ),
     530                 :                        GetMIFParm( papszNextField, 3, 0.0 ),
     531                 :                        GetMIFParm( papszNextField, 1, 0.0 ),
     532                 :                        GetMIFParm( papszNextField, 0, 0.0 ),
     533                 :                        GetMIFParm( papszNextField, 4, 0.0 ),
     534               0 :                        GetMIFParm( papszNextField, 5, 0.0 ) );
     535               0 :         break;
     536                 : 
     537                 :         /*--------------------------------------------------------------
     538                 :          * Mercator
     539                 :          *-------------------------------------------------------------*/
     540                 :       case 10:
     541                 :         poSR->SetMercator( 0.0, GetMIFParm( papszNextField, 0, 0.0 ),
     542               0 :                            1.0, 0.0, 0.0 );
     543               0 :         break;
     544                 : 
     545                 :         /*--------------------------------------------------------------
     546                 :          * Miller Cylindrical
     547                 :          *-------------------------------------------------------------*/
     548                 :       case 11:
     549                 :         poSR->SetMC( 0.0, GetMIFParm( papszNextField, 0, 0.0 ),
     550               0 :                      0.0, 0.0 );
     551               0 :         break;
     552                 : 
     553                 :         /*--------------------------------------------------------------
     554                 :          * Robinson
     555                 :          *-------------------------------------------------------------*/
     556                 :       case 12:
     557                 :         poSR->SetRobinson( GetMIFParm( papszNextField, 0, 0.0 ),
     558               0 :                            0.0, 0.0 );
     559               0 :         break;
     560                 : 
     561                 :         /*--------------------------------------------------------------
     562                 :          * Mollweide
     563                 :          *-------------------------------------------------------------*/
     564                 :       case 13:
     565                 :         poSR->SetMollweide( GetMIFParm( papszNextField, 0, 0.0 ),
     566               0 :                             0.0, 0.0 );
     567                 : 
     568                 :         /*--------------------------------------------------------------
     569                 :          * Eckert IV
     570                 :          *-------------------------------------------------------------*/
     571                 :       case 14:
     572                 :         poSR->SetEckertIV( GetMIFParm( papszNextField, 0, 0.0 ),
     573               0 :                            0.0, 0.0 );
     574               0 :         break;
     575                 : 
     576                 :         /*--------------------------------------------------------------
     577                 :          * Eckert VI
     578                 :          *-------------------------------------------------------------*/
     579                 :       case 15:
     580                 :         poSR->SetEckertVI( GetMIFParm( papszNextField, 0, 0.0 ),
     581               0 :                            0.0, 0.0 );
     582               0 :         break;
     583                 : 
     584                 :         /*--------------------------------------------------------------
     585                 :          * Sinusoidal
     586                 :          *-------------------------------------------------------------*/
     587                 :       case 16:
     588                 :         poSR->SetSinusoidal( GetMIFParm( papszNextField, 0, 0.0 ),
     589               0 :                              0.0, 0.0 );
     590               0 :         break;
     591                 : 
     592                 :         /*--------------------------------------------------------------
     593                 :          * Gall
     594                 :          *-------------------------------------------------------------*/
     595                 :       case 17:
     596                 :         poSR->SetGS( GetMIFParm( papszNextField, 0, 0.0 ),
     597               0 :                      0.0, 0.0 );
     598               0 :         break;
     599                 :         
     600                 :         /*--------------------------------------------------------------
     601                 :          * New Zealand Map Grid
     602                 :          *-------------------------------------------------------------*/
     603                 :       case 18:
     604                 :         poSR->SetNZMG( GetMIFParm( papszNextField, 1, 0.0 ),
     605                 :                        GetMIFParm( papszNextField, 0, 0.0 ),
     606                 :                        GetMIFParm( papszNextField, 2, 0.0 ),
     607               0 :                        GetMIFParm( papszNextField, 3, 0.0 ) );
     608               0 :         break;
     609                 : 
     610                 :         /*--------------------------------------------------------------
     611                 :          * Lambert Conic Conformal (Belgium)
     612                 :          *-------------------------------------------------------------*/
     613                 :       case 19:
     614                 :         poSR->SetLCCB( GetMIFParm( papszNextField, 2, 0.0 ),
     615                 :                        GetMIFParm( papszNextField, 3, 0.0 ),
     616                 :                        GetMIFParm( papszNextField, 1, 0.0 ),
     617                 :                        GetMIFParm( papszNextField, 0, 0.0 ),
     618                 :                        GetMIFParm( papszNextField, 4, 0.0 ),
     619               0 :                        GetMIFParm( papszNextField, 5, 0.0 ) );
     620               0 :         break;
     621                 : 
     622                 :         /*--------------------------------------------------------------
     623                 :          * Stereographic
     624                 :          *-------------------------------------------------------------*/
     625                 :       case 20:
     626                 :       case 31: /* double stereographic */
     627                 :         poSR->SetStereographic( 
     628                 :             GetMIFParm( papszNextField, 1, 0.0 ),
     629                 :             GetMIFParm( papszNextField, 0, 0.0 ),
     630                 :             GetMIFParm( papszNextField, 2, 1.0 ),
     631                 :             GetMIFParm( papszNextField, 3, 0.0 ),
     632               0 :             GetMIFParm( papszNextField, 4, 0.0 ) );
     633               0 :         break;
     634                 : 
     635                 :         /*--------------------------------------------------------------
     636                 :          * Swiss Oblique Mercator / Cylindrical
     637                 :          *-------------------------------------------------------------*/
     638                 :       case 25:
     639                 :         poSR->SetSOC( GetMIFParm( papszNextField, 1, 0.0 ),
     640                 :                       GetMIFParm( papszNextField, 0, 0.0 ),
     641                 :                       GetMIFParm( papszNextField, 2, 0.0 ),
     642               0 :                       GetMIFParm( papszNextField, 3, 0.0 ) );
     643               0 :         break;
     644                 : 
     645                 :         /*--------------------------------------------------------------
     646                 :          * Regional Mercator
     647                 :          *-------------------------------------------------------------*/
     648                 :       case 26:
     649                 :         poSR->SetMercator( GetMIFParm( papszNextField, 1, 0.0 ), 
     650                 :                            GetMIFParm( papszNextField, 0, 0.0 ),
     651               0 :                            1.0, 0.0, 0.0 );
     652               0 :         break;
     653                 : 
     654                 :         /*--------------------------------------------------------------
     655                 :          * Polygonic
     656                 :          *-------------------------------------------------------------*/
     657                 :       case 27:
     658                 :         poSR->SetPolyconic( GetMIFParm( papszNextField, 1, 0.0 ), 
     659                 :                             GetMIFParm( papszNextField, 0, 0.0 ),
     660                 :                           GetMIFParm( papszNextField, 2, 0.0 ),
     661               0 :                           GetMIFParm( papszNextField, 3, 0.0 ) );
     662               0 :         break;
     663                 : 
     664                 :         /*--------------------------------------------------------------
     665                 :          * CassiniSoldner
     666                 :          *-------------------------------------------------------------*/
     667                 :       case 30:
     668                 :         poSR->SetCS( 
     669                 :             GetMIFParm( papszNextField, 1, 0.0 ),
     670                 :             GetMIFParm( papszNextField, 0, 0.0 ),
     671                 :             GetMIFParm( papszNextField, 2, 0.0 ),
     672               0 :             GetMIFParm( papszNextField, 3, 0.0 ) );
     673                 :         break;
     674                 : 
     675                 :       default:
     676                 :         break;
     677                 :     }
     678                 : 
     679                 : /* -------------------------------------------------------------------- */
     680                 : /*      Set linear units.                                               */
     681                 : /* -------------------------------------------------------------------- */
     682               4 :     if( pszUnitsName != NULL )
     683               4 :         poSR->SetLinearUnits( pszUnitsName, dfUnitsConv );
     684                 : 
     685                 : /* -------------------------------------------------------------------- */
     686                 : /*      For Non-Earth projection, we're done at this point.             */
     687                 : /* -------------------------------------------------------------------- */
     688               4 :     if (nProjection == 0)
     689                 :     {
     690               0 :         CSLDestroy(papszFields);
     691               0 :         return poSR;
     692                 :     }
     693                 : 
     694                 : /* ==================================================================== */
     695                 : /*      Establish the GeogCS                                            */
     696                 : /* ==================================================================== */
     697               4 :     const char *pszGeogName = "unnamed";
     698               4 :     const char *pszSpheroidName = "GRS_1980";
     699               4 :     double      dfSemiMajor = 6378137.0;
     700               4 :     double      dfInvFlattening = 298.257222101;
     701               4 :     const char *pszPrimeM = "Greenwich";
     702               4 :     double      dfPMLongToGreenwich = 0.0;
     703                 : 
     704                 : /* -------------------------------------------------------------------- */
     705                 : /*      Find the datum, and collect it's parameters if possible.        */
     706                 : /* -------------------------------------------------------------------- */
     707                 :     int         iDatum;
     708               4 :     MapInfoDatumInfo *psDatumInfo = NULL;
     709                 :     
     710             392 :     for( iDatum = 0; asDatumInfoList[iDatum].nMapInfoDatumID != -1; iDatum++ )
     711                 :     {
     712             392 :         if( asDatumInfoList[iDatum].nMapInfoDatumID == nDatum )
     713                 :         {
     714               4 :             psDatumInfo = asDatumInfoList + iDatum;
     715               4 :             break;
     716                 :         }
     717                 :     }
     718                 : 
     719               4 :     if( asDatumInfoList[iDatum].nMapInfoDatumID == -1
     720                 :         && nDatum != 999 && nDatum != 9999 )
     721                 :     {
     722                 :         /* use WGS84 */
     723               0 :         psDatumInfo = asDatumInfoList + 0;
     724                 :     }
     725                 : 
     726               4 :     if( psDatumInfo != NULL )
     727                 :     {
     728               4 :         nEllipsoid = psDatumInfo->nEllipsoid;
     729               4 :         adfDatumParm[0] =  psDatumInfo->dfShiftX;
     730               4 :         adfDatumParm[1] = psDatumInfo->dfShiftY;
     731               4 :         adfDatumParm[2] = psDatumInfo->dfShiftZ;
     732               4 :         adfDatumParm[3] = psDatumInfo->dfDatumParm0;
     733               4 :         adfDatumParm[4] = psDatumInfo->dfDatumParm1;
     734               4 :         adfDatumParm[5] = psDatumInfo->dfDatumParm2;
     735               4 :         adfDatumParm[6] = psDatumInfo->dfDatumParm3;
     736               4 :         adfDatumParm[7] = psDatumInfo->dfDatumParm4;
     737                 :     }
     738                 :     
     739                 : /* -------------------------------------------------------------------- */
     740                 : /*      Set the spheroid if it is known from the table.                 */
     741                 : /* -------------------------------------------------------------------- */
     742              24 :     for( int i = 0; asSpheroidInfoList[i].nMapInfoId != -1; i++ )
     743                 :     {
     744              24 :         if( asSpheroidInfoList[i].nMapInfoId == nEllipsoid )
     745                 :         {
     746               4 :             dfSemiMajor = asSpheroidInfoList[i].dfA;
     747               4 :             dfInvFlattening = asSpheroidInfoList[i].dfInvFlattening;
     748               4 :             pszSpheroidName = asSpheroidInfoList[i].pszMapinfoName;
     749               4 :             break;
     750                 :         }
     751                 :     }
     752                 : 
     753                 : /* -------------------------------------------------------------------- */
     754                 : /*      apply datum parameters.                                         */
     755                 : /* -------------------------------------------------------------------- */
     756                 :     char        szDatumName[128];
     757                 : 
     758               4 :     if( nDatum == 999 )
     759                 :     {
     760                 :         sprintf( szDatumName,
     761                 :                  "MIF 9999,%d,%.15g,%.15g,%.15g",
     762                 :                  nEllipsoid,
     763                 :                  adfDatumParm[0],
     764                 :                  adfDatumParm[1],
     765               0 :                  adfDatumParm[2] );
     766                 :     }
     767               4 :     else if( nDatum == 9999 )
     768                 :     {
     769                 :         sprintf( szDatumName,
     770                 :                  "MIF 9999,%d,%.15g,%.15g,%.15g,%.15g,%.15g,%.15g,%.15g,%.15g",
     771                 :                  nEllipsoid,
     772                 :                  adfDatumParm[0],
     773                 :                  adfDatumParm[1],
     774                 :                  adfDatumParm[2],
     775                 :                  adfDatumParm[3],
     776                 :                  adfDatumParm[4],
     777                 :                  adfDatumParm[5],
     778                 :                  adfDatumParm[6],
     779               0 :                  adfDatumParm[7] );
     780                 :     }
     781               8 :     else if( psDatumInfo->pszOGCDatumName != NULL
     782                 :              && strlen(psDatumInfo->pszOGCDatumName) > 0 )
     783                 :     {
     784                 :         strncpy( szDatumName, psDatumInfo->pszOGCDatumName,
     785               4 :                  sizeof(szDatumName) );
     786                 :     }
     787                 :     else
     788                 :     {
     789               0 :         sprintf( szDatumName, "MIF %d", nDatum );
     790                 :     }
     791                 : 
     792                 : /* -------------------------------------------------------------------- */
     793                 : /*      Set prime meridian for 9999 datums.                             */
     794                 : /* -------------------------------------------------------------------- */
     795               4 :     if( nDatum == 9999 || adfDatumParm[7] != 0.0 )
     796                 :     {
     797               1 :         pszPrimeM = "non-Greenwich";
     798               1 :         dfPMLongToGreenwich = adfDatumParm[7];
     799                 :     }
     800                 : 
     801                 : /* -------------------------------------------------------------------- */
     802                 : /*      Set the GeogCS.                                                 */
     803                 : /* -------------------------------------------------------------------- */
     804                 :     poSR->SetGeogCS( pszGeogName, szDatumName, pszSpheroidName,
     805                 :                      dfSemiMajor, dfInvFlattening,
     806                 :                      pszPrimeM, dfPMLongToGreenwich,
     807                 :                      SRS_UA_DEGREE,
     808               4 :                      atof(SRS_UA_DEGREE_CONV) );
     809                 : 
     810                 :     poSR->SetTOWGS84( adfDatumParm[0], adfDatumParm[1], adfDatumParm[2],
     811                 :                       -adfDatumParm[3], -adfDatumParm[4], -adfDatumParm[5], 
     812               4 :                       adfDatumParm[6] );
     813                 : 
     814                 : /* -------------------------------------------------------------------- */
     815                 : /*      Report on translation.                                          */
     816                 : /* -------------------------------------------------------------------- */
     817                 :     char        *pszWKT;
     818                 : 
     819               4 :     poSR->exportToWkt( &pszWKT );
     820               4 :     if( pszWKT != NULL )
     821                 :     {
     822                 :         CPLDebug( "MITAB",
     823                 :                   "This CoordSys value:\n%s\nwas translated to:\n%s\n",
     824               4 :                   pszCoordSys, pszWKT );
     825               4 :         CPLFree( pszWKT );
     826                 :     }
     827                 : 
     828               4 :     CSLDestroy(papszFields);
     829                 : 
     830               4 :     return poSR;
     831                 : }
     832                 : 
     833                 : /************************************************************************/
     834                 : /*                      MITABSpatialRef2CoordSys()                      */
     835                 : /*                                                                      */
     836                 : /*      Converts a OGRSpatialReference object into a MIF COORDSYS       */
     837                 : /*      string.                                                         */
     838                 : /*                                                                      */
     839                 : /*      The function returns a newly allocated string that should be    */
     840                 : /*      CPLFree()'d by the caller.                                      */
     841                 : /************************************************************************/
     842                 : 
     843               1 : char *MITABSpatialRef2CoordSys( OGRSpatialReference * poSR )
     844                 : 
     845                 : {
     846               1 :     if( poSR == NULL )
     847               0 :         return NULL;
     848                 :     
     849                 :     /*-----------------------------------------------------------------
     850                 :      * Get the linear units.
     851                 :      *----------------------------------------------------------------*/
     852                 :     double      dfLinearConv;
     853                 :     char        *pszLinearUnits;
     854                 : 
     855               1 :     dfLinearConv = poSR->GetLinearUnits( &pszLinearUnits );
     856                 : 
     857                 :     /*-----------------------------------------------------------------
     858                 :      * Transform the projection and projection parameters.
     859                 :      *----------------------------------------------------------------*/
     860               1 :     const char *pszProjection = poSR->GetAttrValue("PROJECTION");
     861                 :     double      parms[10];
     862               1 :     int         nProjection = 0;
     863               1 :     int         nParmCount = 0;
     864                 : 
     865               1 :     if( pszProjection == NULL )
     866                 :     {
     867                 :         /*--------------------------------------------------------------
     868                 :          * NULL projection.  
     869                 :          * We have 2 possibilities: CoordSys NonEarth or Lat/Lon 
     870                 :          * NonEarth ... is an empty SpatialRef.  
     871                 :          * Lat/Lon has no "PROJECTION" but GEOGCS is set
     872                 :          *-------------------------------------------------------------*/
     873               0 :          if ( poSR->GetAttrValue("GEOGCS") == NULL)
     874               0 :             nProjection = 0; // Non-Earth
     875                 :         else
     876               0 :             nProjection = 1; // Lat/Lon
     877                 :     }
     878               1 :     else if( EQUAL(pszProjection,SRS_PT_ALBERS_CONIC_EQUAL_AREA) )
     879                 :     {
     880               0 :         nProjection = 9;
     881               0 :         parms[0] = poSR->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
     882               0 :         parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
     883               0 :         parms[2] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
     884               0 :         parms[3] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
     885               0 :         parms[4] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
     886               0 :         parms[5] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
     887               0 :         nParmCount = 6;
     888                 :     }
     889                 : 
     890               1 :     else if( EQUAL(pszProjection,SRS_PT_AZIMUTHAL_EQUIDISTANT) )
     891                 :     {
     892               0 :         nProjection = 5;
     893               0 :         parms[0] = poSR->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
     894               0 :         parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
     895               0 :         parms[2] = 90.0;
     896               0 :         nParmCount = 3;
     897                 : 
     898               0 :         if( ABS((ABS(parms[1]) - 90)) > 0.001 )
     899               0 :             nProjection = 28;
     900                 :     }
     901                 : 
     902               1 :     else if( EQUAL(pszProjection,SRS_PT_CYLINDRICAL_EQUAL_AREA) )
     903                 :     {
     904               0 :         nProjection = 2;
     905               0 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
     906               0 :         parms[1] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
     907               0 :         nParmCount = 2;
     908                 :     }
     909                 : 
     910               1 :     else if( EQUAL(pszProjection,SRS_PT_ECKERT_IV) )
     911                 :     {
     912               0 :         nProjection = 14;
     913               0 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
     914               0 :         nParmCount = 1;
     915                 :     }
     916                 : 
     917               1 :     else if( EQUAL(pszProjection,SRS_PT_ECKERT_VI) )
     918                 :     {
     919               0 :         nProjection = 15;
     920               0 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
     921               0 :         nParmCount = 1;
     922                 :     }
     923                 : 
     924               1 :     else if( EQUAL(pszProjection,SRS_PT_EQUIDISTANT_CONIC) )
     925                 :     {
     926               0 :         nProjection = 6;
     927               0 :         parms[0] = poSR->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
     928               0 :         parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
     929               0 :         parms[2] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
     930               0 :         parms[3] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
     931               0 :         parms[4] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
     932               0 :         parms[5] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
     933               0 :         nParmCount = 6;
     934                 :     }
     935                 : 
     936               1 :     else if( EQUAL(pszProjection,SRS_PT_GALL_STEREOGRAPHIC) )
     937                 :     {
     938               0 :         nProjection = 17;
     939               0 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
     940               0 :         nParmCount = 1;
     941                 :     }
     942                 : 
     943               1 :     else if( EQUAL(pszProjection,SRS_PT_HOTINE_OBLIQUE_MERCATOR) )
     944                 :     {
     945               0 :         nProjection = 7;
     946               0 :         parms[0] = poSR->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
     947               0 :         parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
     948               0 :         parms[2] = poSR->GetProjParm(SRS_PP_AZIMUTH,0.0);
     949               0 :         parms[3] = poSR->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
     950               0 :         parms[4] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
     951               0 :         parms[5] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
     952               0 :         nParmCount = 6;
     953                 :     }
     954                 : 
     955               1 :     else if( EQUAL(pszProjection,SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA) )
     956                 :     {
     957               0 :         nProjection = 4;
     958               0 :         parms[0] = poSR->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
     959               0 :         parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
     960               0 :         parms[2] = 90.0;
     961               0 :         nParmCount = 3;
     962                 : 
     963               0 :         if( ABS((ABS(parms[1]) - 90)) > 0.001 )
     964               0 :             nProjection = 28;
     965                 :     }
     966                 : 
     967               1 :     else if( EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP) )
     968                 :     {
     969               1 :         nProjection = 3;
     970               1 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
     971               1 :         parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
     972               1 :         parms[2] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
     973               1 :         parms[3] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
     974               1 :         parms[4] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
     975               1 :         parms[5] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
     976               1 :         nParmCount = 6;
     977                 :     }
     978                 : 
     979               0 :     else if( EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM) )
     980                 :     {
     981               0 :         nProjection = 19;
     982               0 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
     983               0 :         parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
     984               0 :         parms[2] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
     985               0 :         parms[3] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
     986               0 :         parms[4] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
     987               0 :         parms[5] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
     988               0 :         nParmCount = 6;
     989                 :     }
     990                 : 
     991               0 :     else if( EQUAL(pszProjection,SRS_PT_MERCATOR_1SP) )
     992                 :     {
     993               0 :         nProjection = 10;
     994               0 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
     995               0 :         parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
     996               0 :         nParmCount = 1;
     997                 : 
     998               0 :         if( parms[1] != 0.0 )
     999                 :         {
    1000               0 :             nProjection = 26;
    1001               0 :             nParmCount = 2;
    1002                 :         }
    1003                 :     }
    1004                 : 
    1005               0 :     else if( EQUAL(pszProjection,SRS_PT_MILLER_CYLINDRICAL) )
    1006                 :     {
    1007               0 :         nProjection = 11;
    1008               0 :         parms[0] = poSR->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
    1009               0 :         nParmCount = 1;
    1010                 :     }
    1011                 : 
    1012               0 :     else if( EQUAL(pszProjection,SRS_PT_MOLLWEIDE) )
    1013                 :     {
    1014               0 :         nProjection = 13;
    1015               0 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1016               0 :         nParmCount = 1;
    1017                 :     }
    1018                 : 
    1019               0 :     else if( EQUAL(pszProjection,SRS_PT_SWISS_OBLIQUE_CYLINDRICAL) )
    1020                 :     {
    1021               0 :         nProjection = 25;
    1022               0 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1023               0 :         parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1024               0 :         parms[2] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1025               0 :         parms[3] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1026               0 :         nParmCount = 4;
    1027                 :     }
    1028                 : 
    1029               0 :     else if( EQUAL(pszProjection,SRS_PT_ROBINSON) )
    1030                 :     {
    1031               0 :         nProjection = 12;
    1032               0 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1033               0 :         nParmCount = 1;
    1034                 :     }
    1035                 : 
    1036               0 :     else if( EQUAL(pszProjection,SRS_PT_SINUSOIDAL) )
    1037                 :     {
    1038               0 :         nProjection = 16;
    1039               0 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1040               0 :         nParmCount = 1;
    1041                 :     }
    1042                 : 
    1043               0 :     else if( EQUAL(pszProjection,SRS_PT_STEREOGRAPHIC) )
    1044                 :     {
    1045               0 :         nProjection = 20;
    1046               0 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1047               0 :         parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1048               0 :         parms[2] = poSR->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
    1049               0 :         parms[3] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1050               0 :         parms[4] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1051               0 :         nParmCount = 5;
    1052                 :     }
    1053                 : 
    1054               0 :     else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR) )
    1055                 :     {
    1056               0 :         nProjection = 8;
    1057               0 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1058               0 :         parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1059               0 :         parms[2] = poSR->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
    1060               0 :         parms[3] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1061               0 :         parms[4] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1062               0 :         nParmCount = 5;
    1063                 :     }
    1064                 : 
    1065                 :     // Transverse Mercator,(modified for Danish System 34 Jylland-Fyn)
    1066               0 :     else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_21) )
    1067                 :     {
    1068               0 :        nProjection = 21;
    1069               0 :        parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1070               0 :        parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1071               0 :        parms[2] = poSR->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
    1072               0 :        parms[3] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1073               0 :        parms[4] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1074               0 :        nParmCount = 5;
    1075                 :     }
    1076                 : 
    1077                 :     // Transverse Mercator,(modified for Danish System 34 Sjaelland)
    1078               0 :     else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_22) )
    1079                 :     {
    1080               0 :        nProjection = 22;
    1081               0 :        parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1082               0 :        parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1083               0 :        parms[2] = poSR->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
    1084               0 :        parms[3] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1085               0 :        parms[4] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1086               0 :        nParmCount = 5;
    1087                 :     }
    1088                 : 
    1089                 :     // Transverse Mercator,(modified for Danish System 34/45 Bornholm)
    1090               0 :     else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_23) )
    1091                 :     {
    1092               0 :        nProjection = 23;
    1093               0 :        parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1094               0 :        parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1095               0 :        parms[2] = poSR->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
    1096               0 :        parms[3] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1097               0 :        parms[4] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1098               0 :        nParmCount = 5;
    1099                 :     }
    1100                 : 
    1101                 :     // Transverse Mercator,(modified for Finnish KKJ)
    1102               0 :     else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_24) )
    1103                 :     {
    1104               0 :        nProjection = 24;
    1105               0 :        parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1106               0 :        parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1107               0 :        parms[2] = poSR->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
    1108               0 :        parms[3] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1109               0 :        parms[4] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1110               0 :        nParmCount = 5;
    1111                 :     }
    1112                 : 
    1113               0 :     else if( EQUAL(pszProjection,SRS_PT_CASSINI_SOLDNER) )
    1114                 :     {
    1115               0 :         nProjection = 30;
    1116               0 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1117               0 :         parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1118               0 :         parms[2] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1119               0 :         parms[3] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1120               0 :         nParmCount = 4;
    1121                 :     }
    1122                 : 
    1123               0 :     else if( EQUAL(pszProjection,SRS_PT_NEW_ZEALAND_MAP_GRID) )
    1124                 :     {
    1125               0 :         nProjection = 18;
    1126               0 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1127               0 :         parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1128               0 :         parms[2] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1129               0 :         parms[3] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1130               0 :         nParmCount = 4;
    1131                 :     }
    1132                 : 
    1133               0 :     else if( EQUAL(pszProjection,SRS_PT_POLYCONIC) )
    1134                 :     {
    1135               0 :         nProjection = 27;
    1136               0 :         parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1137               0 :         parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1138               0 :         parms[2] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1139               0 :         parms[3] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1140               0 :         nParmCount = 4;
    1141                 :     }
    1142                 : 
    1143                 :     /* ==============================================================
    1144                 :      * Translate Datum and Ellipsoid
    1145                 :      * ============================================================== */
    1146               1 :     int         nDatum = 0;
    1147               1 :     double      adfDatumParm[8] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
    1148               1 :     int         nEllipsoid=0;
    1149                 :     
    1150               1 :     const char *pszWKTDatum = poSR->GetAttrValue("DATUM");
    1151                 : 
    1152               1 :     if( pszWKTDatum == NULL )
    1153                 :     {
    1154               0 :         nDatum = 0;
    1155               0 :         if( nProjection == 1 )
    1156               0 :             nProjection = 0;
    1157                 :     }
    1158                 :     
    1159                 :     /*-----------------------------------------------------------------
    1160                 :      * We know the MIF datum number, and need to look it up to
    1161                 :      * translate into datum parameters.
    1162                 :      *----------------------------------------------------------------*/
    1163               1 :     else if( EQUALN(pszWKTDatum,"MIF ",4)
    1164                 :              && atoi(pszWKTDatum+4) != 999
    1165                 :              && atoi(pszWKTDatum+4) != 9999 )
    1166                 :     {
    1167               0 :         nDatum = atoi(pszWKTDatum+4);
    1168                 :     }
    1169                 : 
    1170                 :     /*-----------------------------------------------------------------
    1171                 :      * We have the MIF datum parameters, and apply those directly.
    1172                 :      *----------------------------------------------------------------*/
    1173               1 :     else if( EQUALN(pszWKTDatum,"MIF ",4)
    1174                 :              && (atoi(pszWKTDatum+4) == 999 || atoi(pszWKTDatum+4) == 9999) )
    1175                 :     {
    1176                 :         char    **papszFields;
    1177                 :         
    1178               0 :         nDatum = atoi(pszWKTDatum+4);
    1179                 : 
    1180                 :         papszFields =
    1181               0 :             CSLTokenizeStringComplex( pszWKTDatum+4, ",", FALSE, TRUE);
    1182                 : 
    1183               0 :         if( CSLCount(papszFields) >= 5 )
    1184                 :         {
    1185               0 :             nEllipsoid = atoi(papszFields[1]);
    1186               0 :             adfDatumParm[0] = atof(papszFields[2]);
    1187               0 :             adfDatumParm[1] = atof(papszFields[3]);
    1188               0 :             adfDatumParm[2] = atof(papszFields[4]);
    1189                 :         }
    1190                 : 
    1191               0 :         if( CSLCount(papszFields) >= 10 )
    1192                 :         {
    1193               0 :             adfDatumParm[3] = atof(papszFields[5]);
    1194               0 :             adfDatumParm[4] = atof(papszFields[6]);
    1195               0 :             adfDatumParm[5] = atof(papszFields[7]);
    1196               0 :             adfDatumParm[6] = atof(papszFields[8]);
    1197               0 :             adfDatumParm[7] = atof(papszFields[9]);
    1198                 :         }
    1199                 : 
    1200               0 :         if( CSLCount(papszFields) < 5 )
    1201               0 :             nDatum = 104; /* WGS84 */
    1202                 : 
    1203               0 :         CSLDestroy( papszFields );
    1204                 :     }
    1205                 :     
    1206                 :     /*-----------------------------------------------------------------
    1207                 :      * We have a "real" datum name.  Try to look it up and get the
    1208                 :      * parameters.  If we don't find it just use WGS84.
    1209                 :      *----------------------------------------------------------------*/
    1210                 :     else 
    1211                 :     {
    1212                 :         int     i;
    1213                 : 
    1214              67 :         for( i = 0; asDatumInfoList[i].nMapInfoDatumID != -1; i++ )
    1215                 :         {
    1216              67 :             if( EQUAL(pszWKTDatum,asDatumInfoList[i].pszOGCDatumName) )
    1217                 :             {
    1218               1 :                 nDatum = asDatumInfoList[i].nMapInfoDatumID;
    1219               1 :                 break;
    1220                 :             }
    1221                 :         }
    1222                 : 
    1223               1 :         if( nDatum == 0 )
    1224               0 :             nDatum = 104; /* WGS84 */
    1225                 :     }
    1226                 : 
    1227                 :     /*-----------------------------------------------------------------
    1228                 :      * Translate the units
    1229                 :      *----------------------------------------------------------------*/
    1230               1 :     const char  *pszMIFUnits = "m";
    1231                 : 
    1232               1 :     if( nProjection == 1 )
    1233               0 :         pszMIFUnits = NULL;
    1234               1 :     else if( pszLinearUnits == NULL )
    1235               0 :         pszMIFUnits = "m";
    1236               1 :     else if( dfLinearConv == 1000.0 )
    1237               0 :         pszMIFUnits = "km";
    1238               1 :     else if( dfLinearConv == 0.0254 || EQUAL(pszLinearUnits,"Inch")
    1239                 :              || EQUAL(pszLinearUnits,"IINCH"))
    1240               0 :         pszMIFUnits = "in";
    1241               1 :     else if( dfLinearConv == atof(SRS_UL_FOOT_CONV)
    1242                 :              || EQUAL(pszLinearUnits,SRS_UL_FOOT) )
    1243               0 :         pszMIFUnits = "ft";
    1244               1 :     else if( EQUAL(pszLinearUnits,"YARD") || EQUAL(pszLinearUnits,"IYARD") 
    1245                 :              || dfLinearConv == 0.9144 )
    1246               0 :         pszMIFUnits = "yd";
    1247               1 :     else if( dfLinearConv == 0.001 )
    1248               0 :         pszMIFUnits = "mm";
    1249               1 :     else if( dfLinearConv == 0.01 )
    1250               0 :         pszMIFUnits = "cm";
    1251               1 :     else if( dfLinearConv == 1.0 )
    1252               1 :         pszMIFUnits = "m";
    1253               0 :     else if( dfLinearConv == atof(SRS_UL_US_FOOT_CONV)
    1254                 :              || EQUAL(pszLinearUnits,SRS_UL_US_FOOT) )
    1255               0 :         pszMIFUnits = "survey ft";
    1256               0 :     else if( EQUAL(pszLinearUnits,SRS_UL_NAUTICAL_MILE) )
    1257               0 :         pszMIFUnits = "nmi";
    1258               0 :     else if( EQUAL(pszLinearUnits,SRS_UL_LINK) 
    1259                 :              || EQUAL(pszLinearUnits,"GUNTERLINK") )
    1260               0 :         pszMIFUnits = "li";
    1261               0 :     else if( EQUAL(pszLinearUnits,SRS_UL_CHAIN) 
    1262                 :              || EQUAL(pszLinearUnits,"GUNTERCHAIN") )
    1263               0 :         pszMIFUnits = "ch";
    1264               0 :     else if( EQUAL(pszLinearUnits,SRS_UL_ROD) )
    1265               0 :         pszMIFUnits = "rd";
    1266               0 :     else if( EQUAL(pszLinearUnits,"Mile") 
    1267                 :              || EQUAL(pszLinearUnits,"IMILE") )
    1268               0 :         pszMIFUnits = "mi";
    1269                 :     
    1270                 : /* -------------------------------------------------------------------- */
    1271                 : /*      Build coordinate system definition.                             */
    1272                 : /* -------------------------------------------------------------------- */
    1273                 :     char        szCoordSys[256];
    1274                 : 
    1275               1 :     if( nProjection != 0 )
    1276                 :     {
    1277                 :         sprintf( szCoordSys,
    1278                 :                  "Earth Projection %d",
    1279               1 :                  nProjection );
    1280                 : 
    1281                 :     }
    1282                 :     else
    1283                 :         sprintf( szCoordSys,
    1284               0 :                  "NonEarth Units" );
    1285                 : 
    1286                 : /* -------------------------------------------------------------------- */
    1287                 : /*      Append Datum                                                    */
    1288                 : /* -------------------------------------------------------------------- */
    1289               1 :     if( nProjection != 0 )
    1290                 :     {
    1291                 :         sprintf( szCoordSys + strlen(szCoordSys),
    1292                 :                  ", %d",
    1293               1 :                  nDatum );
    1294                 : 
    1295               1 :         if( nDatum == 999 || nDatum == 9999 )
    1296                 :         {
    1297                 :             sprintf( szCoordSys + strlen(szCoordSys),
    1298                 :                      ", %d, %.15g, %.15g, %.15g",
    1299                 :                      nEllipsoid,
    1300               0 :                      adfDatumParm[0], adfDatumParm[1], adfDatumParm[2] );
    1301                 :         }
    1302                 :         
    1303               1 :         if( nDatum == 9999 )
    1304                 :         {
    1305                 :             sprintf( szCoordSys + strlen(szCoordSys),
    1306                 :                      ", %.15g, %.15g, %.15g, %.15g, %.15g",
    1307                 :                      adfDatumParm[3], adfDatumParm[4], adfDatumParm[5],
    1308               0 :                      adfDatumParm[6], adfDatumParm[7] );
    1309                 :         }
    1310                 :     }
    1311                 : 
    1312                 : /* -------------------------------------------------------------------- */
    1313                 : /*      Append units.                                                   */
    1314                 : /* -------------------------------------------------------------------- */
    1315               1 :     if( nProjection != 1 && pszMIFUnits != NULL )
    1316                 :     {
    1317               1 :         if( nProjection != 0 )
    1318               1 :             strcat( szCoordSys, "," );
    1319                 :         
    1320                 :         sprintf( szCoordSys + strlen(szCoordSys),
    1321                 :                  " \"%s\"",
    1322               1 :                  pszMIFUnits );
    1323                 :     }
    1324                 : 
    1325                 : /* -------------------------------------------------------------------- */
    1326                 : /*      Append Projection Parms.                                        */
    1327                 : /* -------------------------------------------------------------------- */
    1328               7 :     for( int iParm = 0; iParm < nParmCount; iParm++ )
    1329                 :         sprintf( szCoordSys + strlen(szCoordSys),
    1330                 :                  ", %.15g",
    1331               6 :                  parms[iParm] );
    1332                 : 
    1333                 : /* -------------------------------------------------------------------- */
    1334                 : /*      Report on translation                                           */
    1335                 : /* -------------------------------------------------------------------- */
    1336               1 :     char        *pszWKT = NULL;
    1337                 : 
    1338               1 :     poSR->exportToWkt( &pszWKT );
    1339               1 :     if( pszWKT != NULL )
    1340                 :     {
    1341                 :         CPLDebug( "MITAB",
    1342                 :                   "This WKT Projection:\n%s\n\ntranslates to:\n%s\n",
    1343               1 :                   pszWKT, szCoordSys );
    1344               1 :         CPLFree( pszWKT );
    1345                 :     }
    1346                 : 
    1347               1 :     return( CPLStrdup( szCoordSys ) );
    1348                 : }
    1349                 : 
    1350                 : 
    1351                 : /************************************************************************/
    1352                 : /*                      MITABExtractCoordSysBounds                      */
    1353                 : /*                                                                      */
    1354                 : /* Return TRUE if MIF coordsys string contains a BOUNDS parameter and   */
    1355                 : /* Set x/y min/max values.                                              */
    1356                 : /************************************************************************/
    1357                 : 
    1358                 : GBool MITABExtractCoordSysBounds( const char * pszCoordSys,
    1359                 :                                   double &dXMin, double &dYMin,
    1360               0 :                                   double &dXMax, double &dYMax )
    1361                 : 
    1362                 : {
    1363                 :     char        **papszFields;
    1364                 : 
    1365               0 :     if( pszCoordSys == NULL )
    1366               0 :         return FALSE;
    1367                 :     
    1368               0 :     papszFields = CSLTokenizeStringComplex( pszCoordSys, " ,()", TRUE, FALSE );
    1369                 : 
    1370               0 :     int iBounds = CSLFindString( papszFields, "Bounds" );
    1371                 : 
    1372               0 :     if (iBounds >= 0 && iBounds + 4 < CSLCount(papszFields))
    1373                 :     {
    1374               0 :         dXMin = atof(papszFields[++iBounds]);
    1375               0 :         dYMin = atof(papszFields[++iBounds]);
    1376               0 :         dXMax = atof(papszFields[++iBounds]);
    1377               0 :         dYMax = atof(papszFields[++iBounds]);
    1378               0 :         CSLDestroy( papszFields );
    1379               0 :         return TRUE;
    1380                 :     }
    1381                 : 
    1382               0 :     CSLDestroy( papszFields );
    1383               0 :     return FALSE;
    1384                 : }
    1385                 : 
    1386                 : 
    1387                 : /**********************************************************************
    1388                 :  *                     MITABCoordSys2TABProjInfo()
    1389                 :  *
    1390                 :  * Convert a MIF COORDSYS string into a TABProjInfo structure.
    1391                 :  *
    1392                 :  * Note that it would have been possible to achieve the same by calling
    1393                 :  * TABFile::SetSpatialRef( MITABCoordSys2SpatialRef() ) but this would 
    1394                 :  * involve lots of manipulations for cases where only a simple conversion
    1395                 :  * is required.
    1396                 :  *
    1397                 :  * Returns 0 on success, -1 on error.
    1398                 :  **********************************************************************/
    1399               0 : int MITABCoordSys2TABProjInfo(const char * pszCoordSys, TABProjInfo *psProj)
    1400                 : 
    1401                 : {
    1402                 :     char        **papszFields;
    1403                 : 
    1404                 :     // Set all fields to zero, equivalent of NonEarth Units "mi"
    1405               0 :     memset(psProj, 0, sizeof(TABProjInfo));
    1406                 : 
    1407               0 :     if( pszCoordSys == NULL )
    1408               0 :         return -1;
    1409                 :     
    1410                 :     /*-----------------------------------------------------------------
    1411                 :      * Parse the passed string into words.
    1412                 :      *----------------------------------------------------------------*/
    1413               0 :     while(*pszCoordSys == ' ') pszCoordSys++;  // Eat leading spaces
    1414               0 :     if( EQUALN(pszCoordSys,"CoordSys",8) )
    1415               0 :         pszCoordSys += 9;
    1416                 :     
    1417               0 :     papszFields = CSLTokenizeStringComplex( pszCoordSys, " ,", TRUE, FALSE );
    1418                 : 
    1419                 :     /*-----------------------------------------------------------------
    1420                 :      * Clip off Bounds information.
    1421                 :      *----------------------------------------------------------------*/
    1422               0 :     int         iBounds = CSLFindString( papszFields, "Bounds" );
    1423                 : 
    1424               0 :     while( iBounds != -1 && papszFields[iBounds] != NULL )
    1425                 :     {
    1426               0 :         CPLFree( papszFields[iBounds] );
    1427               0 :         papszFields[iBounds] = NULL;
    1428               0 :         iBounds++;
    1429                 :     }
    1430                 : 
    1431                 :     /*-----------------------------------------------------------------
    1432                 :      * Fetch the projection.
    1433                 :      *----------------------------------------------------------------*/
    1434                 :     char        **papszNextField;
    1435                 : 
    1436               0 :     if( CSLCount( papszFields ) >= 3
    1437                 :         && EQUAL(papszFields[0],"Earth")
    1438                 :         && EQUAL(papszFields[1],"Projection") )
    1439                 :     {
    1440               0 :         psProj->nProjId = atoi(papszFields[2]);
    1441               0 :         papszNextField = papszFields + 3;
    1442                 :     }
    1443               0 :     else if (CSLCount( papszFields ) >= 2
    1444                 :              && EQUAL(papszFields[0],"NonEarth") )
    1445                 :     {
    1446                 :         // NonEarth Units "..." Bounds (x, y) (x, y)
    1447               0 :         psProj->nProjId = 0;
    1448               0 :         papszNextField = papszFields + 2;
    1449                 : 
    1450               0 :         if( papszNextField[0] != NULL && EQUAL(papszNextField[0],"Units") )
    1451               0 :             papszNextField++;
    1452                 :     }
    1453                 :     else
    1454                 :     {
    1455                 :         // Invalid projection string ???
    1456               0 :         if (CSLCount(papszFields) > 0)
    1457                 :             CPLError(CE_Warning, CPLE_IllegalArg,
    1458               0 :                      "Failed parsing CoordSys: '%s'", pszCoordSys);
    1459               0 :         CSLDestroy(papszFields);
    1460               0 :         return -1;
    1461                 :     }
    1462                 : 
    1463                 :     /*-----------------------------------------------------------------
    1464                 :      * Fetch the datum information.
    1465                 :      *----------------------------------------------------------------*/
    1466               0 :     int         nDatum = 0;
    1467                 : 
    1468               0 :     if( psProj->nProjId != 0 && CSLCount(papszNextField) > 0 )
    1469                 :     {
    1470               0 :         nDatum = atoi(papszNextField[0]);
    1471               0 :         papszNextField++;
    1472                 :     }
    1473                 : 
    1474               0 :     if( (nDatum == 999 || nDatum == 9999)
    1475                 :         && CSLCount(papszNextField) >= 4 )
    1476                 :     {
    1477               0 :         psProj->nEllipsoidId = atoi(papszFields[0]);
    1478               0 :         psProj->dDatumShiftX = atof(papszNextField[1]);
    1479               0 :         psProj->dDatumShiftY = atof(papszNextField[2]);
    1480               0 :         psProj->dDatumShiftZ = atof(papszNextField[3]);
    1481               0 :         papszNextField += 4;
    1482                 : 
    1483               0 :         if( nDatum == 9999
    1484                 :             && CSLCount(papszNextField) >= 5 )
    1485                 :         {
    1486               0 :             psProj->adDatumParams[0] = atof(papszNextField[0]);
    1487               0 :             psProj->adDatumParams[1] = atof(papszNextField[1]);
    1488               0 :             psProj->adDatumParams[2] = atof(papszNextField[2]);
    1489               0 :             psProj->adDatumParams[3] = atof(papszNextField[3]);
    1490               0 :             psProj->adDatumParams[4] = atof(papszNextField[4]);
    1491               0 :             papszNextField += 5;
    1492                 :         }
    1493                 :     }
    1494               0 :     else if (nDatum != 999 && nDatum != 9999)
    1495                 :     {
    1496                 :     /*-----------------------------------------------------------------
    1497                 :      * Find the datum, and collect it's parameters if possible.
    1498                 :      *----------------------------------------------------------------*/
    1499                 :         int         iDatum;
    1500               0 :         MapInfoDatumInfo *psDatumInfo = NULL;
    1501                 :         
    1502               0 :         for(iDatum=0; asDatumInfoList[iDatum].nMapInfoDatumID != -1; iDatum++)
    1503                 :         {
    1504               0 :             if( asDatumInfoList[iDatum].nMapInfoDatumID == nDatum )
    1505                 :             {
    1506               0 :                 psDatumInfo = asDatumInfoList + iDatum;
    1507               0 :                 break;
    1508                 :             }
    1509                 :         }
    1510                 : 
    1511               0 :         if( asDatumInfoList[iDatum].nMapInfoDatumID == -1
    1512                 :             && nDatum != 999 && nDatum != 9999 )
    1513                 :         {
    1514                 :             /* use WGS84 */
    1515               0 :             psDatumInfo = asDatumInfoList + 0;
    1516                 :         }
    1517                 : 
    1518               0 :         if( psDatumInfo != NULL )
    1519                 :         {
    1520               0 :             psProj->nEllipsoidId = psDatumInfo->nEllipsoid;
    1521               0 :             psProj->nDatumId = psDatumInfo->nMapInfoDatumID;
    1522               0 :             psProj->dDatumShiftX = psDatumInfo->dfShiftX;
    1523               0 :             psProj->dDatumShiftY = psDatumInfo->dfShiftY;
    1524               0 :             psProj->dDatumShiftZ = psDatumInfo->dfShiftZ;
    1525               0 :             psProj->adDatumParams[0] = psDatumInfo->dfDatumParm0;
    1526               0 :             psProj->adDatumParams[1] = psDatumInfo->dfDatumParm1;
    1527               0 :             psProj->adDatumParams[2] = psDatumInfo->dfDatumParm2;
    1528               0 :             psProj->adDatumParams[3] = psDatumInfo->dfDatumParm3;
    1529               0 :             psProj->adDatumParams[4] = psDatumInfo->dfDatumParm4;
    1530                 :         }
    1531                 :     }    
    1532                 : 
    1533                 :     /*-----------------------------------------------------------------
    1534                 :      * Fetch the units string.
    1535                 :      *----------------------------------------------------------------*/
    1536               0 :     if( CSLCount(papszNextField) > 0 )
    1537                 :     {
    1538               0 :         psProj->nUnitsId = TABUnitIdFromString(papszNextField[0]);
    1539               0 :         papszNextField++;
    1540                 :     }
    1541                 : 
    1542                 :     /*-----------------------------------------------------------------
    1543                 :      * Finally the projection parameters.
    1544                 :      *----------------------------------------------------------------*/
    1545               0 :     for(int iParam=0; iParam < 6 && CSLCount(papszNextField) > 0; iParam++)
    1546                 :     {
    1547               0 :         psProj->adProjParams[iParam] = atof(papszNextField[0]);
    1548               0 :         papszNextField++;         
    1549                 :     }
    1550                 : 
    1551               0 :     return 0;
    1552                 : }
    1553                 : 

Generated by: LTP GCOV extension version 1.5