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