LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/mitab - mitab_spatialref.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 462 145 31.4 %
Date: 2012-12-26 Functions: 2 2 100.0 %

       1                 : /**********************************************************************
       2                 :  * $Id: mitab_spatialref.cpp,v 1.55 2011-06-11 00:35:00 fwarmerdam Exp $
       3                 :  *
       4                 :  * Name:     mitab_spatialref.cpp
       5                 :  * Project:  MapInfo TAB Read/Write library
       6                 :  * Language: C++
       7                 :  * Purpose:  Implementation of the SpatialRef stuff in the TABFile class.
       8                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       9                 :  *
      10                 :  **********************************************************************
      11                 :  * Copyright (c) 1999-2001, Frank Warmerdam
      12                 :  *
      13                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      14                 :  * copy of this software and associated documentation files (the "Software"),
      15                 :  * to deal in the Software without restriction, including without limitation
      16                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      17                 :  * and/or sell copies of the Software, and to permit persons to whom the
      18                 :  * Software is furnished to do so, subject to the following conditions:
      19                 :  * 
      20                 :  * The above copyright notice and this permission notice shall be included
      21                 :  * in all copies or substantial portions of the Software.
      22                 :  * 
      23                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      24                 :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      26                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      28                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
      29                 :  * DEALINGS IN THE SOFTWARE.
      30                 :  **********************************************************************
      31                 :  *
      32                 :  * $Log: mitab_spatialref.cpp,v $
      33                 :  * Revision 1.55  2011-06-11 00:35:00  fwarmerdam
      34                 :  * add support for reading google mercator (#4115)
      35                 :  *
      36                 :  * Revision 1.54  2010-10-07 18:46:26  aboudreault
      37                 :  * Fixed bad use of atof when locale setting doesn't use . for float (GDAL bug #3775)
      38                 :  *
      39                 :  * Revision 1.53  2010-09-07 16:48:08  aboudreault
      40                 :  * Removed incomplete patch for affine params support in mitab. (bug 1155)
      41                 :  *
      42                 :  * Revision 1.52  2010-07-08 17:21:12  aboudreault
      43                 :  * Put back New_Zealand Datum in asDatumInfoList
      44                 :  *
      45                 :  * Revision 1.51  2010-07-07 19:00:15  aboudreault
      46                 :  * Cleanup Win32 Compile Warnings (GDAL bug #2930)
      47                 :  *
      48                 :  * Revision 1.50  2010-07-05 17:20:14  aboudreault
      49                 :  * Added Krovak projection suppoprt (bug 2230)
      50                 :  *
      51                 :  * Revision 1.49  2009-10-15 16:16:37  fwarmerdam
      52                 :  * add the default EPSG/OGR name for new zealand datums (gdal #3187)
      53                 :  *
      54                 :  * Revision 1.48  2007/11/21 21:15:45  dmorissette
      55                 :  * Fix asDatumInfoList[] and asSpheroidInfoList[] defns/refs (bug 1826)
      56                 :  *
      57                 :  * Revision 1.47  2006/07/10 17:58:48  fwarmerdam
      58                 :  * North_American_Datum_1927 support
      59                 :  *
      60                 :  * Revision 1.46  2006/07/07 19:41:32  dmorissette
      61                 :  * Fixed problem with uninitialized sTABProj.nAffineFlag (bug 1254,1319)
      62                 :  *
      63                 :  * Revision 1.45  2006/05/09 20:21:29  fwarmerdam
      64                 :  * Coordsys false easting and northing are in the units of the coordsys, not
      65                 :  * necessarily meters.  Adjusted mitab_spatialref.cpp to reflect this.
      66                 :  * http://bugzilla.remotesensing.org/show_bug.cgi?id=1113
      67                 :  *
      68                 :  * Revision 1.44  2005/09/29 20:15:36  dmorissette
      69                 :  * More improvements to handling of modified TM projections 21-24.
      70                 :  * Added correct name stings to all datum definitions (Anthony D, bug 1155)
      71                 :  *
      72                 :  * Revision 1.43  2005/05/12 22:07:52  dmorissette
      73                 :  * Improved handling of Danish modified TM proj#21-24 (hss, bugs 976,1010)
      74                 :  *
      75                 :  * Revision 1.42  2005/03/22 23:24:54  dmorissette
      76                 :  * Added support for datum id in .MAP header (bug 910)
      77                 :  *
      78                 :  * Revision 1.41  2004/10/11 20:50:04  dmorissette
      79                 :  * 7 new datum defns, 1 fixed and list of ellipsoids updated (Bug 608,Uffe K.)
      80                 :  *
      81                 :  * Revision 1.40  2003/03/21 14:20:42  warmerda
      82                 :  * fixed up regional mercator handling, was screwing up transverse mercator
      83                 :  *
      84                 :  * Revision 1.39  2002/12/19 20:46:01  warmerda
      85                 :  * fixed spelling of Provisional_South_American_Datum_1956
      86                 :  *
      87                 :  * Revision 1.38  2002/12/12 20:12:18  warmerda
      88                 :  * fixed signs of rotational parameters for TOWGS84 in WKT
      89                 :  *
      90                 :  * Revision 1.37  2002/10/15 14:33:30  warmerda
      91                 :  * Added untested support in mitab_spatialref.cpp, and mitab_coordsys.cpp for
      92                 :  * projections Regional Mercator (26), Polyconic (27), Azimuthal Equidistant -
      93                 :  * All origin latitudes (28), and Lambert Azimuthal Equal Area - any aspect 
      94                 :  * (29).
      95                 :  *
      96                 :  * Revision 1.36  2002/09/05 15:38:16  warmerda
      97                 :  * one more ogc datum name
      98                 :  *
      99                 :  * Revision 1.35  2002/09/05 15:23:22  warmerda
     100                 :  * added some EPSG datum names provided by Siro Martello @ Cadcorp
     101                 :  *
     102                 :  * Revision 1.34  2002/04/01 19:49:24  warmerda
     103                 :  * added support for cassini/soldner - proj 30
     104                 :  *
     105                 :  * Revision 1.33  2002/03/01 19:00:15  warmerda
     106                 :  * False Easting/Northing should be in the linear units of measure in MapInfo,
     107                 :  * but in OGRSpatialReference/WKT they are always in meters.  Convert accordingly.
     108                 :  *
     109                 :  * Revision 1.32  2001/10/25 16:13:41  warmerda
     110                 :  * Added OGC string for datum 12
     111                 :  *
     112                 :  * Revision 1.31  2001/08/10 21:25:59  warmerda
     113                 :  * SetSpatialRef() now makes a clone of the srs instead of taking a ref to it
     114                 :  *
     115                 :  * Revision 1.30  2001/04/23 17:38:06  warmerda
     116                 :  * fixed use of freed points bug for datum 999/9999
     117                 :  *
     118                 :  * Revision 1.29  2001/04/04 21:43:19  warmerda
     119                 :  * added code to set WGS84 values
     120                 :  *
     121                 :  * Revision 1.28  2001/01/23 21:23:42  daniel
     122                 :  * Added projection bounds lookup table, called from TABFile::SetProjInfo()
     123                 :  *
     124                 :  * Revision 1.27  2001/01/22 16:00:53  warmerda
     125                 :  * reworked swiss projection support
     126                 :  *
     127                 :  * Revision 1.26  2001/01/19 21:56:18  warmerda
     128                 :  * added untested support for Swiss Oblique Mercator
     129                 :  *
     130                 :  * Revision 1.25  2000/12/05 14:56:55  daniel
     131                 :  * Added some missing unit names (aliases) in TABFile::SetSpatialRef()
     132                 :  *
     133                 :  * Revision 1.24  2000/10/16 21:44:50  warmerda
     134                 :  * added nonearth support
     135                 :  *
     136                 :  * Revision 1.23  2000/10/16 18:01:20  warmerda
     137                 :  * added check for NULL on passed in spatial ref
     138                 :  *
     139                 :  * Revision 1.22  2000/10/02 14:46:36  daniel
     140                 :  * Added 7 parameter datums with id 1000+
     141                 :  *
     142                 :  * Revision 1.21  2000/09/29 22:09:18  daniel
     143                 :  * Added new datums/ellipsoid from MapInfo V6.0
     144                 :  *
     145                 :  * Revision 1.20  2000/09/28 16:39:44  warmerda
     146                 :  * avoid warnings for unused, and unitialized variables
     147                 :  *
     148                 :  * Revision 1.19  2000/02/07 17:43:17  daniel
     149                 :  * Fixed offset in parsing of custom datum string in SetSpatialRef()
     150                 :  *
     151                 :  * Revision 1.18  2000/02/04 05:30:50  daniel
     152                 :  * Fixed problem in GetSpatialRef() with szDatumName[] buffer size and added
     153                 :  * use of an epsilon in comparing of datum parameters.
     154                 :  *
     155                 :  * Revision 1.17  2000/01/15 22:30:45  daniel
     156                 :  * Switch to MIT/X-Consortium OpenSource license
     157                 :  *
     158                 :  * Revision 1.16  1999/12/21 20:01:47  warmerda
     159                 :  * added support for DATUM 0
     160                 :  *
     161                 :  * Revision 1.15  1999/11/11 02:56:17  warmerda
     162                 :  * fixed problems with stereographic
     163                 :  *
     164                 :  * Revision 1.14  1999/11/10 20:13:12  warmerda
     165                 :  * implement spheroid table
     166                 :  *
     167                 :  * Revision 1.13  1999/11/09 22:31:38  warmerda
     168                 :  * initial implementation of MIF CoordSys support
     169                 :  *
     170                 :  * Revision 1.12  1999/10/19 16:31:32  warmerda
     171                 :  * Improved mile support.
     172                 :  *
     173                 :  * Revision 1.11  1999/10/19 16:27:50  warmerda
     174                 :  * Added support for Mile (units=0).  Also added support for nonearth
     175                 :  * projections.
     176                 :  *
     177                 :  * Revision 1.10  1999/10/05 18:56:08  warmerda
     178                 :  * fixed lots of bugs with projection parameters
     179                 :  *
     180                 :  * Revision 1.9  1999/10/04 21:17:47  warmerda
     181                 :  * Make sure that asDatumInfoList comparisons include the ellipsoid code.
     182                 :  * Don't include OGC name for local NAD27 values.  Put NAD83 ahead of GRS80
     183                 :  * so it will be used in preference even though they are identical parms.
     184                 :  *
     185                 :  * Revision 1.8  1999/10/04 19:46:42  warmerda
     186                 :  * assorted changes, including rework of units
     187                 :  *
     188                 :  * Revision 1.7  1999/09/28 04:52:17  daniel
     189                 :  * Added missing param in sprintf() format for szDatumName[]
     190                 :  *
     191                 :  * Revision 1.6  1999/09/28 02:51:46  warmerda
     192                 :  * Added ellipsoid codes, and bulk of write implementation.
     193                 :  *
     194                 :  * Revision 1.5  1999/09/27 21:23:41  warmerda
     195                 :  * added more projections
     196                 :  *
     197                 :  * Revision 1.4  1999/09/24 04:01:28  warmerda
     198                 :  * remember nMIDatumId changes
     199                 :  *
     200                 :  * Revision 1.3  1999/09/23 19:51:38  warmerda
     201                 :  * added datum mapping table support
     202                 :  *
     203                 :  * Revision 1.2  1999/09/22 23:04:59  daniel
     204                 :  * Handle reference count on OGRSpatialReference properly
     205                 :  *
     206                 :  * Revision 1.1  1999/09/21 19:39:22  daniel
     207                 :  * Moved Get/SetSpatialRef() to a separate file
     208                 :  *
     209                 :  **********************************************************************/
     210                 : 
     211                 : #include "mitab.h"
     212                 : 
     213                 : /* -------------------------------------------------------------------- */
     214                 : /*      This table was automatically generated by doing translations    */
     215                 : /*      between mif and tab for each datum, and extracting the          */
     216                 : /*      parameters from the tab file.  The EPSG codes and OGC names     */
     217                 : /*      were added afterwards and may be incomplete or inaccurate.       */
     218                 : /* -------------------------------------------------------------------- */
     219                 : 
     220                 : MapInfoDatumInfo asDatumInfoList[] =
     221                 : {
     222                 : 
     223                 : { 0,    104, "WGS_1984",                   28,0, 0, 0, 0, 0, 0, 0, 0},
     224                 : { 6269, 74,  "North_American_Datum_1983",  0, 0, 0, 0, 0, 0, 0, 0, 0},
     225                 : 
     226                 : { 0,    0,  "",                            29, 0,   0,    0,   0, 0, 0, 0, 0}, // Datum ignore
     227                 : 
     228                 : { 6201, 1,  "Adindan",                     6, -162, -12,  206, 0, 0, 0, 0, 0},
     229                 : { 6205, 2,  "Afgooye",                     3, -43,  -163, 45,  0, 0, 0, 0, 0},
     230                 : { 6204, 3,  "Ain_el_Abd_1970",             4, -150, -251, -2,  0, 0, 0, 0, 0},
     231                 : { 0,    4,  "Anna_1_Astro_1965",           2, -491, -22,  435, 0, 0, 0, 0, 0},
     232                 : { 6209, 5,  "Arc_1950",                    15,-143, -90,  -294,0, 0, 0, 0, 0},
     233                 : { 6210, 6,  "Arc_1960",                    6, -160, -8,   -300,0, 0, 0, 0, 0},
     234                 : { 0,    7,  "Ascension_Islands",           4, -207, 107,  52,  0, 0, 0, 0, 0},
     235                 : { 0,    8,  "Astro_Beacon_E",              4, 145,  75,   -272,0, 0, 0, 0, 0},
     236                 : { 0,    9,  "Astro_B4_Sorol_Atoll",        4, 114,  -116, -333,0, 0, 0, 0, 0},
     237                 : { 0,    10, "Astro_Dos_71_4",              4, -320, 550,  -494,0, 0, 0, 0, 0},
     238                 : { 0,    11, "Astronomic_Station_1952",     4, 124,  -234, -25, 0, 0, 0, 0, 0},
     239                 : { 6202, 12, "Australian_Geodetic_Datum_66",2, -133, -48,  148, 0, 0, 0, 0, 0},
     240                 : { 6203, 13, "Australian_Geodetic_Datum_84",2, -134, -48,  149, 0, 0, 0, 0, 0},
     241                 : { 0,    14, "Bellevue_Ign",                4, -127, -769, 472, 0, 0, 0, 0, 0},
     242                 : { 6216, 15, "Bermuda_1957",                7, -73,  213,  296, 0, 0, 0, 0, 0},
     243                 : { 6218, 16, "Bogota",                      4, 307,  304,  -318,0, 0, 0, 0, 0},
     244                 : { 6221, 17, "Campo_Inchauspe",             4, -148, 136,  90,  0, 0, 0, 0, 0},
     245                 : { 0,    18, "Canton_Astro_1966",           4, 298,  -304, -375,0, 0, 0, 0, 0},
     246                 : { 6222, 19, "Cape",                        6, -136, -108, -292,0, 0, 0, 0, 0},
     247                 : { 6717, 20, "Cape_Canaveral",              7, -2,   150,  181, 0, 0, 0, 0, 0},
     248                 : { 6223, 21, "Carthage",                    6, -263, 6,    431, 0, 0, 0, 0, 0},
     249                 : { 6672, 22, "Chatham_1971",                4, 175,  -38,  113, 0, 0, 0, 0, 0},
     250                 : { 6224, 23, "Chua",                        4, -134, 229,  -29, 0, 0, 0, 0, 0},
     251                 : { 6225, 24, "Corrego_Alegre",              4, -206, 172,  -6,  0, 0, 0, 0, 0},
     252                 : { 6211, 25, "Batavia",                     10,-377,681,   -50, 0, 0, 0, 0, 0},
     253                 : { 0,    26, "Dos_1968",                    4, 230,  -199, -752,0, 0, 0, 0, 0},
     254                 : { 6719, 27, "Easter_Island_1967",          4, 211,  147,  111, 0, 0, 0, 0, 0},
     255                 : { 6230, 28, "European_Datum_1950",         4, -87,  -98,  -121,0, 0, 0, 0, 0},
     256                 : { 6668, 29, "European_Datum_1979",         4, -86,  -98,  -119,0, 0, 0, 0, 0},
     257                 : { 6233, 30, "Gandajika_1970",              4, -133, -321, 50,  0, 0, 0, 0, 0},
     258                 : { 6272, 31, "New_Zealand_GD49",            4, 84,   -22,  209, 0, 0, 0, 0, 0},
     259                 : { 6272, 31, "New_Zealand_Geodetic_Datum_1949",4,84, -22,  209, 0, 0, 0, 0, 0},
     260                 : { 0,    32, "GRS_67",                      21,0,    0,    0,   0, 0, 0, 0, 0},
     261                 : { 0,    33, "GRS_80",                      0, 0,    0,    0,   0, 0, 0, 0, 0},
     262                 : { 6675, 34, "Guam_1963",                   7, -100, -248, 259, 0, 0, 0, 0, 0},
     263                 : { 0,    35, "Gux_1_Astro",                 4, 252,  -209, -751,0, 0, 0, 0, 0},
     264                 : { 6254, 36, "Hito_XVIII_1963",             4, 16,   196,  93,  0, 0, 0, 0, 0},
     265                 : { 6658, 37, "Hjorsey_1955",                4, -73,  46,   -86, 0, 0, 0, 0, 0},
     266                 : { 6738, 38, "Hong_Kong_1963",              4, -156, -271, -189,0, 0, 0, 0, 0},
     267                 : { 6236, 39, "Hu_Tzu_Shan",                 4, -634, -549, -201,0, 0, 0, 0, 0},
     268                 : { 0,    40, "Indian_Thailand_Vietnam",     11,214,  836,  303, 0, 0, 0, 0, 0},
     269                 : { 0,    41, "Indian_Bangladesh",           11,289,  734,  257, 0, 0, 0, 0, 0},
     270                 : { 0,    42, "Ireland_1965",                13,506,  -122, 611, 0, 0, 0, 0, 0},
     271                 : { 0,    43, "ISTS_073_Astro_1969",         4, 208,  -435, -229,0, 0, 0, 0, 0},
     272                 : { 6725, 44, "Johnston_Island_1961",        4, 191,  -77,  -204,0, 0, 0, 0, 0},
     273                 : { 6244, 45, "Kandawala",                   11,-97,  787,  86,  0, 0, 0, 0, 0},
     274                 : { 0,    46, "Kerguyelen_Island",           4, 145,  -187, 103, 0, 0, 0, 0, 0},
     275                 : { 6245, 47, "Kertau",                      17,-11,  851,  5,   0, 0, 0, 0, 0},
     276                 : { 0,    48, "L_C_5_Astro",                 7, 42,   124,  147, 0, 0, 0, 0, 0},
     277                 : { 6251, 49, "Liberia_1964",                6, -90,  40,   88,  0, 0, 0, 0, 0},
     278                 : { 0,    50, "Luzon_Phillippines",          7, -133, -77,  -51, 0, 0, 0, 0, 0},
     279                 : { 0,    51, "Luzon_Mindanao_Island",       7, -133, -79,  -72, 0, 0, 0, 0, 0},
     280                 : { 6256, 52, "Mahe_1971",                   6, 41,   -220, -134,0, 0, 0, 0, 0},
     281                 : { 0,    53, "Marco_Astro",                 4, -289, -124, 60,  0, 0, 0, 0, 0},
     282                 : { 6262, 54, "Massawa",                     10,639,  405,  60,  0, 0, 0, 0, 0},
     283                 : { 6261, 55, "Merchich",                    16,31,   146,  47,  0, 0, 0, 0, 0},
     284                 : { 0,    56, "Midway_Astro_1961",           4, 912,  -58,  1227,0, 0, 0, 0, 0},
     285                 : { 6263, 57, "Minna",                       6, -92,  -93,  122, 0, 0, 0, 0, 0},
     286                 : { 0,    58, "Nahrwan_Masirah_Island",      6, -247, -148, 369, 0, 0, 0, 0, 0},
     287                 : { 0,    59, "Nahrwan_Un_Arab_Emirates",    6, -249, -156, 381, 0, 0, 0, 0, 0},
     288                 : { 0,    60, "Nahrwan_Saudi_Arabia",        6, -231, -196, 482, 0, 0, 0, 0, 0},
     289                 : { 6271, 61, "Naparima_1972",               4, -2,   374,  172, 0, 0, 0, 0, 0},
     290                 : { 6267, 62, "NAD_1927",                    7, -8,   160,  176, 0, 0, 0, 0, 0},
     291                 : { 6267, 62, "North_American_Datum_1927",   7, -8,   160,  176, 0, 0, 0, 0, 0},
     292                 : { 0,    63, "NAD_27_Alaska",               7, -5,   135,  172, 0, 0, 0, 0, 0},
     293                 : { 0,    64, "NAD_27_Bahamas",              7, -4,   154,  178, 0, 0, 0, 0, 0},
     294                 : { 0,    65, "NAD_27_San_Salvador",         7, 1,    140,  165, 0, 0, 0, 0, 0},
     295                 : { 0,    66, "NAD_27_Canada",               7, -10,  158,  187, 0, 0, 0, 0, 0},
     296                 : { 0,    67, "NAD_27_Canal_Zone",           7, 0,    125,  201, 0, 0, 0, 0, 0},
     297                 : { 0,    68, "NAD_27_Caribbean",            7, -7,   152,  178, 0, 0, 0, 0, 0},
     298                 : { 0,    69, "NAD_27_Central_America",      7, 0,    125,  194, 0, 0, 0, 0, 0},
     299                 : { 0,    70, "NAD_27_Cuba",                 7, -9,   152,  178, 0, 0, 0, 0, 0},
     300                 : { 0,    71, "NAD_27_Greenland",            7, 11,   114,  195, 0, 0, 0, 0, 0},
     301                 : { 0,    72, "NAD_27_Mexico",               7, -12,  130,  190, 0, 0, 0, 0, 0},
     302                 : { 0,    73, "NAD_27_Michigan",             8, -8,   160,  176, 0, 0, 0, 0, 0},
     303                 : { 0,    75, "Observatorio_1966",           4, -425, -169, 81,  0, 0, 0, 0, 0},
     304                 : { 0,    76, "Old_Egyptian",                22,-130, 110, -13,  0, 0, 0, 0, 0},
     305                 : { 6135, 77, "Old_Hawaiian",                7, 61,   -285, -181,0, 0, 0, 0, 0},
     306                 : { 0,    78, "Oman",                        6, -346, -1,   224, 0, 0, 0, 0, 0},
     307                 : { 6277, 79, "OSGB_1936",                   9, 375,  -111, 431, 0, 0, 0, 0, 0},
     308                 : { 0,    80, "Pico_De_Las_Nieves",          4, -307, -92,  127, 0, 0, 0, 0, 0},
     309                 : { 6729, 81, "Pitcairn_Astro_1967",         4, 185,  165,  42,  0, 0, 0, 0, 0},
     310                 : { 6248, 82, "Provisional_South_American",  4, -288, 175,  -376,0, 0, 0, 0, 0},
     311                 : { 6139, 83, "Puerto_Rico",                 7, 11,   72,   -101,0, 0, 0, 0, 0},
     312                 : { 6614, 84, "Qatar_National",              4, -128, -283, 22,  0, 0, 0, 0, 0},
     313                 : { 6287, 85, "Qornoq",                      4, 164,  138, -189, 0, 0, 0, 0, 0},
     314                 : { 6627, 86, "Reunion",                     4, 94,   -948,-1262,0, 0, 0, 0, 0},
     315                 : { 6265, 87, "Monte_Mario",                 4, -225, -65, 9,    0, 0, 0, 0, 0},
     316                 : { 0,    88, "Santo_Dos",                   4, 170,  42,  84,   0, 0, 0, 0, 0},
     317                 : { 0,    89, "Sao_Braz",                    4, -203, 141, 53,   0, 0, 0, 0, 0},
     318                 : { 6292, 90, "Sapper_Hill_1943",            4, -355, 16,  74,   0, 0, 0, 0, 0},
     319                 : { 6293, 91, "Schwarzeck",                  14,616,  97,  -251, 0, 0, 0, 0, 0},
     320                 : { 6618, 92, "South_American_Datum_1969",   24,-57,  1,   -41,  0, 0, 0, 0, 0},
     321                 : { 0,    93, "South_Asia",                  19,7,    -10, -26,  0, 0, 0, 0, 0},
     322                 : { 0,    94, "Southeast_Base",              4, -499, -249,314,  0, 0, 0, 0, 0},
     323                 : { 0,    95, "Southwest_Base",              4, -104, 167, -38,  0, 0, 0, 0, 0},
     324                 : { 6298, 96, "Timbalai_1948",               11,-689, 691, -46,  0, 0, 0, 0, 0},
     325                 : { 6301, 97, "Tokyo",                       10,-128, 481, 664,  0, 0, 0, 0, 0},
     326                 : { 0,    98, "Tristan_Astro_1968",          4, -632, 438, -609, 0, 0, 0, 0, 0},
     327                 : { 6731, 99, "Viti_Levu_1916",              6, 51,   391, -36,  0, 0, 0, 0, 0},
     328                 : { 0,    100, "Wake_Entiwetok_1960",        23,101,  52,  -39,  0, 0, 0, 0, 0},
     329                 : { 0,    101, "WGS_60",                     26,0,    0,   0,    0, 0, 0, 0, 0},
     330                 : { 6760, 102, "WGS_66",                     27,0,    0,   0,    0, 0, 0, 0, 0},
     331                 : { 6322, 103, "WGS_1972",                   1, 0,    8,   10,   0, 0, 0, 0, 0},
     332                 : { 6326, 104, "WGS_1984",                   28,0,    0,   0,    0, 0, 0, 0, 0},
     333                 : { 6309, 105, "Yacare",                     4, -155, 171, 37,   0, 0, 0, 0, 0},
     334                 : { 6311, 106, "Zanderij",                   4, -265, 120, -358, 0, 0, 0, 0, 0},
     335                 : { 0,    107, "NTF",                        30,-168, -60, 320,  0, 0, 0, 0, 0},
     336                 : { 6231, 108, "European_Datum_1987",        4, -83,  -96, -113, 0, 0, 0, 0, 0},
     337                 : { 0,    109, "Netherlands_Bessel",         10,593,  26,  478,  0, 0, 0, 0, 0},
     338                 : { 0,    110, "Belgium_Hayford",            4, 81,   120, 129,  0, 0, 0, 0, 0},
     339                 : { 0,    111, "NWGL_10",                    1, -1,   15,  1,    0, 0, 0, 0, 0},
     340                 : { 6124, 112, "Rikets_koordinatsystem_1990",10,498,  -36, 568,  0, 0, 0, 0, 0},
     341                 : { 0,    113, "Lisboa_DLX",                 4, -303, -62, 105,  0, 0, 0, 0, 0},
     342                 : { 0,    114, "Melrica_1973_D73",           4, -223, 110, 37,   0, 0, 0, 0, 0},
     343                 : { 0,    115, "Euref_98",                   0, 0,    0,   0,    0, 0, 0, 0, 0},
     344                 : { 0,    116, "GDA94",                      0, 0,    0,   0,    0, 0, 0, 0, 0},
     345                 : { 6167, 117, "NZGD2000",                   0, 0,    0,   0,    0, 0, 0, 0, 0},
     346                 : { 6167, 117, "New_Zealand_Geodetic_Datum_2000",0,0, 0,   0,    0, 0, 0, 0, 0},
     347                 : { 6169, 118, "America_Samoa",              7, -115, 118, 426,  0, 0, 0, 0, 0},
     348                 : { 0,    119, "Antigua_Astro_1965",         6, -270, 13,  62,   0, 0, 0, 0, 0},
     349                 : { 6713, 120, "Ayabelle_Lighthouse",        6, -79, -129, 145,  0, 0, 0, 0, 0},
     350                 : { 6219, 121, "Bukit_Rimpah",               10,-384, 664, -48,  0, 0, 0, 0, 0},
     351                 : { 0,    122, "Estonia_1937",               10,374, 150,  588,  0, 0, 0, 0, 0},
     352                 : { 6155, 123, "Dabola",                     6, -83, 37,   124,  0, 0, 0, 0, 0},
     353                 : { 6736, 124, "Deception_Island",           6, 260, 12,   -147, 0, 0, 0, 0, 0},
     354                 : { 0,    125, "Fort_Thomas_1955",           6, -7, 215,   225,  0, 0, 0, 0, 0},
     355                 : { 0,    126, "Graciosa_base_1948",         4, -104, 167, -38,  0, 0, 0, 0, 0},
     356                 : { 6255, 127, "Herat_North",                4, -333, -222,114,  0, 0, 0, 0, 0},
     357                 : { 0,    128, "Hermanns_Kogel",             10,682, -203, 480,  0, 0, 0, 0, 0},
     358                 : { 6240, 129, "Indian",                     50,283, 682,  231,  0, 0, 0, 0, 0},
     359                 : { 6239, 130, "Indian_1954",                11,217, 823,  299,  0, 0, 0, 0, 0},
     360                 : { 6131, 131, "Indian_1960",                11,198, 881,  317,  0, 0, 0, 0, 0},
     361                 : { 6240, 132, "Indian_1975",                11,210, 814,  289,  0, 0, 0, 0, 0},
     362                 : { 6238, 133, "Indonesian_Datum_1974",      4, -24, -15,  5,    0, 0, 0, 0, 0},
     363                 : { 0,    134, "ISTS061_Astro_1968",         4, -794, 119, -298, 0, 0, 0, 0, 0},
     364                 : { 0,    135, "Kusaie_Astro_1951",          4, 647, 1777, -1124,0, 0, 0, 0, 0},
     365                 : { 6250, 136, "Leigon",                     6, -130, 29,  364,  0, 0, 0, 0, 0},
     366                 : { 0,    137, "Montserrat_Astro_1958",      6, 174, 359,  365,  0, 0, 0, 0, 0},
     367                 : { 6266, 138, "Mporaloko",                  6, -74, -130, 42,   0, 0, 0, 0, 0},
     368                 : { 0,    139, "North_Sahara_1959",          6, -186, -93, 310,  0, 0, 0, 0, 0},
     369                 : { 0,    140, "Observatorio_Met_1939",      4, -425, -169,81,   0, 0, 0, 0, 0},
     370                 : { 6620, 141, "Point_58",                   6, -106, -129,165,  0, 0, 0, 0, 0},
     371                 : { 6282, 142, "Pointe_Noire",               6, -148, 51,  -291, 0, 0, 0, 0, 0},
     372                 : { 6615, 143, "Porto_Santo_1936",           4, -499, -249,314,  0, 0, 0, 0, 0},
     373                 : { 6616, 144, "Selvagem_Grande_1938",       4, -289, -124,60,   0, 0, 0, 0, 0},
     374                 : { 0,    145, "Sierra_Leone_1960",          6, -88,  4,   101,  0, 0, 0, 0, 0},
     375                 : { 6156, 146, "S_JTSK_Ferro",               10, 589, 76,  480,  0, 0, 0, 0, 0},
     376                 : { 6297, 147, "Tananarive_1925",            4, -189, -242,-91,  0, 0, 0, 0, 0},
     377                 : { 0,    148, "Voirol_1874",                6, -73,  -247,227,  0, 0, 0, 0, 0},
     378                 : { 0,    149, "Virol_1960",                 6, -123, -206,219,  0, 0, 0, 0, 0},
     379                 : { 6148, 150, "Hartebeesthoek94",           0, 0,    0,   0,    0, 0, 0, 0, 0},
     380                 : { 6122, 151, "ATS77",                      51, 0, 0, 0, 0, 0, 0, 0, 0},
     381                 : { 6612, 152, "JGD2000",                    0, 0, 0, 0, 0, 0, 0, 0, 0},
     382                 : { 0,    157, "WGS_1984",                   54, 0, 0, 0, 0, 0, 0, 0, 0}, // Google merc
     383                 : { 0,    1000,"DHDN_Potsdam_Rauenberg",     10,582,  105, 414, -1.04, -0.35, 3.08, 8.3, 0},
     384                 : { 6284, 1001,"Pulkovo_1942",               3, 24,   -123, -94, -0.02, 0.25, 0.13, 1.1, 0},
     385                 : { 6275, 1002,"NTF_Paris_Meridian",         30,-168, -60, 320, 0, 0, 0, 0, 2.337229166667},
     386                 : { 0,    1003,"Switzerland_CH_1903",        10,660.077,13.551, 369.344, 0.804816, 0.577692, 0.952236, 5.66,0},
     387                 : { 6237, 1004,"Hungarian_Datum_1972",       21,-56,  75.77, 15.31, -0.37, -0.2, -0.21, -1.01, 0},
     388                 : { 0,    1005,"Cape_7_Parameter",           28,-134.73,-110.92, -292.66, 0, 0, 0, 1, 0},
     389                 : { 6203, 1006,"AGD84_7_Param_Aust",         2, -117.763,-51.51, 139.061, -0.292, -0.443, -0.277, -0.191, 0},
     390                 : { 0,    1007,"AGD66_7_Param_ACT",          2, -129.193,-41.212, 130.73, -0.246, -0.374, -0.329, -2.955, 0},
     391                 : { 0,    1008,"AGD66_7_Param_TAS",          2, -120.271,-64.543, 161.632, -0.2175, 0.0672, 0.1291, 2.4985, 0},
     392                 : { 0,    1009,"AGD66_7_Param_VIC_NSW",      2, -119.353,-48.301, 139.484, -0.415, -0.26, -0.437, -0.613, 0},
     393                 : { 6272, 1010,"NZGD_7_Param_49",            4, 59.47, -5.04, 187.44, -0.47, 0.1, -1.024, -4.5993, 0},
     394                 : { 0,    1011,"Rikets_Tri_7_Param_1990",    10,419.3836, 99.3335, 591.3451, -0.850389, -1.817277, 7.862238, -0.99496, 0},
     395                 : { 0,    1012,"Russia_PZ90",                52, -1.08,-0.27,-0.9,0, 0, -0.16,-0.12, 0},
     396                 : { 0,    1013,"Russia_SK42",                52, 23.92,-141.27,-80.9, 0, -0.35,-0.82, -0.12, 0},
     397                 : { 0,    1014,"Russia_SK95",                52, 24.82,-131.21,-82.66,0,0,-0.16,-0.12, 0},
     398                 : { 6301, 1015,"Tokyo",                      10, -146.414, 507.337, 680.507,0,0,0,0,0},
     399                 : { 0,    1016,"Finnish_KKJ",                4, -96.062, -82.428, -121.754, -4.801, -0.345, 1.376, 1.496, 0},
     400                 : { 6610, 1017,"Xian 1980",                  53, 24, -123, -94, -0.02, -0.25, 0.13, 1.1, 0},
     401                 : { 0,    1018,"Lithuanian Pulkovo 1942",    4, -40.59527, -18.54979, -69.33956, -2.508, -1.8319, 2.6114, -4.2991, 0},
     402                 : { 0,    1019,"Belgian 1972 7 Parameter",   4, -99.059, 53.322, -112.486, -0.419, 0.83, -1.885, 0.999999, 0},
     403                 : { 6818, 1020,"S-JTSK with Ferro prime meridian", 10, 589, 76, 480, 0, 0, 0, 0, -17.666666666667}, 
     404                 : 
     405                 : { -1,   -1, NULL,                          0, 0, 0, 0, 0, 0, 0, 0, 0}
     406                 : };
     407                 : 
     408                 : /* -------------------------------------------------------------------- */
     409                 : /*      This table was hand entered from Appendix I of the mapinfo 6    */
     410                 : /*      manuals.                                                        */
     411                 : /* -------------------------------------------------------------------- */
     412                 : 
     413                 : MapInfoSpheroidInfo asSpheroidInfoList[] =
     414                 : {
     415                 : { 9,"Airy 1930",                                6377563.396,    299.3249646},
     416                 : {13,"Airy 1930 (modified for Ireland 1965",     6377340.189,    299.3249646},
     417                 : {51,"ATS77 (Average Terrestrial System 1977)",  6378135,        298.257},
     418                 : { 2,"Australian",                               6378160.0,      298.25},
     419                 : {10,"Bessel 1841",                              6377397.155,    299.1528128},
     420                 : {35,"Bessel 1841 (modified for NGO 1948)",      6377492.0176,   299.15281},
     421                 : {14,"Bessel 1841 (modified for Schwarzeck)",    6377483.865,    299.1528128},
     422                 : {36,"Clarke 1858",                              6378293.639,    294.26068},
     423                 : { 7,"Clarke 1866",                              6378206.4,      294.9786982},
     424                 : { 8,"Clarke 1866 (modified for Michigan)",      6378450.047484481,294.9786982},
     425                 : { 6,"Clarke 1880",                              6378249.145,    293.465},
     426                 : {15,"Clarke 1880 (modified for Arc 1950)",      6378249.145326, 293.4663076},
     427                 : {30,"Clarke 1880 (modified for IGN)",           6378249.2,      293.4660213},
     428                 : {37,"Clarke 1880 (modified for Jamaica)",       6378249.136,    293.46631},
     429                 : {16,"Clarke 1880 (modified for Merchich)",      6378249.2,      293.46598},
     430                 : {38,"Clarke 1880 (modified for Palestine)",     6378300.79,     293.46623},
     431                 : {39,"Everest (Brunei and East Malaysia)",       6377298.556,    300.8017},
     432                 : {11,"Everest (India 1830)",                     6377276.345,    300.8017},
     433                 : {40,"Everest (India 1956)",                     6377301.243,    300.80174},
     434                 : {50,"Everest (Pakistan)",                       6377309.613,    300.8017},
     435                 : {17,"Everest (W. Malaysia and Singapore 1948)", 6377304.063,    300.8017},
     436                 : {48,"Everest (West Malaysia 1969)",             6377304.063,    300.8017},
     437                 : {18,"Fischer 1960",                             6378166.0,      298.3},
     438                 : {19,"Fischer 1960 (modified for South Asia)",   6378155.0,      298.3},
     439                 : {20,"Fischer 1968",                             6378150.0,      298.3},
     440                 : {21,"GRS 67",                                   6378160.0,      298.247167427},
     441                 : { 0,"GRS 80",                                   6378137.0,      298.257222101},
     442                 : { 5,"Hayford",                                  6378388.0,      297.0},
     443                 : {22,"Helmert 1906",                             6378200.0,      298.3},
     444                 : {23,"Hough",                                    6378270.0,      297.0},
     445                 : {31,"IAG 75",                                   6378140.0,      298.257222},
     446                 : {41,"Indonesian",                               6378160.0,      298.247},
     447                 : { 4,"International 1924",                       6378388.0,      297.0},
     448                 : {49,"Irish (WOFO)",                             6377542.178,    299.325},
     449                 : { 3,"Krassovsky",                               6378245.0,      298.3},
     450                 : {32,"MERIT 83",                                 6378137.0,      298.257},
     451                 : {33,"New International 1967",                   6378157.5,      298.25},
     452                 : {42,"NWL 9D",                                   6378145.0,      298.25},
     453                 : {43,"NWL 10D",                                  6378135.0,      298.26},
     454                 : {44,"OSU86F",                                   6378136.2,      298.25722},
     455                 : {45,"OSU91A",                                   6378136.3,      298.25722},
     456                 : {46,"Plessis 1817",                             6376523.0,      308.64},
     457                 : {52,"PZ90",                                     6378136.0,      298.257839303},
     458                 : {24,"South American",                           6378160.0,      298.25},
     459                 : {12,"Sphere",                                   6370997.0,      0.0},
     460                 : {47,"Struve 1860",                              6378297.0,      294.73},
     461                 : {34,"Walbeck",                                  6376896.0,      302.78},
     462                 : {25,"War Office",                               6378300.583,    296.0},
     463                 : {26,"WGS 60",                                   6378165.0,      298.3},
     464                 : {27,"WGS 66",                                   6378145.0,      298.25},
     465                 : { 1,"WGS 72",                                   6378135.0,      298.26},
     466                 : {28,"WGS 84",                                   6378137.0,      298.257223563},
     467                 : {29,"WGS 84 (MAPINFO Datum 0)",                 6378137.01,     298.257223563},
     468                 : {54,"WGS 84 (MAPINFO Datum 157)",               6378137.01,     298.257223563},
     469                 : {-1,NULL,                                       0.0,            0.0}
     470                 : };
     471                 :  
     472                 : /**********************************************************************
     473                 :  *                   TABFile::GetSpatialRef()
     474                 :  *
     475                 :  * Returns a reference to an OGRSpatialReference for this dataset.
     476                 :  * If the projection parameters have not been parsed yet, then we will
     477                 :  * parse them before returning.
     478                 :  *
     479                 :  * The returned object is owned and maintained by this TABFile and
     480                 :  * should not be modified or freed by the caller.
     481                 :  *
     482                 :  * Returns NULL if the SpatialRef cannot be accessed.
     483                 :  **********************************************************************/
     484               2 : OGRSpatialReference *TABFile::GetSpatialRef()
     485                 : {
     486               2 :     if (m_eAccessMode != TABRead)
     487                 :     {
     488                 :         CPLError(CE_Failure, CPLE_NotSupported,
     489               0 :                  "GetSpatialRef() can be used only with Read access.");
     490               0 :         return NULL;
     491                 :     }
     492                 :  
     493               2 :     if (m_poMAPFile == NULL )
     494                 :     {
     495                 :         CPLError(CE_Failure, CPLE_AssertionFailed,
     496               0 :                  "GetSpatialRef() failed: file has not been opened yet.");
     497               0 :         return NULL;
     498                 :     }
     499                 : 
     500                 :     /*-----------------------------------------------------------------
     501                 :      * If projection params have already been processed, just use them.
     502                 :      *----------------------------------------------------------------*/
     503               2 :     if (m_poSpatialRef != NULL)
     504               0 :         return m_poSpatialRef;
     505                 :     
     506                 : 
     507                 :     /*-----------------------------------------------------------------
     508                 :      * Fetch the parameters from the header.
     509                 :      *----------------------------------------------------------------*/
     510                 :     TABMAPHeaderBlock *poHeader;
     511                 :     TABProjInfo     sTABProj;
     512                 : 
     513               2 :     if ((poHeader = m_poMAPFile->GetHeaderBlock()) == NULL ||
     514                 :         poHeader->GetProjInfo( &sTABProj ) != 0)
     515                 :     {
     516                 :         CPLError(CE_Failure, CPLE_FileIO,
     517               0 :                  "GetSpatialRef() failed reading projection parameters.");
     518               0 :         return NULL;
     519                 :     }
     520                 : 
     521                 :     /*-----------------------------------------------------------------
     522                 :      * Get the units name, and translation factor.
     523                 :      *----------------------------------------------------------------*/
     524                 :     const char *pszUnitsName; 
     525                 :     const char *pszUnitsConv;
     526               2 :     double      dfConv = 1.0;
     527                 : 
     528               2 :     switch( sTABProj.nUnitsId )
     529                 :     {
     530                 :       case 0:
     531               0 :         pszUnitsName = "Mile";
     532               0 :         pszUnitsConv = "1609.344";
     533               0 :         break;
     534                 : 
     535                 :       case 1:
     536               0 :         pszUnitsName = "Kilometer";
     537               0 :         pszUnitsConv = "1000.0";
     538               0 :         break;
     539                 :             
     540                 :       case 2:
     541               0 :         pszUnitsName = "IINCH";
     542               0 :         pszUnitsConv = "0.0254";
     543               0 :         break;
     544                 :             
     545                 :       case 3:
     546               0 :         pszUnitsName = SRS_UL_FOOT;
     547               0 :         pszUnitsConv = SRS_UL_FOOT_CONV;
     548               0 :         break;
     549                 :             
     550                 :       case 4:
     551               0 :         pszUnitsName = "IYARD";
     552               0 :         pszUnitsConv = "0.9144";
     553               0 :         break;
     554                 :             
     555                 :       case 5:
     556               0 :         pszUnitsName = "Millimeter";
     557               0 :         pszUnitsConv = "0.001";
     558               0 :         break;
     559                 :             
     560                 :       case 6:
     561               0 :         pszUnitsName = "Centimeter";
     562               0 :         pszUnitsConv = "0.01";
     563               0 :         break;
     564                 :             
     565                 :       case 7:
     566               2 :         pszUnitsName = SRS_UL_METER;
     567               2 :         pszUnitsConv = "1.0";
     568               2 :         break;
     569                 :             
     570                 :       case 8:
     571               0 :         pszUnitsName = SRS_UL_US_FOOT;
     572               0 :         pszUnitsConv = SRS_UL_US_FOOT_CONV;
     573               0 :         break;
     574                 :             
     575                 :       case 9:
     576               0 :         pszUnitsName = SRS_UL_NAUTICAL_MILE;
     577               0 :         pszUnitsConv = SRS_UL_NAUTICAL_MILE_CONV;
     578               0 :         break;
     579                 :             
     580                 :       case 30:
     581               0 :         pszUnitsName = SRS_UL_LINK;
     582               0 :         pszUnitsConv = SRS_UL_LINK_CONV;
     583               0 :         break;
     584                 :             
     585                 :       case 31:
     586               0 :         pszUnitsName = SRS_UL_CHAIN;
     587               0 :         pszUnitsConv = SRS_UL_CHAIN_CONV;
     588               0 :         break;
     589                 :             
     590                 :       case 32:
     591               0 :         pszUnitsName = SRS_UL_ROD;
     592               0 :         pszUnitsConv = SRS_UL_ROD_CONV;
     593               0 :         break;
     594                 :             
     595                 :       default:
     596               0 :         pszUnitsName = SRS_UL_METER;
     597               0 :         pszUnitsConv = "1.0";
     598                 :         break;
     599                 :     }
     600                 : 
     601               2 :     dfConv = CPLAtof(pszUnitsConv);
     602                 : 
     603                 :     /*-----------------------------------------------------------------
     604                 :      * Transform them into an OGRSpatialReference.
     605                 :      *----------------------------------------------------------------*/
     606               2 :     m_poSpatialRef = new OGRSpatialReference;
     607                 : 
     608                 :     /*-----------------------------------------------------------------
     609                 :      * Handle the PROJCS style projections, but add the datum later.
     610                 :      *----------------------------------------------------------------*/
     611               2 :     switch( sTABProj.nProjId )
     612                 :     {
     613                 :         /*--------------------------------------------------------------
     614                 :          * NonEarth ... we return with an empty SpatialRef.  Eventually
     615                 :          * we might want to include the units, but not for now.
     616                 :          *-------------------------------------------------------------*/
     617                 :       case 0:
     618               0 :         m_poSpatialRef->SetLocalCS( "Nonearth" );
     619               0 :         break;
     620                 : 
     621                 :         /*--------------------------------------------------------------
     622                 :          * lat/long .. just add the GEOGCS later.
     623                 :          *-------------------------------------------------------------*/
     624                 :       case 1:
     625               0 :         break;
     626                 : 
     627                 :         /*--------------------------------------------------------------
     628                 :          * Cylindrical Equal Area
     629                 :          *-------------------------------------------------------------*/
     630                 :       case 2:
     631                 :         m_poSpatialRef->SetCEA( sTABProj.adProjParams[1],
     632                 :                                 sTABProj.adProjParams[0],
     633                 :                                 sTABProj.adProjParams[2],
     634               0 :                                 sTABProj.adProjParams[3] );
     635               0 :         break;
     636                 : 
     637                 :         /*--------------------------------------------------------------
     638                 :          * Lambert Conic Conformal
     639                 :          *-------------------------------------------------------------*/
     640                 :       case 3:
     641                 :         m_poSpatialRef->SetLCC( sTABProj.adProjParams[2],
     642                 :                                 sTABProj.adProjParams[3],
     643                 :                                 sTABProj.adProjParams[1],
     644                 :                                 sTABProj.adProjParams[0],
     645                 :                                 sTABProj.adProjParams[4],
     646               0 :                                 sTABProj.adProjParams[5] );
     647               0 :         break;
     648                 : 
     649                 :         /*--------------------------------------------------------------
     650                 :          * Lambert Azimuthal Equal Area
     651                 :          *-------------------------------------------------------------*/
     652                 :       case 4:
     653                 :       case 29:
     654                 :         m_poSpatialRef->SetLAEA( sTABProj.adProjParams[1],
     655                 :                                  sTABProj.adProjParams[0],
     656               0 :                                  0.0, 0.0 );
     657               0 :         break;
     658                 : 
     659                 :         /*--------------------------------------------------------------
     660                 :          * Azimuthal Equidistant (Polar aspect only)
     661                 :          *-------------------------------------------------------------*/
     662                 :       case 5:
     663                 :       case 28:
     664                 :         m_poSpatialRef->SetAE( sTABProj.adProjParams[1],
     665                 :                                sTABProj.adProjParams[0],
     666               0 :                                0.0, 0.0 );
     667               0 :         break;
     668                 : 
     669                 :         /*--------------------------------------------------------------
     670                 :          * Equidistant Conic
     671                 :          *-------------------------------------------------------------*/
     672                 :       case 6:
     673                 :         m_poSpatialRef->SetEC( sTABProj.adProjParams[2],
     674                 :                                sTABProj.adProjParams[3],
     675                 :                                sTABProj.adProjParams[1],
     676                 :                                sTABProj.adProjParams[0],
     677                 :                                sTABProj.adProjParams[4],
     678               0 :                                sTABProj.adProjParams[5] );
     679               0 :         break;
     680                 : 
     681                 :         /*--------------------------------------------------------------
     682                 :          * Hotine Oblique Mercator
     683                 :          *-------------------------------------------------------------*/
     684                 :       case 7:
     685                 :         m_poSpatialRef->SetHOM( sTABProj.adProjParams[1],
     686                 :                                 sTABProj.adProjParams[0], 
     687                 :                                 sTABProj.adProjParams[2],
     688                 :                                 90.0, 
     689                 :                                 sTABProj.adProjParams[3],
     690                 :                                 sTABProj.adProjParams[4],
     691               0 :                                 sTABProj.adProjParams[5] );
     692               0 :         break;
     693                 : 
     694                 :         /*--------------------------------------------------------------
     695                 :          * Transverse Mercator
     696                 :          *-------------------------------------------------------------*/
     697                 :       case 8:
     698                 :         m_poSpatialRef->SetTM( sTABProj.adProjParams[1],
     699                 :                                sTABProj.adProjParams[0],
     700                 :                                sTABProj.adProjParams[2],
     701                 :                                sTABProj.adProjParams[3],
     702               2 :                                sTABProj.adProjParams[4] );
     703               2 :         break;
     704                 : 
     705                 :         /*----------------------------------------------------------------
     706                 :          * Transverse Mercator,(modified for Danish System 34 Jylland-Fyn)
     707                 :          *---------------------------------------------------------------*/
     708                 :       case 21:
     709                 :          m_poSpatialRef->SetTMVariant( SRS_PT_TRANSVERSE_MERCATOR_MI_21,
     710                 :                                        sTABProj.adProjParams[1],
     711                 :                                        sTABProj.adProjParams[0],
     712                 :                                        sTABProj.adProjParams[2],
     713                 :                                        sTABProj.adProjParams[3],
     714               0 :                                        sTABProj.adProjParams[4] );
     715               0 :          break;
     716                 : 
     717                 :         /*--------------------------------------------------------------
     718                 :          * Transverse Mercator,(modified for Danish System 34 Sjaelland)
     719                 :          *-------------------------------------------------------------*/
     720                 :       case 22:
     721                 :          m_poSpatialRef->SetTMVariant( SRS_PT_TRANSVERSE_MERCATOR_MI_22,
     722                 :                                        sTABProj.adProjParams[1],
     723                 :                                        sTABProj.adProjParams[0],
     724                 :                                        sTABProj.adProjParams[2],
     725                 :                                        sTABProj.adProjParams[3],
     726               0 :                                        sTABProj.adProjParams[4] );
     727               0 :          break;
     728                 : 
     729                 :         /*----------------------------------------------------------------
     730                 :          * Transverse Mercator,(modified for Danish System 34/45 Bornholm)
     731                 :          *---------------------------------------------------------------*/
     732                 :       case 23:
     733                 :          m_poSpatialRef->SetTMVariant( SRS_PT_TRANSVERSE_MERCATOR_MI_23,
     734                 :                                        sTABProj.adProjParams[1],
     735                 :                                        sTABProj.adProjParams[0],
     736                 :                                        sTABProj.adProjParams[2],
     737                 :                                        sTABProj.adProjParams[3],
     738               0 :                                        sTABProj.adProjParams[4] );
     739               0 :          break;
     740                 : 
     741                 :         /*--------------------------------------------------------------
     742                 :          * Transverse Mercator,(modified for Finnish KKJ)
     743                 :          *-------------------------------------------------------------*/
     744                 :       case 24:
     745                 :          m_poSpatialRef->SetTMVariant( SRS_PT_TRANSVERSE_MERCATOR_MI_24,
     746                 :                                        sTABProj.adProjParams[1],
     747                 :                                        sTABProj.adProjParams[0],
     748                 :                                        sTABProj.adProjParams[2],
     749                 :                                        sTABProj.adProjParams[3],
     750               0 :                                        sTABProj.adProjParams[4] );
     751               0 :          break;
     752                 : 
     753                 :         /*--------------------------------------------------------------
     754                 :          * Albers Conic Equal Area
     755                 :          *-------------------------------------------------------------*/
     756                 :       case 9:
     757                 :         m_poSpatialRef->SetACEA( sTABProj.adProjParams[2],
     758                 :                                  sTABProj.adProjParams[3],
     759                 :                                  sTABProj.adProjParams[1],
     760                 :                                  sTABProj.adProjParams[0],
     761                 :                                  sTABProj.adProjParams[4],
     762               0 :                                  sTABProj.adProjParams[5] );
     763               0 :         break;
     764                 : 
     765                 :         /*--------------------------------------------------------------
     766                 :          * Mercator
     767                 :          *-------------------------------------------------------------*/
     768                 :       case 10:
     769                 :         m_poSpatialRef->SetMercator( 0.0, sTABProj.adProjParams[0],
     770               0 :                                      1.0, 0.0, 0.0 );
     771               0 :         break;
     772                 : 
     773                 :         /*--------------------------------------------------------------
     774                 :          * Miller Cylindrical
     775                 :          *-------------------------------------------------------------*/
     776                 :       case 11:
     777                 :         m_poSpatialRef->SetMC( 0.0, sTABProj.adProjParams[0],
     778               0 :                                0.0, 0.0 );
     779               0 :         break;
     780                 : 
     781                 :         /*--------------------------------------------------------------
     782                 :          * Robinson
     783                 :          *-------------------------------------------------------------*/
     784                 :       case 12:
     785                 :         m_poSpatialRef->SetRobinson( sTABProj.adProjParams[0],
     786               0 :                                      0.0, 0.0 );
     787               0 :         break;
     788                 : 
     789                 :         /*--------------------------------------------------------------
     790                 :          * Mollweide
     791                 :          *-------------------------------------------------------------*/
     792                 :       case 13:
     793                 :         m_poSpatialRef->SetMollweide( sTABProj.adProjParams[0],
     794               0 :                                       0.0, 0.0 );
     795               0 :         break;
     796                 : 
     797                 :         /*--------------------------------------------------------------
     798                 :          * Eckert IV
     799                 :          *-------------------------------------------------------------*/
     800                 :       case 14:
     801               0 :         m_poSpatialRef->SetEckertIV( sTABProj.adProjParams[0], 0.0, 0.0 );
     802               0 :         break;
     803                 : 
     804                 :         /*--------------------------------------------------------------
     805                 :          * Eckert VI
     806                 :          *-------------------------------------------------------------*/
     807                 :       case 15:
     808               0 :         m_poSpatialRef->SetEckertVI( sTABProj.adProjParams[0], 0.0, 0.0 );
     809               0 :         break;
     810                 : 
     811                 :         /*--------------------------------------------------------------
     812                 :          * Sinusoidal
     813                 :          *-------------------------------------------------------------*/
     814                 :       case 16:
     815                 :         m_poSpatialRef->SetSinusoidal( sTABProj.adProjParams[0],
     816               0 :                                        0.0, 0.0 );
     817               0 :         break;
     818                 : 
     819                 :         /*--------------------------------------------------------------
     820                 :          * Gall Stereographic
     821                 :          *-------------------------------------------------------------*/
     822                 :       case 17:
     823               0 :         m_poSpatialRef->SetGS( sTABProj.adProjParams[0], 0.0, 0.0 );
     824               0 :         break;
     825                 :         
     826                 :         /*--------------------------------------------------------------
     827                 :          * New Zealand Map Grid
     828                 :          *-------------------------------------------------------------*/
     829                 :       case 18:
     830                 :         m_poSpatialRef->SetNZMG( sTABProj.adProjParams[1],
     831                 :                                  sTABProj.adProjParams[0],
     832                 :                                  sTABProj.adProjParams[2],
     833               0 :                                  sTABProj.adProjParams[3] );
     834               0 :         break;
     835                 : 
     836                 :         /*--------------------------------------------------------------
     837                 :          * Lambert Conic Conformal (Belgium)
     838                 :          *-------------------------------------------------------------*/
     839                 :       case 19:
     840                 :         m_poSpatialRef->SetLCCB( sTABProj.adProjParams[2],
     841                 :                                  sTABProj.adProjParams[3],
     842                 :                                  sTABProj.adProjParams[1],
     843                 :                                  sTABProj.adProjParams[0],
     844                 :                                  sTABProj.adProjParams[4],
     845               0 :                                  sTABProj.adProjParams[5] );
     846               0 :         break;
     847                 : 
     848                 :         /*--------------------------------------------------------------
     849                 :          * Stereographic
     850                 :          *-------------------------------------------------------------*/
     851                 :       case 20:
     852                 :       case 31: /* this is called Double Stereographic, whats the diff? */
     853                 :         m_poSpatialRef->SetStereographic( sTABProj.adProjParams[1],
     854                 :                                           sTABProj.adProjParams[0],
     855                 :                                           sTABProj.adProjParams[2],
     856                 :                                           sTABProj.adProjParams[3],
     857               0 :                                           sTABProj.adProjParams[4] );
     858               0 :         break;
     859                 : 
     860                 :         /*--------------------------------------------------------------
     861                 :          * Swiss Oblique Mercator / Cylindrical
     862                 :          *-------------------------------------------------------------*/
     863                 :       case 25:
     864                 :         m_poSpatialRef->SetSOC( sTABProj.adProjParams[1],
     865                 :                                 sTABProj.adProjParams[0],
     866                 :                                 sTABProj.adProjParams[2],
     867               0 :                                 sTABProj.adProjParams[3] );
     868               0 :         break;
     869                 : 
     870                 :         /*--------------------------------------------------------------
     871                 :          * Regional Mercator (regular mercator with a latitude).
     872                 :          *-------------------------------------------------------------*/
     873                 :       case 26:
     874                 :         m_poSpatialRef->SetMercator( sTABProj.adProjParams[1],
     875                 :                                      sTABProj.adProjParams[0],
     876               0 :                                      1.0, 0.0, 0.0 );
     877               0 :         break;
     878                 : 
     879                 :         /*--------------------------------------------------------------
     880                 :          * Polyconic
     881                 :          *-------------------------------------------------------------*/
     882                 :       case 27:
     883                 :         m_poSpatialRef->SetPolyconic( sTABProj.adProjParams[1],
     884                 :                                       sTABProj.adProjParams[0],
     885                 :                                       sTABProj.adProjParams[2],
     886               0 :                                       sTABProj.adProjParams[3] );
     887               0 :         break;
     888                 : 
     889                 :         /*--------------------------------------------------------------
     890                 :          * Cassini/Soldner
     891                 :          *-------------------------------------------------------------*/
     892                 :       case 30:
     893                 :         m_poSpatialRef->SetCS( sTABProj.adProjParams[1],
     894                 :                                sTABProj.adProjParams[0],
     895                 :                                sTABProj.adProjParams[2],
     896               0 :                                sTABProj.adProjParams[3] );
     897               0 :         break;
     898                 : 
     899                 :      /*--------------------------------------------------------------
     900                 :       * Krovak
     901                 :       *-------------------------------------------------------------*/
     902                 :       case 32:
     903                 :         m_poSpatialRef->SetKrovak( sTABProj.adProjParams[1],   // dfCenterLat
     904                 :                                    sTABProj.adProjParams[0],   // dfCenterLong
     905                 :                                    sTABProj.adProjParams[3],   // dfAzimuth
     906                 :                                    sTABProj.adProjParams[2],   // dfPseudoStdParallelLat
     907                 :                                    1.0,              // dfScale
     908                 :                                    sTABProj.adProjParams[4],   // dfFalseEasting
     909               0 :                                    sTABProj.adProjParams[5] ); // dfFalseNorthing
     910                 :         break;
     911                 : 
     912                 :       default:
     913                 :         break;
     914                 :     }
     915                 : 
     916                 :     /*-----------------------------------------------------------------
     917                 :      * Collect units definition.
     918                 :      *----------------------------------------------------------------*/
     919               2 :     if( sTABProj.nProjId != 1 && m_poSpatialRef->GetRoot() != NULL )
     920                 :     {
     921               2 :         OGR_SRSNode     *poUnits = new OGR_SRSNode("UNIT");
     922                 :         
     923               2 :         m_poSpatialRef->GetRoot()->AddChild(poUnits);
     924                 : 
     925               4 :         poUnits->AddChild( new OGR_SRSNode( pszUnitsName ) );
     926               4 :         poUnits->AddChild( new OGR_SRSNode( pszUnitsConv ) );
     927                 :     }
     928                 : 
     929                 :     /*-----------------------------------------------------------------
     930                 :      * Local (nonearth) coordinate systems have no Geographic relationship
     931                 :      * so we just return from here. 
     932                 :      *----------------------------------------------------------------*/
     933               2 :     if( sTABProj.nProjId == 0 )
     934               0 :         return m_poSpatialRef;
     935                 : 
     936                 :     /*-----------------------------------------------------------------
     937                 :      * Set the datum.  We are only given the X, Y and Z shift for
     938                 :      * the datum, so for now we just synthesize a name from this.
     939                 :      * It would be better if we could lookup a name based on the shift.
     940                 :      *
     941                 :      * Since we have already encountered files in which adDatumParams[] values
     942                 :      * were in the order of 1e-150 when they should have actually been zeros,
     943                 :      * we will use an epsilon in our scan instead of looking for equality.
     944                 :      *----------------------------------------------------------------*/
     945                 : #define TAB_EQUAL(a, b) (((a)<(b) ? ((b)-(a)) : ((a)-(b))) < 1e-10)
     946                 :     char        szDatumName[160];
     947                 :     int         iDatumInfo;
     948               2 :     MapInfoDatumInfo *psDatumInfo = NULL;
     949                 : 
     950              35 :     for( iDatumInfo = 0;
     951                 :          asDatumInfoList[iDatumInfo].nMapInfoDatumID != -1;
     952                 :          iDatumInfo++ )
     953                 :     {
     954              35 :         psDatumInfo = asDatumInfoList + iDatumInfo;
     955                 :         
     956              35 :         if( TAB_EQUAL(psDatumInfo->nEllipsoid, sTABProj.nEllipsoidId) &&
     957                 :             ((sTABProj.nDatumId > 0 && 
     958                 :               sTABProj.nDatumId == psDatumInfo->nMapInfoDatumID) ||
     959                 :              (sTABProj.nDatumId <= 0
     960                 :               && TAB_EQUAL(psDatumInfo->dfShiftX, sTABProj.dDatumShiftX)
     961                 :               && TAB_EQUAL(psDatumInfo->dfShiftY, sTABProj.dDatumShiftY)
     962                 :               && TAB_EQUAL(psDatumInfo->dfShiftZ, sTABProj.dDatumShiftZ)
     963               0 :               && TAB_EQUAL(psDatumInfo->dfDatumParm0,sTABProj.adDatumParams[0])
     964               0 :               && TAB_EQUAL(psDatumInfo->dfDatumParm1,sTABProj.adDatumParams[1])
     965               0 :               && TAB_EQUAL(psDatumInfo->dfDatumParm2,sTABProj.adDatumParams[2])
     966               0 :               && TAB_EQUAL(psDatumInfo->dfDatumParm3,sTABProj.adDatumParams[3])
     967               0 :               && TAB_EQUAL(psDatumInfo->dfDatumParm4,sTABProj.adDatumParams[4]))))
     968               2 :             break;
     969                 : 
     970              33 :         psDatumInfo = NULL;
     971                 :     }
     972                 : 
     973               2 :     if( psDatumInfo == NULL )
     974                 :     {
     975               0 :         if( sTABProj.adDatumParams[0] == 0.0
     976               0 :             && sTABProj.adDatumParams[1] == 0.0
     977               0 :             && sTABProj.adDatumParams[2] == 0.0
     978               0 :             && sTABProj.adDatumParams[3] == 0.0
     979               0 :             && sTABProj.adDatumParams[4] == 0.0 )
     980                 :         {
     981                 :             sprintf( szDatumName,
     982                 :                      "MIF 999,%d,%.15g,%.15g,%.15g", 
     983                 :                      sTABProj.nEllipsoidId,
     984                 :                      sTABProj.dDatumShiftX, 
     985                 :                      sTABProj.dDatumShiftY, 
     986               0 :                      sTABProj.dDatumShiftZ );
     987                 :         }
     988                 :         else
     989                 :         {
     990                 :             sprintf( szDatumName,
     991                 :                      "MIF 9999,%d,%.15g,%.15g,%.15g,%.15g,%.15g,%.15g,%.15g,%.15g",
     992                 :                      sTABProj.nEllipsoidId,
     993                 :                      sTABProj.dDatumShiftX, 
     994                 :                      sTABProj.dDatumShiftY, 
     995                 :                      sTABProj.dDatumShiftZ,
     996                 :                      sTABProj.adDatumParams[0],
     997                 :                      sTABProj.adDatumParams[1],
     998                 :                      sTABProj.adDatumParams[2],
     999                 :                      sTABProj.adDatumParams[3],
    1000               0 :                      sTABProj.adDatumParams[4] );
    1001                 :         }
    1002                 :     }
    1003               2 :     else if( strlen(psDatumInfo->pszOGCDatumName) > 0 )
    1004                 :     {
    1005                 :         strncpy( szDatumName, psDatumInfo->pszOGCDatumName,
    1006               2 :                  sizeof(szDatumName) );
    1007                 :     }
    1008                 :     else
    1009                 :     {
    1010               0 :         sprintf( szDatumName, "MIF %d", psDatumInfo->nMapInfoDatumID );
    1011                 :     }
    1012                 : 
    1013                 :     /*-----------------------------------------------------------------
    1014                 :      * Set the spheroid.
    1015                 :      *----------------------------------------------------------------*/
    1016               2 :     double      dfSemiMajor=0.0, dfInvFlattening=0.0;
    1017               2 :     const char *pszSpheroidName = NULL;
    1018                 : 
    1019              85 :     for( int i = 0; asSpheroidInfoList[i].nMapInfoId != -1; i++ )
    1020                 :     {
    1021              85 :         if( asSpheroidInfoList[i].nMapInfoId == sTABProj.nEllipsoidId )
    1022                 :         {
    1023               2 :             dfSemiMajor = asSpheroidInfoList[i].dfA;
    1024               2 :             dfInvFlattening = asSpheroidInfoList[i].dfInvFlattening;
    1025               2 :             pszSpheroidName = asSpheroidInfoList[i].pszMapinfoName;
    1026               2 :             break;
    1027                 :         }
    1028                 :     }
    1029                 : 
    1030                 :     // use WGS 84 if nothing is known.
    1031               2 :     if( pszSpheroidName == NULL )
    1032                 :     {
    1033               0 :         pszSpheroidName = "unknown";
    1034               0 :         dfSemiMajor = 6378137.0;
    1035               0 :         dfInvFlattening = 298.257223563;
    1036                 :     }
    1037                 : 
    1038                 :     /*-----------------------------------------------------------------
    1039                 :      * Set the prime meridian.
    1040                 :      *----------------------------------------------------------------*/
    1041               2 :     double      dfPMOffset = 0.0;
    1042               2 :     const char *pszPMName = "Greenwich";
    1043                 :     
    1044               2 :     if( sTABProj.adDatumParams[4] != 0.0 )
    1045                 :     {
    1046               0 :         dfPMOffset = sTABProj.adDatumParams[4];
    1047                 : 
    1048               0 :         pszPMName = "non-Greenwich";
    1049                 :     }
    1050                 :                     
    1051                 :     /*-----------------------------------------------------------------
    1052                 :      * Create a GEOGCS definition.
    1053                 :      *----------------------------------------------------------------*/
    1054                 : 
    1055                 :     m_poSpatialRef->SetGeogCS( "unnamed",
    1056                 :                                szDatumName,
    1057                 :                                pszSpheroidName,
    1058                 :                                dfSemiMajor, dfInvFlattening,
    1059                 :                                pszPMName, dfPMOffset,
    1060               2 :                                SRS_UA_DEGREE, CPLAtof(SRS_UA_DEGREE_CONV));
    1061                 : 
    1062               2 :     if( psDatumInfo != NULL )
    1063                 :     {
    1064                 :         m_poSpatialRef->SetTOWGS84( psDatumInfo->dfShiftX, 
    1065                 :                                     psDatumInfo->dfShiftY,
    1066                 :                                     psDatumInfo->dfShiftZ,
    1067                 :                                     psDatumInfo->dfDatumParm0 == 0 ? 0 : -psDatumInfo->dfDatumParm0, /* avoids 0 to be transformed into -0 */
    1068                 :                                     psDatumInfo->dfDatumParm1 == 0 ? 0 : -psDatumInfo->dfDatumParm1,
    1069                 :                                     psDatumInfo->dfDatumParm2 == 0 ? 0 : -psDatumInfo->dfDatumParm2,
    1070               2 :                                     psDatumInfo->dfDatumParm3 );
    1071                 :     }
    1072                 : 
    1073                 :     /*-----------------------------------------------------------------
    1074                 :      * Special case for Google Mercator (datum=157, ellipse=54, gdal #4115)
    1075                 :      *----------------------------------------------------------------*/
    1076               2 :     if( sTABProj.nProjId == 10 
    1077                 :         && sTABProj.nDatumId == 157
    1078                 :         && sTABProj.nEllipsoidId == 54 )
    1079                 :     {
    1080               0 :         m_poSpatialRef->SetNode( "PROJCS", "WGS 84 / Pseudo-Mercator" );
    1081               0 :         m_poSpatialRef->SetExtension( "PROJCS", "PROJ4", "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext  +no_defs" );
    1082                 :     }
    1083                 : 
    1084               2 :     return m_poSpatialRef;
    1085                 : }
    1086                 : 
    1087                 : /**********************************************************************
    1088                 :  *                   TABFile::SetSpatialRef()
    1089                 :  *
    1090                 :  * Set the OGRSpatialReference for this dataset.
    1091                 :  * A reference to the OGRSpatialReference will be kept, and it will also
    1092                 :  * be converted into a TABProjInfo to be stored in the .MAP header.
    1093                 :  *
    1094                 :  * Returns 0 on success, and -1 on error.
    1095                 :  **********************************************************************/
    1096               2 : int TABFile::SetSpatialRef(OGRSpatialReference *poSpatialRef)
    1097                 : {
    1098               2 :     if (m_eAccessMode != TABWrite)
    1099                 :     {
    1100                 :         CPLError(CE_Failure, CPLE_NotSupported,
    1101               0 :                  "SetSpatialRef() can be used only with Write access.");
    1102               0 :         return -1;
    1103                 :     }
    1104                 : 
    1105               2 :     if (m_poMAPFile == NULL )
    1106                 :     {
    1107                 :         CPLError(CE_Failure, CPLE_AssertionFailed,
    1108               0 :                  "SetSpatialRef() failed: file has not been opened yet.");
    1109               0 :         return -1;
    1110                 :     }
    1111                 : 
    1112               2 :     if( poSpatialRef == NULL )
    1113                 :     {
    1114                 :         CPLError(CE_Failure, CPLE_AssertionFailed,
    1115               0 :                  "SetSpatialRef() failed: Called with NULL poSpatialRef.");
    1116               0 :         return -1;
    1117                 :     }
    1118                 : 
    1119                 :     /*-----------------------------------------------------------------
    1120                 :      * Keep a copy of the OGRSpatialReference...
    1121                 :      * Note: we have to take the reference count into account...
    1122                 :      *----------------------------------------------------------------*/
    1123               2 :     if (m_poSpatialRef && m_poSpatialRef->Dereference() == 0)
    1124               0 :         delete m_poSpatialRef;
    1125                 :     
    1126               2 :     m_poSpatialRef = poSpatialRef->Clone();
    1127                 : 
    1128                 :     /*-----------------------------------------------------------------
    1129                 :      * Initialize TABProjInfo
    1130                 :      *----------------------------------------------------------------*/
    1131                 :     TABProjInfo     sTABProj;
    1132                 : 
    1133               2 :     sTABProj.nProjId = 0;
    1134               2 :     sTABProj.nEllipsoidId = 0; /* how will we set this? */
    1135               2 :     sTABProj.nUnitsId = 7;
    1136               2 :     sTABProj.adProjParams[0] = sTABProj.adProjParams[1] = 0.0;
    1137               2 :     sTABProj.adProjParams[2] = sTABProj.adProjParams[3] = 0.0;
    1138               2 :     sTABProj.adProjParams[4] = sTABProj.adProjParams[5] = 0.0;
    1139                 :     
    1140               2 :     sTABProj.nDatumId = 0;
    1141               2 :     sTABProj.dDatumShiftX = 0.0;
    1142               2 :     sTABProj.dDatumShiftY = 0.0;
    1143               2 :     sTABProj.dDatumShiftZ = 0.0;
    1144               2 :     sTABProj.adDatumParams[0] = 0.0;
    1145               2 :     sTABProj.adDatumParams[1] = 0.0;
    1146               2 :     sTABProj.adDatumParams[2] = 0.0;
    1147               2 :     sTABProj.adDatumParams[3] = 0.0;
    1148               2 :     sTABProj.adDatumParams[4] = 0.0;
    1149                 : 
    1150               2 :     sTABProj.nAffineFlag   = 0;
    1151               2 :     sTABProj.nAffineUnits  = 7;
    1152               2 :     sTABProj.dAffineParamA = 0.0;
    1153               2 :     sTABProj.dAffineParamB = 0.0;
    1154               2 :     sTABProj.dAffineParamC = 0.0;
    1155               2 :     sTABProj.dAffineParamD = 0.0;
    1156               2 :     sTABProj.dAffineParamE = 0.0;
    1157               2 :     sTABProj.dAffineParamF = 0.0;
    1158                 : 
    1159                 :     /*-----------------------------------------------------------------
    1160                 :      * Get the linear units and conversion.
    1161                 :      *----------------------------------------------------------------*/
    1162                 :     char        *pszLinearUnits;
    1163                 :     double      dfLinearConv;
    1164                 : 
    1165               2 :     dfLinearConv = poSpatialRef->GetLinearUnits( &pszLinearUnits );
    1166               2 :     if( dfLinearConv == 0.0 )
    1167               0 :         dfLinearConv = 1.0;
    1168                 : 
    1169                 :     /*-----------------------------------------------------------------
    1170                 :      * Transform the projection and projection parameters.
    1171                 :      *----------------------------------------------------------------*/
    1172               2 :     const char *pszProjection = poSpatialRef->GetAttrValue("PROJECTION");
    1173               2 :     double      *parms = sTABProj.adProjParams;
    1174                 : 
    1175               2 :     if( pszProjection == NULL && poSpatialRef->GetAttrNode("LOCAL_CS") != NULL)
    1176                 :     {
    1177                 :         /* nonearth */
    1178               0 :         sTABProj.nProjId = 0;
    1179                 :     }
    1180                 : 
    1181               2 :     else if( pszProjection == NULL )
    1182                 :     {
    1183               0 :         sTABProj.nProjId = 1;
    1184                 :     }
    1185                 : 
    1186               2 :     else if( EQUAL(pszProjection,SRS_PT_ALBERS_CONIC_EQUAL_AREA) )
    1187                 :     {
    1188               0 :         sTABProj.nProjId = 9;
    1189               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
    1190               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
    1191               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
    1192               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
    1193               0 :         parms[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1194               0 :         parms[5] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1195                 :     }
    1196                 : 
    1197               2 :     else if( EQUAL(pszProjection,SRS_PT_AZIMUTHAL_EQUIDISTANT) )
    1198                 :     {
    1199               0 :         sTABProj.nProjId = 5;
    1200               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
    1201               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
    1202               0 :         parms[2] = 90.0;
    1203                 : 
    1204               0 :         if( ABS((ABS(parms[1]) - 90)) > 0.001 )
    1205               0 :             sTABProj.nProjId = 28;
    1206                 :     }
    1207                 : 
    1208               2 :     else if( EQUAL(pszProjection,SRS_PT_CYLINDRICAL_EQUAL_AREA) )
    1209                 :     {
    1210               0 :         sTABProj.nProjId = 2;
    1211               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1212               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
    1213                 :     }
    1214                 : 
    1215               2 :     else if( EQUAL(pszProjection,SRS_PT_ECKERT_IV) )
    1216                 :     {
    1217               0 :         sTABProj.nProjId = 14;
    1218               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1219                 :     }
    1220                 : 
    1221               2 :     else if( EQUAL(pszProjection,SRS_PT_ECKERT_VI) )
    1222                 :     {
    1223               0 :         sTABProj.nProjId = 15;
    1224               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1225                 :     }
    1226                 : 
    1227               2 :     else if( EQUAL(pszProjection,SRS_PT_EQUIDISTANT_CONIC) )
    1228                 :     {
    1229               0 :         sTABProj.nProjId = 6;
    1230               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
    1231               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
    1232               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
    1233               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
    1234               0 :         parms[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1235               0 :         parms[5] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1236                 :     }
    1237                 : 
    1238               2 :     else if( EQUAL(pszProjection,SRS_PT_GALL_STEREOGRAPHIC) )
    1239                 :     {
    1240               0 :         sTABProj.nProjId = 17;
    1241               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1242                 :     }
    1243                 : 
    1244               2 :     else if( EQUAL(pszProjection,SRS_PT_HOTINE_OBLIQUE_MERCATOR) )
    1245                 :     {
    1246               0 :         sTABProj.nProjId = 7;
    1247               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
    1248               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
    1249               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_AZIMUTH,0.0);
    1250               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
    1251               0 :         parms[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1252               0 :         parms[5] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1253                 :     }
    1254                 : 
    1255               2 :     else if( EQUAL(pszProjection,SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA) )
    1256                 :     {
    1257               0 :         sTABProj.nProjId = 4;
    1258               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
    1259               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
    1260               0 :         parms[2] = 90.0;
    1261                 : 
    1262               0 :         if( ABS((ABS(parms[1]) - 90)) > 0.001 )
    1263               0 :             sTABProj.nProjId = 28;
    1264                 :     }
    1265                 : 
    1266               2 :     else if( EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP) )
    1267                 :     {
    1268               0 :         sTABProj.nProjId = 3;
    1269               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1270               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1271               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
    1272               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
    1273               0 :         parms[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1274               0 :         parms[5] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1275                 :     }
    1276                 : 
    1277               2 :     else if( EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM) )
    1278                 :     {
    1279               0 :         sTABProj.nProjId = 19;
    1280               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1281               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1282               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
    1283               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
    1284               0 :         parms[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1285               0 :         parms[5] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1286                 :     }
    1287                 : 
    1288               2 :     else if( EQUAL(pszProjection,SRS_PT_MERCATOR_1SP) )
    1289                 :     {
    1290               0 :         sTABProj.nProjId = 10;
    1291               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1292               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1293               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
    1294                 : 
    1295               0 :         if( parms[1] != 0.0 )
    1296               0 :             sTABProj.nProjId = 26;
    1297                 :     }
    1298                 : 
    1299               2 :     else if( EQUAL(pszProjection,SRS_PT_MILLER_CYLINDRICAL) )
    1300                 :     {
    1301               0 :         sTABProj.nProjId = 11;
    1302               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
    1303                 :     }
    1304                 : 
    1305               2 :     else if( EQUAL(pszProjection,SRS_PT_MOLLWEIDE) )
    1306                 :     {
    1307               0 :         sTABProj.nProjId = 13;
    1308               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1309                 :     }
    1310                 : 
    1311               2 :     else if( EQUAL(pszProjection,SRS_PT_NEW_ZEALAND_MAP_GRID) )
    1312                 :     {
    1313               0 :         sTABProj.nProjId = 18;
    1314               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1315               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1316               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1317               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1318                 :     }
    1319                 : 
    1320               2 :     else if( EQUAL(pszProjection,SRS_PT_SWISS_OBLIQUE_CYLINDRICAL) )
    1321                 :     {
    1322               0 :         sTABProj.nProjId = 25;
    1323               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1324               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1325               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1326               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1327                 :     }
    1328                 : 
    1329               2 :     else if( EQUAL(pszProjection,SRS_PT_ROBINSON) )
    1330                 :     {
    1331               0 :         sTABProj.nProjId = 12;
    1332               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1333                 :     }
    1334                 : 
    1335               2 :     else if( EQUAL(pszProjection,SRS_PT_SINUSOIDAL) )
    1336                 :     {
    1337               0 :         sTABProj.nProjId = 16;
    1338               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1339                 :     }
    1340                 : 
    1341               2 :     else if( EQUAL(pszProjection,SRS_PT_STEREOGRAPHIC) )
    1342                 :     {
    1343               0 :         sTABProj.nProjId = 20;
    1344               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1345               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1346               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
    1347               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1348               0 :         parms[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1349                 :     }
    1350                 : 
    1351               2 :     else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR) )
    1352                 :     {
    1353               2 :         sTABProj.nProjId = 8;
    1354               2 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1355               2 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1356               2 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
    1357               2 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1358               2 :         parms[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1359                 :     }
    1360                 : 
    1361               0 :     else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_21) ) // Encom 2003
    1362                 :     {
    1363               0 :         sTABProj.nProjId = 21;
    1364               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1365               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1366               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
    1367               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1368               0 :         parms[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1369                 :     }
    1370                 : 
    1371               0 :     else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_22) ) // Encom 2003
    1372                 :     {
    1373               0 :         sTABProj.nProjId = 22;
    1374               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1375               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1376               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
    1377               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1378               0 :         parms[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1379                 :     }
    1380                 : 
    1381               0 :     else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_23) ) // Encom 2003
    1382                 :     {
    1383               0 :         sTABProj.nProjId = 23;
    1384               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1385               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1386               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
    1387               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1388               0 :         parms[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1389                 :     }
    1390                 : 
    1391               0 :     else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_24) ) // Encom 2003
    1392                 :     {
    1393               0 :         sTABProj.nProjId = 24;
    1394               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1395               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1396               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
    1397               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1398               0 :         parms[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1399                 :     }
    1400                 : 
    1401               0 :     else if( EQUAL(pszProjection,SRS_PT_CASSINI_SOLDNER) )
    1402                 :     {
    1403               0 :         sTABProj.nProjId = 30;
    1404               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1405               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1406               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1407               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1408                 :     }
    1409                 : 
    1410               0 :     else if( EQUAL(pszProjection,SRS_PT_NEW_ZEALAND_MAP_GRID) )
    1411                 :     {
    1412               0 :         sTABProj.nProjId = 18;
    1413               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1414               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1415               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1416               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1417                 :     }
    1418                 : 
    1419               0 :     else if( EQUAL(pszProjection,SRS_PT_POLYCONIC) )
    1420                 :     {
    1421               0 :         sTABProj.nProjId = 27;
    1422               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1423               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1424               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1425               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1426                 :     }
    1427                 : 
    1428               0 :    else if( EQUAL(pszProjection,SRS_PT_KROVAK) )
    1429                 :    {
    1430               0 :         sTABProj.nProjId = 32;
    1431               0 :         parms[0] = poSpatialRef->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
    1432               0 :         parms[1] = poSpatialRef->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
    1433               0 :         parms[2] = poSpatialRef->GetProjParm(SRS_PP_PSEUDO_STD_PARALLEL_1,0.0);
    1434               0 :         parms[3] = poSpatialRef->GetProjParm(SRS_PP_AZIMUTH,0.0);
    1435               0 :         parms[4] = poSpatialRef->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
    1436               0 :         parms[5] = poSpatialRef->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
    1437                 :    }
    1438                 : 
    1439                 :     /* ==============================================================
    1440                 :      * Translate Datum and Ellipsoid
    1441                 :      * ============================================================== */
    1442               2 :     const char *pszWKTDatum = poSpatialRef->GetAttrValue("DATUM");
    1443               2 :     MapInfoDatumInfo *psDatumInfo = NULL;
    1444                 :     
    1445               2 :     int nDatumEPSGCode = -1;
    1446               2 :     const char *pszDatumAuthority = poSpatialRef->GetAuthorityName("DATUM");
    1447               2 :     const char *pszDatumCode = poSpatialRef->GetAuthorityCode("DATUM");
    1448                 : 
    1449               2 :     if (pszDatumCode && pszDatumAuthority && EQUAL(pszDatumAuthority, "EPSG"))
    1450                 :     {
    1451               2 :       nDatumEPSGCode = atoi(pszDatumCode);
    1452                 :     }
    1453                 : 
    1454                 :     /*-----------------------------------------------------------------
    1455                 :      * Default to WGS84 if we have no datum at all.
    1456                 :      *----------------------------------------------------------------*/
    1457               2 :     if( pszWKTDatum == NULL )
    1458                 :     {
    1459               0 :         psDatumInfo = asDatumInfoList+0; /* WGS 84 */
    1460                 :     }
    1461                 : 
    1462                 :     /*-----------------------------------------------------------------
    1463                 :      * We know the MIF datum number, and need to look it up to
    1464                 :      * translate into datum parameters.
    1465                 :      *----------------------------------------------------------------*/
    1466               2 :     else if( EQUALN(pszWKTDatum,"MIF ",4)
    1467                 :              && atoi(pszWKTDatum+4) != 999
    1468                 :              && atoi(pszWKTDatum+4) != 9999 )
    1469                 :     {
    1470                 :         int     i;
    1471                 : 
    1472               0 :         for( i = 0; asDatumInfoList[i].nMapInfoDatumID != -1; i++ )
    1473                 :         {
    1474               0 :             if( atoi(pszWKTDatum+4) == asDatumInfoList[i].nMapInfoDatumID )
    1475                 :             {
    1476               0 :                 psDatumInfo = asDatumInfoList + i;
    1477               0 :                 break;
    1478                 :             }
    1479                 :         }
    1480                 : 
    1481               0 :         if( psDatumInfo == NULL )
    1482               0 :             psDatumInfo = asDatumInfoList+0; /* WGS 84 */
    1483                 :     }
    1484                 : 
    1485                 :     /*-----------------------------------------------------------------
    1486                 :      * We have the MIF datum parameters, and apply those directly.
    1487                 :      *----------------------------------------------------------------*/
    1488               2 :     else if( EQUALN(pszWKTDatum,"MIF ",4)
    1489                 :              && (atoi(pszWKTDatum+4) == 999 || atoi(pszWKTDatum+4) == 9999) )
    1490                 :     {
    1491                 :         char **papszFields;
    1492                 : 
    1493                 :         papszFields =
    1494               0 :             CSLTokenizeStringComplex( pszWKTDatum+4, ",", FALSE, TRUE);
    1495                 : 
    1496               0 :         if( CSLCount(papszFields) >= 5 )
    1497                 :         {
    1498               0 :             sTABProj.nEllipsoidId = (GByte)atoi(papszFields[1]);
    1499               0 :             sTABProj.dDatumShiftX = atof(papszFields[2]);
    1500               0 :             sTABProj.dDatumShiftY = atof(papszFields[3]);
    1501               0 :             sTABProj.dDatumShiftZ = atof(papszFields[4]);
    1502                 :         }
    1503                 : 
    1504               0 :         if( CSLCount(papszFields) >= 10 )
    1505                 :         {
    1506               0 :             sTABProj.adDatumParams[0] = atof(papszFields[5]);
    1507               0 :             sTABProj.adDatumParams[1] = atof(papszFields[6]);
    1508               0 :             sTABProj.adDatumParams[2] = atof(papszFields[7]);
    1509               0 :             sTABProj.adDatumParams[3] = atof(papszFields[8]);
    1510               0 :             sTABProj.adDatumParams[4] = atof(papszFields[9]);
    1511                 :         }
    1512                 : 
    1513               0 :         if( CSLCount(papszFields) < 5 )
    1514               0 :             psDatumInfo = asDatumInfoList+0; /* WKS84 */
    1515                 : 
    1516               0 :         CSLDestroy( papszFields );
    1517                 :     }
    1518                 :     
    1519                 :     /*-----------------------------------------------------------------
    1520                 :      * We have a "real" datum name, and possibly an EPSG code for the
    1521                 :      * datum.  Try to look it up (using EPSG code first) and get the
    1522                 :      * parameters.  If we don't find it with either just use WGS84.
    1523                 :      *----------------------------------------------------------------*/
    1524                 :     else 
    1525                 :     {
    1526                 :         int     i;
    1527                 : 
    1528              35 :         for( i = 0; asDatumInfoList[i].nMapInfoDatumID != -1; i++ )
    1529                 :         {
    1530              35 :           if ( (nDatumEPSGCode > 0 && asDatumInfoList[i].nDatumEPSGCode == nDatumEPSGCode) ||
    1531                 :                EQUAL(pszWKTDatum,asDatumInfoList[i].pszOGCDatumName) )
    1532                 :             {
    1533               2 :                 psDatumInfo = asDatumInfoList + i;
    1534               2 :                 break;
    1535                 :             }
    1536                 :         }
    1537                 : 
    1538               2 :          if( psDatumInfo == NULL )
    1539               0 :             psDatumInfo = asDatumInfoList+0; /* WGS 84 */
    1540                 :     }
    1541                 : 
    1542               2 :     if( psDatumInfo != NULL )
    1543                 :     {
    1544               2 :         sTABProj.nEllipsoidId = (GByte)psDatumInfo->nEllipsoid;
    1545               2 :         sTABProj.nDatumId = (GInt16)psDatumInfo->nMapInfoDatumID;
    1546               2 :         sTABProj.dDatumShiftX = psDatumInfo->dfShiftX;
    1547               2 :         sTABProj.dDatumShiftY = psDatumInfo->dfShiftY;
    1548               2 :         sTABProj.dDatumShiftZ = psDatumInfo->dfShiftZ;
    1549               2 :         sTABProj.adDatumParams[0] = psDatumInfo->dfDatumParm0;
    1550               2 :         sTABProj.adDatumParams[1] = psDatumInfo->dfDatumParm1;
    1551               2 :         sTABProj.adDatumParams[2] = psDatumInfo->dfDatumParm2;
    1552               2 :         sTABProj.adDatumParams[3] = psDatumInfo->dfDatumParm3;
    1553               2 :         sTABProj.adDatumParams[4] = psDatumInfo->dfDatumParm4;
    1554                 :     }
    1555                 :     
    1556                 :     /*-----------------------------------------------------------------
    1557                 :      * Translate the units
    1558                 :      *----------------------------------------------------------------*/
    1559               2 :     if( sTABProj.nProjId == 1 || pszLinearUnits == NULL )
    1560               0 :         sTABProj.nUnitsId = 13;
    1561               2 :     else if( dfLinearConv == 1000.0 )
    1562               0 :         sTABProj.nUnitsId = 1;
    1563               2 :     else if( dfLinearConv == 0.0254 || EQUAL(pszLinearUnits,"Inch")
    1564                 :              || EQUAL(pszLinearUnits,"IINCH") )
    1565               0 :         sTABProj.nUnitsId = 2;
    1566               2 :     else if( dfLinearConv == CPLAtof(SRS_UL_FOOT_CONV)
    1567                 :              || EQUAL(pszLinearUnits,SRS_UL_FOOT) )
    1568               0 :         sTABProj.nUnitsId = 3;
    1569               2 :     else if( EQUAL(pszLinearUnits,"YARD") || EQUAL(pszLinearUnits,"IYARD") 
    1570                 :              || dfLinearConv == 0.9144 )
    1571               0 :         sTABProj.nUnitsId = 4;
    1572               2 :     else if( dfLinearConv == 0.001 )
    1573               0 :         sTABProj.nUnitsId = 5;
    1574               2 :     else if( dfLinearConv == 0.01 )
    1575               0 :         sTABProj.nUnitsId = 6;
    1576               2 :     else if( dfLinearConv == 1.0 )
    1577               2 :         sTABProj.nUnitsId = 7;
    1578               0 :     else if( dfLinearConv == CPLAtof(SRS_UL_US_FOOT_CONV)
    1579                 :              || EQUAL(pszLinearUnits,SRS_UL_US_FOOT) )
    1580               0 :         sTABProj.nUnitsId = 8;
    1581               0 :     else if( EQUAL(pszLinearUnits,SRS_UL_NAUTICAL_MILE) )
    1582               0 :         sTABProj.nUnitsId = 9;
    1583               0 :     else if( EQUAL(pszLinearUnits,SRS_UL_LINK) 
    1584                 :              || EQUAL(pszLinearUnits,"GUNTERLINK") )
    1585               0 :         sTABProj.nUnitsId = 30;
    1586               0 :     else if( EQUAL(pszLinearUnits,SRS_UL_CHAIN) 
    1587                 :              || EQUAL(pszLinearUnits,"GUNTERCHAIN") )
    1588               0 :         sTABProj.nUnitsId = 31;
    1589               0 :     else if( EQUAL(pszLinearUnits,SRS_UL_ROD) )
    1590               0 :         sTABProj.nUnitsId = 32;
    1591               0 :     else if( EQUAL(pszLinearUnits,"Mile") 
    1592                 :              || EQUAL(pszLinearUnits,"IMILE") )
    1593               0 :         sTABProj.nUnitsId = 0;
    1594                 :     else
    1595               0 :         sTABProj.nUnitsId = 7;
    1596                 :     
    1597                 :     /*-----------------------------------------------------------------
    1598                 :      * Set the new parameters in the .MAP header.
    1599                 :      * This will also trigger lookup of default bounds for the projection.
    1600                 :      *----------------------------------------------------------------*/
    1601               2 :     if ( SetProjInfo( &sTABProj ) != 0 )
    1602                 :     {
    1603                 :         CPLError(CE_Failure, CPLE_FileIO,
    1604               0 :                  "SetSpatialRef() failed setting projection parameters.");
    1605               0 :         return -1;
    1606                 :     }
    1607                 : 
    1608               2 :     return 0;
    1609                 : }
    1610                 : 

Generated by: LCOV version 1.7