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 44 : static double GetMIFParm( char ** papszFields, int iField, double dfDefault )
129 :
130 : {
131 44 : if( iField >= CSLCount(papszFields) )
132 0 : return dfDefault;
133 : else
134 44 : 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 8 : OGRSpatialReference *MITABCoordSys2SpatialRef( const char * pszCoordSys )
145 :
146 : {
147 : char **papszFields;
148 : OGRSpatialReference *poSR;
149 :
150 8 : if( pszCoordSys == NULL )
151 0 : return NULL;
152 :
153 : /* -------------------------------------------------------------------- */
154 : /* Parse the passed string into words. */
155 : /* -------------------------------------------------------------------- */
156 8 : while(*pszCoordSys == ' ') pszCoordSys++; // Eat leading spaces
157 8 : if( EQUALN(pszCoordSys,"CoordSys",8) )
158 4 : pszCoordSys += 9;
159 :
160 8 : papszFields = CSLTokenizeStringComplex( pszCoordSys, " ,", TRUE, FALSE );
161 :
162 : /* -------------------------------------------------------------------- */
163 : /* Clip off Bounds information. */
164 : /* -------------------------------------------------------------------- */
165 8 : int iBounds = CSLFindString( papszFields, "Bounds" );
166 :
167 28 : while( iBounds != -1 && papszFields[iBounds] != NULL )
168 : {
169 12 : CPLFree( papszFields[iBounds] );
170 12 : papszFields[iBounds] = NULL;
171 12 : iBounds++;
172 : }
173 :
174 : /* -------------------------------------------------------------------- */
175 : /* Create a spatialreference object to operate on. */
176 : /* -------------------------------------------------------------------- */
177 8 : poSR = new OGRSpatialReference;
178 :
179 : /* -------------------------------------------------------------------- */
180 : /* Fetch the projection. */
181 : /* -------------------------------------------------------------------- */
182 : char **papszNextField;
183 8 : int nProjection = 0;
184 :
185 24 : if( CSLCount( papszFields ) >= 3
186 8 : && EQUAL(papszFields[0],"Earth")
187 8 : && EQUAL(papszFields[1],"Projection") )
188 : {
189 8 : nProjection = atoi(papszFields[2]);
190 8 : 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 8 : int nDatum = 0;
217 8 : double adfDatumParm[8] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
218 8 : int nEllipsoid=0;
219 :
220 8 : if( nProjection != 0 && CSLCount(papszNextField) > 0 )
221 : {
222 8 : nDatum = atoi(papszNextField[0]);
223 8 : papszNextField++;
224 : }
225 :
226 8 : 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 8 : 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 8 : const char *pszMIFUnits = NULL;
251 8 : const char *pszUnitsName = NULL;
252 8 : double dfUnitsConv = 1.0;
253 :
254 8 : if( CSLCount(papszNextField) > 0 )
255 : {
256 8 : pszMIFUnits = papszNextField[0];
257 8 : papszNextField++;
258 : }
259 :
260 8 : if( nProjection == 1 || pszMIFUnits == NULL )
261 : /* do nothing */;
262 8 : else if( EQUAL(pszMIFUnits,"km") )
263 : {
264 0 : pszUnitsName = "Kilometer";
265 0 : dfUnitsConv = 1000.0;
266 : }
267 8 : else if( EQUAL(pszMIFUnits, "in" ) )
268 : {
269 0 : pszUnitsName = "IINCH";
270 0 : dfUnitsConv = 0.0254;
271 : }
272 8 : else if( EQUAL(pszMIFUnits, "ft" ) )
273 : {
274 0 : pszUnitsName = SRS_UL_FOOT;
275 0 : dfUnitsConv = CPLAtof(SRS_UL_FOOT_CONV);
276 : }
277 8 : else if( EQUAL(pszMIFUnits, "yd" ) )
278 : {
279 0 : pszUnitsName = "IYARD";
280 0 : dfUnitsConv = 0.9144;
281 : }
282 8 : else if( EQUAL(pszMIFUnits, "mm" ) )
283 : {
284 0 : pszUnitsName = "Millimeter";
285 0 : dfUnitsConv = 0.001;
286 : }
287 8 : else if( EQUAL(pszMIFUnits, "cm" ) )
288 : {
289 0 : pszUnitsName = "Centimeter";
290 0 : dfUnitsConv = 0.01;
291 : }
292 8 : else if( EQUAL(pszMIFUnits, "m" ) )
293 : {
294 8 : pszUnitsName = SRS_UL_METER;
295 8 : 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 8 : int nBaseProjection = nProjection;
337 8 : if (nBaseProjection>=3000) nBaseProjection -=3000;
338 8 : else if (nBaseProjection>=2000) nBaseProjection -=2000;
339 8 : else if (nBaseProjection>=1000) nBaseProjection -=1000;
340 8 : 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 4 : GetMIFParm( papszNextField, 5, 0.0 ) );
383 4 : 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 4 : GetMIFParm( papszNextField, 4, 0.0 ) );
439 4 : 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 :
532 : /*--------------------------------------------------------------
533 : * Eckert IV
534 : *-------------------------------------------------------------*/
535 : case 14:
536 : poSR->SetEckertIV( GetMIFParm( papszNextField, 0, 0.0 ),
537 0 : 0.0, 0.0 );
538 0 : break;
539 :
540 : /*--------------------------------------------------------------
541 : * Eckert VI
542 : *-------------------------------------------------------------*/
543 : case 15:
544 : poSR->SetEckertVI( GetMIFParm( papszNextField, 0, 0.0 ),
545 0 : 0.0, 0.0 );
546 0 : break;
547 :
548 : /*--------------------------------------------------------------
549 : * Sinusoidal
550 : *-------------------------------------------------------------*/
551 : case 16:
552 : poSR->SetSinusoidal( GetMIFParm( papszNextField, 0, 0.0 ),
553 0 : 0.0, 0.0 );
554 0 : break;
555 :
556 : /*--------------------------------------------------------------
557 : * Gall
558 : *-------------------------------------------------------------*/
559 : case 17:
560 : poSR->SetGS( GetMIFParm( papszNextField, 0, 0.0 ),
561 0 : 0.0, 0.0 );
562 0 : break;
563 :
564 : /*--------------------------------------------------------------
565 : * New Zealand Map Grid
566 : *-------------------------------------------------------------*/
567 : case 18:
568 : poSR->SetNZMG( GetMIFParm( papszNextField, 1, 0.0 ),
569 : GetMIFParm( papszNextField, 0, 0.0 ),
570 : GetMIFParm( papszNextField, 2, 0.0 ),
571 0 : GetMIFParm( papszNextField, 3, 0.0 ) );
572 0 : break;
573 :
574 : /*--------------------------------------------------------------
575 : * Lambert Conic Conformal (Belgium)
576 : *-------------------------------------------------------------*/
577 : case 19:
578 : poSR->SetLCCB( GetMIFParm( papszNextField, 2, 0.0 ),
579 : GetMIFParm( papszNextField, 3, 0.0 ),
580 : GetMIFParm( papszNextField, 1, 0.0 ),
581 : GetMIFParm( papszNextField, 0, 0.0 ),
582 : GetMIFParm( papszNextField, 4, 0.0 ),
583 0 : GetMIFParm( papszNextField, 5, 0.0 ) );
584 0 : break;
585 :
586 : /*--------------------------------------------------------------
587 : * Stereographic
588 : *-------------------------------------------------------------*/
589 : case 20:
590 : case 31: /* double stereographic */
591 : poSR->SetStereographic(
592 : GetMIFParm( papszNextField, 1, 0.0 ),
593 : GetMIFParm( papszNextField, 0, 0.0 ),
594 : GetMIFParm( papszNextField, 2, 1.0 ),
595 : GetMIFParm( papszNextField, 3, 0.0 ),
596 0 : GetMIFParm( papszNextField, 4, 0.0 ) );
597 0 : break;
598 :
599 : /*--------------------------------------------------------------
600 : * Swiss Oblique Mercator / Cylindrical
601 : *-------------------------------------------------------------*/
602 : case 25:
603 : poSR->SetSOC( GetMIFParm( papszNextField, 1, 0.0 ),
604 : GetMIFParm( papszNextField, 0, 0.0 ),
605 : GetMIFParm( papszNextField, 2, 0.0 ),
606 0 : GetMIFParm( papszNextField, 3, 0.0 ) );
607 0 : break;
608 :
609 : /*--------------------------------------------------------------
610 : * Regional Mercator
611 : *-------------------------------------------------------------*/
612 : case 26:
613 : poSR->SetMercator( GetMIFParm( papszNextField, 1, 0.0 ),
614 : GetMIFParm( papszNextField, 0, 0.0 ),
615 0 : 1.0, 0.0, 0.0 );
616 0 : break;
617 :
618 : /*--------------------------------------------------------------
619 : * Polygonic
620 : *-------------------------------------------------------------*/
621 : case 27:
622 : poSR->SetPolyconic( GetMIFParm( papszNextField, 1, 0.0 ),
623 : GetMIFParm( papszNextField, 0, 0.0 ),
624 : GetMIFParm( papszNextField, 2, 0.0 ),
625 0 : GetMIFParm( papszNextField, 3, 0.0 ) );
626 0 : break;
627 :
628 : /*--------------------------------------------------------------
629 : * CassiniSoldner
630 : *-------------------------------------------------------------*/
631 : case 30:
632 : poSR->SetCS(
633 : GetMIFParm( papszNextField, 1, 0.0 ),
634 : GetMIFParm( papszNextField, 0, 0.0 ),
635 : GetMIFParm( papszNextField, 2, 0.0 ),
636 0 : GetMIFParm( papszNextField, 3, 0.0 ) );
637 0 : break;
638 :
639 : /*--------------------------------------------------------------
640 : * Krovak
641 : *-------------------------------------------------------------*/
642 : case 32:
643 : poSR->SetKrovak( GetMIFParm( papszNextField, 1, 0.0 ), // dfCenterLat
644 : GetMIFParm( papszNextField, 0, 0.0 ), // dfCenterLong
645 : GetMIFParm( papszNextField, 3, 1.0 ), // dfAzimuth
646 : GetMIFParm( papszNextField, 2, 0.0 ), // dfPseudoStdParallelLat
647 : 1.0, // dfScale
648 : GetMIFParm( papszNextField, 4, 0.0 ), // dfFalseEasting
649 0 : GetMIFParm( papszNextField, 5, 0.0 )); // dfFalseNorthing
650 : break;
651 :
652 : default:
653 : break;
654 : }
655 :
656 : /* -------------------------------------------------------------------- */
657 : /* Set linear units. */
658 : /* -------------------------------------------------------------------- */
659 8 : if( pszUnitsName != NULL )
660 8 : poSR->SetLinearUnits( pszUnitsName, dfUnitsConv );
661 :
662 : /* -------------------------------------------------------------------- */
663 : /* For Non-Earth projection, we're done at this point. */
664 : /* -------------------------------------------------------------------- */
665 8 : if (nProjection == 0)
666 : {
667 0 : CSLDestroy(papszFields);
668 0 : return poSR;
669 : }
670 :
671 : /* ==================================================================== */
672 : /* Establish the GeogCS */
673 : /* ==================================================================== */
674 8 : const char *pszGeogName = "unnamed";
675 8 : const char *pszSpheroidName = "GRS_1980";
676 8 : double dfSemiMajor = 6378137.0;
677 8 : double dfInvFlattening = 298.257222101;
678 8 : const char *pszPrimeM = "Greenwich";
679 8 : double dfPMLongToGreenwich = 0.0;
680 :
681 : /* -------------------------------------------------------------------- */
682 : /* Find the datum, and collect it's parameters if possible. */
683 : /* -------------------------------------------------------------------- */
684 : int iDatum;
685 8 : MapInfoDatumInfo *psDatumInfo = NULL;
686 :
687 786 : for( iDatum = 0; asDatumInfoList[iDatum].nMapInfoDatumID != -1; iDatum++ )
688 : {
689 786 : if( asDatumInfoList[iDatum].nMapInfoDatumID == nDatum )
690 : {
691 8 : psDatumInfo = asDatumInfoList + iDatum;
692 8 : break;
693 : }
694 : }
695 :
696 8 : if( asDatumInfoList[iDatum].nMapInfoDatumID == -1
697 : && nDatum != 999 && nDatum != 9999 )
698 : {
699 : /* use WGS84 */
700 0 : psDatumInfo = asDatumInfoList + 0;
701 : }
702 :
703 8 : if( psDatumInfo != NULL )
704 : {
705 8 : nEllipsoid = psDatumInfo->nEllipsoid;
706 8 : adfDatumParm[0] = psDatumInfo->dfShiftX;
707 8 : adfDatumParm[1] = psDatumInfo->dfShiftY;
708 8 : adfDatumParm[2] = psDatumInfo->dfShiftZ;
709 8 : adfDatumParm[3] = psDatumInfo->dfDatumParm0;
710 8 : adfDatumParm[4] = psDatumInfo->dfDatumParm1;
711 8 : adfDatumParm[5] = psDatumInfo->dfDatumParm2;
712 8 : adfDatumParm[6] = psDatumInfo->dfDatumParm3;
713 8 : adfDatumParm[7] = psDatumInfo->dfDatumParm4;
714 : }
715 :
716 : /* -------------------------------------------------------------------- */
717 : /* Set the spheroid if it is known from the table. */
718 : /* -------------------------------------------------------------------- */
719 48 : for( int i = 0; asSpheroidInfoList[i].nMapInfoId != -1; i++ )
720 : {
721 48 : if( asSpheroidInfoList[i].nMapInfoId == nEllipsoid )
722 : {
723 8 : dfSemiMajor = asSpheroidInfoList[i].dfA;
724 8 : dfInvFlattening = asSpheroidInfoList[i].dfInvFlattening;
725 8 : pszSpheroidName = asSpheroidInfoList[i].pszMapinfoName;
726 8 : break;
727 : }
728 : }
729 :
730 : /* -------------------------------------------------------------------- */
731 : /* apply datum parameters. */
732 : /* -------------------------------------------------------------------- */
733 : char szDatumName[128];
734 :
735 8 : if( nDatum == 999 )
736 : {
737 : sprintf( szDatumName,
738 : "MIF 9999,%d,%.15g,%.15g,%.15g",
739 : nEllipsoid,
740 : adfDatumParm[0],
741 : adfDatumParm[1],
742 0 : adfDatumParm[2] );
743 : }
744 8 : else if( nDatum == 9999 )
745 : {
746 : sprintf( szDatumName,
747 : "MIF 9999,%d,%.15g,%.15g,%.15g,%.15g,%.15g,%.15g,%.15g,%.15g",
748 : nEllipsoid,
749 : adfDatumParm[0],
750 : adfDatumParm[1],
751 : adfDatumParm[2],
752 : adfDatumParm[3],
753 : adfDatumParm[4],
754 : adfDatumParm[5],
755 : adfDatumParm[6],
756 0 : adfDatumParm[7] );
757 : }
758 16 : else if( psDatumInfo->pszOGCDatumName != NULL
759 : && strlen(psDatumInfo->pszOGCDatumName) > 0 )
760 : {
761 : strncpy( szDatumName, psDatumInfo->pszOGCDatumName,
762 8 : sizeof(szDatumName) );
763 : }
764 : else
765 : {
766 0 : sprintf( szDatumName, "MIF %d", nDatum );
767 : }
768 :
769 : /* -------------------------------------------------------------------- */
770 : /* Set prime meridian for 9999 datums. */
771 : /* -------------------------------------------------------------------- */
772 8 : if( nDatum == 9999 || adfDatumParm[7] != 0.0 )
773 : {
774 2 : pszPrimeM = "non-Greenwich";
775 2 : dfPMLongToGreenwich = adfDatumParm[7];
776 : }
777 :
778 : /* -------------------------------------------------------------------- */
779 : /* Set the GeogCS. */
780 : /* -------------------------------------------------------------------- */
781 : poSR->SetGeogCS( pszGeogName, szDatumName, pszSpheroidName,
782 : dfSemiMajor, dfInvFlattening,
783 : pszPrimeM, dfPMLongToGreenwich,
784 : SRS_UA_DEGREE,
785 8 : CPLAtof(SRS_UA_DEGREE_CONV) );
786 :
787 : poSR->SetTOWGS84( adfDatumParm[0], adfDatumParm[1], adfDatumParm[2],
788 24 : -adfDatumParm[3], -adfDatumParm[4], -adfDatumParm[5],
789 32 : adfDatumParm[6] );
790 :
791 : /*-----------------------------------------------------------------
792 : * Special case for Google Mercator (datum=157, ellipse=54, gdal #4115)
793 : *----------------------------------------------------------------*/
794 :
795 8 : if( nBaseProjection == 10 && nDatum == 157 )
796 : {
797 0 : poSR->SetNode( "PROJCS", "WGS 84 / Pseudo-Mercator" );
798 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" );
799 : }
800 : /* -------------------------------------------------------------------- */
801 : /* Report on translation. */
802 : /* -------------------------------------------------------------------- */
803 : char *pszWKT;
804 :
805 8 : poSR->exportToWkt( &pszWKT );
806 8 : if( pszWKT != NULL )
807 : {
808 : CPLDebug( "MITAB",
809 : "This CoordSys value:\n%s\nwas translated to:\n%s\n",
810 8 : pszCoordSys, pszWKT );
811 8 : CPLFree( pszWKT );
812 : }
813 :
814 8 : CSLDestroy(papszFields);
815 :
816 8 : return poSR;
817 : }
818 :
819 : /************************************************************************/
820 : /* MITABSpatialRef2CoordSys() */
821 : /* */
822 : /* Converts a OGRSpatialReference object into a MIF COORDSYS */
823 : /* string. */
824 : /* */
825 : /* The function returns a newly allocated string that should be */
826 : /* CPLFree()'d by the caller. */
827 : /************************************************************************/
828 :
829 4 : char *MITABSpatialRef2CoordSys( OGRSpatialReference * poSR )
830 :
831 : {
832 4 : if( poSR == NULL )
833 0 : return NULL;
834 :
835 : /*-----------------------------------------------------------------
836 : * Get the linear units.
837 : *----------------------------------------------------------------*/
838 : double dfLinearConv;
839 : char *pszLinearUnits;
840 :
841 4 : dfLinearConv = poSR->GetLinearUnits( &pszLinearUnits );
842 :
843 : /*-----------------------------------------------------------------
844 : * Transform the projection and projection parameters.
845 : *----------------------------------------------------------------*/
846 4 : const char *pszProjection = poSR->GetAttrValue("PROJECTION");
847 : double parms[10];
848 4 : int nProjection = 0;
849 4 : int nParmCount = 0;
850 :
851 4 : if( pszProjection == NULL )
852 : {
853 : /*--------------------------------------------------------------
854 : * NULL projection.
855 : * We have 2 possibilities: CoordSys NonEarth or Lat/Lon
856 : * NonEarth ... is an empty SpatialRef.
857 : * Lat/Lon has no "PROJECTION" but GEOGCS is set
858 : *-------------------------------------------------------------*/
859 0 : if ( poSR->GetAttrValue("GEOGCS") == NULL)
860 0 : nProjection = 0; // Non-Earth
861 : else
862 0 : nProjection = 1; // Lat/Lon
863 : }
864 4 : else if( EQUAL(pszProjection,SRS_PT_ALBERS_CONIC_EQUAL_AREA) )
865 : {
866 0 : nProjection = 9;
867 0 : parms[0] = poSR->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
868 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
869 0 : parms[2] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
870 0 : parms[3] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
871 0 : parms[4] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
872 0 : parms[5] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
873 0 : nParmCount = 6;
874 : }
875 :
876 4 : else if( EQUAL(pszProjection,SRS_PT_AZIMUTHAL_EQUIDISTANT) )
877 : {
878 0 : nProjection = 5;
879 0 : parms[0] = poSR->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
880 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
881 0 : parms[2] = 90.0;
882 0 : nParmCount = 3;
883 :
884 0 : if( ABS((ABS(parms[1]) - 90)) > 0.001 )
885 0 : nProjection = 28;
886 : }
887 :
888 4 : else if( EQUAL(pszProjection,SRS_PT_CYLINDRICAL_EQUAL_AREA) )
889 : {
890 0 : nProjection = 2;
891 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
892 0 : parms[1] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
893 0 : nParmCount = 2;
894 : }
895 :
896 4 : else if( EQUAL(pszProjection,SRS_PT_ECKERT_IV) )
897 : {
898 0 : nProjection = 14;
899 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
900 0 : nParmCount = 1;
901 : }
902 :
903 4 : else if( EQUAL(pszProjection,SRS_PT_ECKERT_VI) )
904 : {
905 0 : nProjection = 15;
906 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
907 0 : nParmCount = 1;
908 : }
909 :
910 4 : else if( EQUAL(pszProjection,SRS_PT_EQUIDISTANT_CONIC) )
911 : {
912 0 : nProjection = 6;
913 0 : parms[0] = poSR->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
914 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
915 0 : parms[2] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
916 0 : parms[3] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
917 0 : parms[4] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
918 0 : parms[5] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
919 0 : nParmCount = 6;
920 : }
921 :
922 4 : else if( EQUAL(pszProjection,SRS_PT_GALL_STEREOGRAPHIC) )
923 : {
924 0 : nProjection = 17;
925 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
926 0 : nParmCount = 1;
927 : }
928 :
929 4 : else if( EQUAL(pszProjection,SRS_PT_HOTINE_OBLIQUE_MERCATOR) )
930 : {
931 0 : nProjection = 7;
932 0 : parms[0] = poSR->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
933 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
934 0 : parms[2] = poSR->GetProjParm(SRS_PP_AZIMUTH,0.0);
935 0 : parms[3] = poSR->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
936 0 : parms[4] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
937 0 : parms[5] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
938 0 : nParmCount = 6;
939 : }
940 :
941 4 : else if( EQUAL(pszProjection,SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA) )
942 : {
943 0 : nProjection = 4;
944 0 : parms[0] = poSR->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
945 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
946 0 : parms[2] = 90.0;
947 0 : nParmCount = 3;
948 :
949 0 : if( ABS((ABS(parms[1]) - 90)) > 0.001 )
950 0 : nProjection = 28;
951 : }
952 :
953 4 : else if( EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP) )
954 : {
955 2 : nProjection = 3;
956 2 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
957 2 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
958 2 : parms[2] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
959 2 : parms[3] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
960 2 : parms[4] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
961 2 : parms[5] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
962 2 : nParmCount = 6;
963 : }
964 :
965 2 : else if( EQUAL(pszProjection,SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM) )
966 : {
967 0 : nProjection = 19;
968 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
969 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
970 0 : parms[2] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_1,0.0);
971 0 : parms[3] = poSR->GetProjParm(SRS_PP_STANDARD_PARALLEL_2,0.0);
972 0 : parms[4] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
973 0 : parms[5] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
974 0 : nParmCount = 6;
975 : }
976 :
977 2 : else if( EQUAL(pszProjection,SRS_PT_MERCATOR_1SP) )
978 : {
979 0 : nProjection = 10;
980 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
981 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
982 0 : nParmCount = 1;
983 :
984 0 : if( parms[1] != 0.0 )
985 : {
986 0 : nProjection = 26;
987 0 : nParmCount = 2;
988 : }
989 : }
990 :
991 2 : else if( EQUAL(pszProjection,SRS_PT_MILLER_CYLINDRICAL) )
992 : {
993 0 : nProjection = 11;
994 0 : parms[0] = poSR->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
995 0 : nParmCount = 1;
996 : }
997 :
998 2 : else if( EQUAL(pszProjection,SRS_PT_MOLLWEIDE) )
999 : {
1000 0 : nProjection = 13;
1001 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
1002 0 : nParmCount = 1;
1003 : }
1004 :
1005 2 : else if( EQUAL(pszProjection,SRS_PT_SWISS_OBLIQUE_CYLINDRICAL) )
1006 : {
1007 0 : nProjection = 25;
1008 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
1009 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
1010 0 : parms[2] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
1011 0 : parms[3] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
1012 0 : nParmCount = 4;
1013 : }
1014 :
1015 2 : else if( EQUAL(pszProjection,SRS_PT_ROBINSON) )
1016 : {
1017 0 : nProjection = 12;
1018 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
1019 0 : nParmCount = 1;
1020 : }
1021 :
1022 2 : else if( EQUAL(pszProjection,SRS_PT_SINUSOIDAL) )
1023 : {
1024 0 : nProjection = 16;
1025 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
1026 0 : nParmCount = 1;
1027 : }
1028 :
1029 2 : else if( EQUAL(pszProjection,SRS_PT_STEREOGRAPHIC) )
1030 : {
1031 0 : nProjection = 20;
1032 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
1033 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
1034 0 : parms[2] = poSR->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
1035 0 : parms[3] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
1036 0 : parms[4] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
1037 0 : nParmCount = 5;
1038 : }
1039 :
1040 2 : else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR) )
1041 : {
1042 2 : nProjection = 8;
1043 2 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
1044 2 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
1045 2 : parms[2] = poSR->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
1046 2 : parms[3] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
1047 2 : parms[4] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
1048 2 : nParmCount = 5;
1049 : }
1050 :
1051 : // Transverse Mercator,(modified for Danish System 34 Jylland-Fyn)
1052 0 : else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_21) )
1053 : {
1054 0 : nProjection = 21;
1055 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
1056 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
1057 0 : parms[2] = poSR->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
1058 0 : parms[3] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
1059 0 : parms[4] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
1060 0 : nParmCount = 5;
1061 : }
1062 :
1063 : // Transverse Mercator,(modified for Danish System 34 Sjaelland)
1064 0 : else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_22) )
1065 : {
1066 0 : nProjection = 22;
1067 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
1068 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
1069 0 : parms[2] = poSR->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
1070 0 : parms[3] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
1071 0 : parms[4] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
1072 0 : nParmCount = 5;
1073 : }
1074 :
1075 : // Transverse Mercator,(modified for Danish System 34/45 Bornholm)
1076 0 : else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_23) )
1077 : {
1078 0 : nProjection = 23;
1079 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
1080 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
1081 0 : parms[2] = poSR->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
1082 0 : parms[3] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
1083 0 : parms[4] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
1084 0 : nParmCount = 5;
1085 : }
1086 :
1087 : // Transverse Mercator,(modified for Finnish KKJ)
1088 0 : else if( EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR_MI_24) )
1089 : {
1090 0 : nProjection = 24;
1091 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
1092 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
1093 0 : parms[2] = poSR->GetProjParm(SRS_PP_SCALE_FACTOR,1.0);
1094 0 : parms[3] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
1095 0 : parms[4] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
1096 0 : nParmCount = 5;
1097 : }
1098 :
1099 0 : else if( EQUAL(pszProjection,SRS_PT_CASSINI_SOLDNER) )
1100 : {
1101 0 : nProjection = 30;
1102 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
1103 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
1104 0 : parms[2] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
1105 0 : parms[3] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
1106 0 : nParmCount = 4;
1107 : }
1108 :
1109 0 : else if( EQUAL(pszProjection,SRS_PT_NEW_ZEALAND_MAP_GRID) )
1110 : {
1111 0 : nProjection = 18;
1112 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
1113 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
1114 0 : parms[2] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
1115 0 : parms[3] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
1116 0 : nParmCount = 4;
1117 : }
1118 :
1119 0 : else if( EQUAL(pszProjection,SRS_PT_POLYCONIC) )
1120 : {
1121 0 : nProjection = 27;
1122 0 : parms[0] = poSR->GetProjParm(SRS_PP_CENTRAL_MERIDIAN,0.0);
1123 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_ORIGIN,0.0);
1124 0 : parms[2] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
1125 0 : parms[3] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
1126 0 : nParmCount = 4;
1127 : }
1128 :
1129 0 : else if( EQUAL(pszProjection,SRS_PT_KROVAK) )
1130 : {
1131 0 : nProjection = 32;
1132 0 : parms[0] = poSR->GetProjParm(SRS_PP_LONGITUDE_OF_CENTER,0.0);
1133 0 : parms[1] = poSR->GetProjParm(SRS_PP_LATITUDE_OF_CENTER,0.0);
1134 0 : parms[2] = poSR->GetProjParm(SRS_PP_PSEUDO_STD_PARALLEL_1,0.0);
1135 0 : parms[3] = poSR->GetProjParm(SRS_PP_AZIMUTH,0.0);
1136 0 : parms[4] = poSR->GetProjParm(SRS_PP_FALSE_EASTING,0.0);
1137 0 : parms[5] = poSR->GetProjParm(SRS_PP_FALSE_NORTHING,0.0);
1138 0 : nParmCount = 6;
1139 : }
1140 :
1141 : /* ==============================================================
1142 : * Translate Datum and Ellipsoid
1143 : * ============================================================== */
1144 4 : int nDatum = 0;
1145 4 : double adfDatumParm[8] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
1146 4 : int nEllipsoid=0;
1147 :
1148 4 : const char *pszWKTDatum = poSR->GetAttrValue("DATUM");
1149 :
1150 4 : if( pszWKTDatum == NULL )
1151 : {
1152 0 : nDatum = 0;
1153 0 : if( nProjection == 1 )
1154 0 : nProjection = 0;
1155 : }
1156 :
1157 : /*-----------------------------------------------------------------
1158 : * We know the MIF datum number, and need to look it up to
1159 : * translate into datum parameters.
1160 : *----------------------------------------------------------------*/
1161 4 : else if( EQUALN(pszWKTDatum,"MIF ",4)
1162 : && atoi(pszWKTDatum+4) != 999
1163 : && atoi(pszWKTDatum+4) != 9999 )
1164 : {
1165 0 : nDatum = atoi(pszWKTDatum+4);
1166 : }
1167 :
1168 : /*-----------------------------------------------------------------
1169 : * We have the MIF datum parameters, and apply those directly.
1170 : *----------------------------------------------------------------*/
1171 4 : else if( EQUALN(pszWKTDatum,"MIF ",4)
1172 : && (atoi(pszWKTDatum+4) == 999 || atoi(pszWKTDatum+4) == 9999) )
1173 : {
1174 : char **papszFields;
1175 :
1176 0 : nDatum = atoi(pszWKTDatum+4);
1177 :
1178 : papszFields =
1179 0 : CSLTokenizeStringComplex( pszWKTDatum+4, ",", FALSE, TRUE);
1180 :
1181 0 : if( CSLCount(papszFields) >= 5 )
1182 : {
1183 0 : nEllipsoid = atoi(papszFields[1]);
1184 0 : adfDatumParm[0] = atof(papszFields[2]);
1185 0 : adfDatumParm[1] = atof(papszFields[3]);
1186 0 : adfDatumParm[2] = atof(papszFields[4]);
1187 : }
1188 :
1189 0 : if( CSLCount(papszFields) >= 10 )
1190 : {
1191 0 : adfDatumParm[3] = atof(papszFields[5]);
1192 0 : adfDatumParm[4] = atof(papszFields[6]);
1193 0 : adfDatumParm[5] = atof(papszFields[7]);
1194 0 : adfDatumParm[6] = atof(papszFields[8]);
1195 0 : adfDatumParm[7] = atof(papszFields[9]);
1196 : }
1197 :
1198 0 : if( CSLCount(papszFields) < 5 )
1199 0 : nDatum = 104; /* WGS84 */
1200 :
1201 0 : CSLDestroy( papszFields );
1202 : }
1203 :
1204 : /*-----------------------------------------------------------------
1205 : * We have a "real" datum name. Try to look it up and get the
1206 : * parameters. If we don't find it just use WGS84.
1207 : *----------------------------------------------------------------*/
1208 : else
1209 : {
1210 : int i;
1211 :
1212 268 : for( i = 0; asDatumInfoList[i].nMapInfoDatumID != -1; i++ )
1213 : {
1214 268 : if( EQUAL(pszWKTDatum,asDatumInfoList[i].pszOGCDatumName) )
1215 : {
1216 4 : nDatum = asDatumInfoList[i].nMapInfoDatumID;
1217 4 : break;
1218 : }
1219 : }
1220 :
1221 4 : if( nDatum == 0 )
1222 0 : nDatum = 104; /* WGS84 */
1223 : }
1224 :
1225 : /*-----------------------------------------------------------------
1226 : * Translate the units
1227 : *----------------------------------------------------------------*/
1228 4 : const char *pszMIFUnits = "m";
1229 :
1230 4 : if( nProjection == 1 )
1231 0 : pszMIFUnits = NULL;
1232 4 : else if( pszLinearUnits == NULL )
1233 0 : pszMIFUnits = "m";
1234 4 : else if( dfLinearConv == 1000.0 )
1235 0 : pszMIFUnits = "km";
1236 4 : else if( dfLinearConv == 0.0254 || EQUAL(pszLinearUnits,"Inch")
1237 : || EQUAL(pszLinearUnits,"IINCH"))
1238 0 : pszMIFUnits = "in";
1239 4 : else if( dfLinearConv == CPLAtof(SRS_UL_FOOT_CONV)
1240 : || EQUAL(pszLinearUnits,SRS_UL_FOOT) )
1241 0 : pszMIFUnits = "ft";
1242 4 : else if( EQUAL(pszLinearUnits,"YARD") || EQUAL(pszLinearUnits,"IYARD")
1243 : || dfLinearConv == 0.9144 )
1244 0 : pszMIFUnits = "yd";
1245 4 : else if( dfLinearConv == 0.001 )
1246 0 : pszMIFUnits = "mm";
1247 4 : else if( dfLinearConv == 0.01 )
1248 0 : pszMIFUnits = "cm";
1249 4 : else if( dfLinearConv == 1.0 )
1250 4 : pszMIFUnits = "m";
1251 0 : else if( dfLinearConv == CPLAtof(SRS_UL_US_FOOT_CONV)
1252 : || EQUAL(pszLinearUnits,SRS_UL_US_FOOT) )
1253 0 : pszMIFUnits = "survey ft";
1254 0 : else if( EQUAL(pszLinearUnits,SRS_UL_NAUTICAL_MILE) )
1255 0 : pszMIFUnits = "nmi";
1256 0 : else if( EQUAL(pszLinearUnits,SRS_UL_LINK)
1257 : || EQUAL(pszLinearUnits,"GUNTERLINK") )
1258 0 : pszMIFUnits = "li";
1259 0 : else if( EQUAL(pszLinearUnits,SRS_UL_CHAIN)
1260 : || EQUAL(pszLinearUnits,"GUNTERCHAIN") )
1261 0 : pszMIFUnits = "ch";
1262 0 : else if( EQUAL(pszLinearUnits,SRS_UL_ROD) )
1263 0 : pszMIFUnits = "rd";
1264 0 : else if( EQUAL(pszLinearUnits,"Mile")
1265 : || EQUAL(pszLinearUnits,"IMILE") )
1266 0 : pszMIFUnits = "mi";
1267 :
1268 : /* -------------------------------------------------------------------- */
1269 : /* Build coordinate system definition. */
1270 : /* -------------------------------------------------------------------- */
1271 : char szCoordSys[256];
1272 :
1273 4 : if( nProjection != 0 )
1274 : {
1275 : sprintf( szCoordSys,
1276 : "Earth Projection %d",
1277 4 : nProjection );
1278 :
1279 : }
1280 : else
1281 : sprintf( szCoordSys,
1282 0 : "NonEarth Units" );
1283 :
1284 : /* -------------------------------------------------------------------- */
1285 : /* Append Datum */
1286 : /* -------------------------------------------------------------------- */
1287 4 : if( nProjection != 0 )
1288 : {
1289 : sprintf( szCoordSys + strlen(szCoordSys),
1290 : ", %d",
1291 4 : nDatum );
1292 :
1293 4 : if( nDatum == 999 || nDatum == 9999 )
1294 : {
1295 : sprintf( szCoordSys + strlen(szCoordSys),
1296 : ", %d, %.15g, %.15g, %.15g",
1297 : nEllipsoid,
1298 0 : adfDatumParm[0], adfDatumParm[1], adfDatumParm[2] );
1299 : }
1300 :
1301 4 : if( nDatum == 9999 )
1302 : {
1303 : sprintf( szCoordSys + strlen(szCoordSys),
1304 : ", %.15g, %.15g, %.15g, %.15g, %.15g",
1305 : adfDatumParm[3], adfDatumParm[4], adfDatumParm[5],
1306 0 : adfDatumParm[6], adfDatumParm[7] );
1307 : }
1308 : }
1309 :
1310 : /* -------------------------------------------------------------------- */
1311 : /* Append units. */
1312 : /* -------------------------------------------------------------------- */
1313 4 : if( nProjection != 1 && pszMIFUnits != NULL )
1314 : {
1315 4 : if( nProjection != 0 )
1316 4 : strcat( szCoordSys, "," );
1317 :
1318 : sprintf( szCoordSys + strlen(szCoordSys),
1319 : " \"%s\"",
1320 4 : pszMIFUnits );
1321 : }
1322 :
1323 : /* -------------------------------------------------------------------- */
1324 : /* Append Projection Parms. */
1325 : /* -------------------------------------------------------------------- */
1326 26 : for( int iParm = 0; iParm < nParmCount; iParm++ )
1327 : sprintf( szCoordSys + strlen(szCoordSys),
1328 : ", %.15g",
1329 22 : parms[iParm] );
1330 :
1331 : /* -------------------------------------------------------------------- */
1332 : /* Report on translation */
1333 : /* -------------------------------------------------------------------- */
1334 4 : char *pszWKT = NULL;
1335 :
1336 4 : poSR->exportToWkt( &pszWKT );
1337 4 : if( pszWKT != NULL )
1338 : {
1339 : CPLDebug( "MITAB",
1340 : "This WKT Projection:\n%s\n\ntranslates to:\n%s\n",
1341 4 : pszWKT, szCoordSys );
1342 4 : CPLFree( pszWKT );
1343 : }
1344 :
1345 4 : return( CPLStrdup( szCoordSys ) );
1346 : }
1347 :
1348 :
1349 : /************************************************************************/
1350 : /* MITABExtractCoordSysBounds */
1351 : /* */
1352 : /* Return TRUE if MIF coordsys string contains a BOUNDS parameter and */
1353 : /* Set x/y min/max values. */
1354 : /************************************************************************/
1355 :
1356 0 : GBool MITABExtractCoordSysBounds( const char * pszCoordSys,
1357 : double &dXMin, double &dYMin,
1358 : double &dXMax, double &dYMax )
1359 :
1360 : {
1361 : char **papszFields;
1362 :
1363 0 : if( pszCoordSys == NULL )
1364 0 : return FALSE;
1365 :
1366 0 : papszFields = CSLTokenizeStringComplex( pszCoordSys, " ,()", TRUE, FALSE );
1367 :
1368 0 : int iBounds = CSLFindString( papszFields, "Bounds" );
1369 :
1370 0 : if (iBounds >= 0 && iBounds + 4 < CSLCount(papszFields))
1371 : {
1372 0 : dXMin = atof(papszFields[++iBounds]);
1373 0 : dYMin = atof(papszFields[++iBounds]);
1374 0 : dXMax = atof(papszFields[++iBounds]);
1375 0 : dYMax = atof(papszFields[++iBounds]);
1376 0 : CSLDestroy( papszFields );
1377 0 : return TRUE;
1378 : }
1379 :
1380 0 : CSLDestroy( papszFields );
1381 0 : return FALSE;
1382 : }
1383 :
1384 :
1385 : /**********************************************************************
1386 : * MITABCoordSys2TABProjInfo()
1387 : *
1388 : * Convert a MIF COORDSYS string into a TABProjInfo structure.
1389 : *
1390 : * Note that it would have been possible to achieve the same by calling
1391 : * TABFile::SetSpatialRef( MITABCoordSys2SpatialRef() ) but this would
1392 : * involve lots of manipulations for cases where only a simple conversion
1393 : * is required.
1394 : *
1395 : * Returns 0 on success, -1 on error.
1396 : **********************************************************************/
1397 0 : int MITABCoordSys2TABProjInfo(const char * pszCoordSys, TABProjInfo *psProj)
1398 :
1399 : {
1400 : char **papszFields;
1401 :
1402 : // Set all fields to zero, equivalent of NonEarth Units "mi"
1403 0 : memset(psProj, 0, sizeof(TABProjInfo));
1404 :
1405 0 : if( pszCoordSys == NULL )
1406 0 : return -1;
1407 :
1408 : /*-----------------------------------------------------------------
1409 : * Parse the passed string into words.
1410 : *----------------------------------------------------------------*/
1411 0 : while(*pszCoordSys == ' ') pszCoordSys++; // Eat leading spaces
1412 0 : if( EQUALN(pszCoordSys,"CoordSys",8) )
1413 0 : pszCoordSys += 9;
1414 :
1415 0 : papszFields = CSLTokenizeStringComplex( pszCoordSys, " ,", TRUE, FALSE );
1416 :
1417 : /*-----------------------------------------------------------------
1418 : * Clip off Bounds information.
1419 : *----------------------------------------------------------------*/
1420 0 : int iBounds = CSLFindString( papszFields, "Bounds" );
1421 :
1422 0 : while( iBounds != -1 && papszFields[iBounds] != NULL )
1423 : {
1424 0 : CPLFree( papszFields[iBounds] );
1425 0 : papszFields[iBounds] = NULL;
1426 0 : iBounds++;
1427 : }
1428 :
1429 : /*-----------------------------------------------------------------
1430 : * Fetch the projection.
1431 : *----------------------------------------------------------------*/
1432 : char **papszNextField;
1433 :
1434 0 : if( CSLCount( papszFields ) >= 3
1435 0 : && EQUAL(papszFields[0],"Earth")
1436 0 : && EQUAL(papszFields[1],"Projection") )
1437 : {
1438 0 : psProj->nProjId = (GByte)atoi(papszFields[2]);
1439 0 : papszNextField = papszFields + 3;
1440 : }
1441 0 : else if (CSLCount( papszFields ) >= 2
1442 0 : && EQUAL(papszFields[0],"NonEarth") )
1443 : {
1444 : // NonEarth Units "..." Bounds (x, y) (x, y)
1445 0 : psProj->nProjId = 0;
1446 0 : papszNextField = papszFields + 2;
1447 :
1448 0 : if( papszNextField[0] != NULL && EQUAL(papszNextField[0],"Units") )
1449 0 : papszNextField++;
1450 : }
1451 : else
1452 : {
1453 : // Invalid projection string ???
1454 0 : if (CSLCount(papszFields) > 0)
1455 : CPLError(CE_Warning, CPLE_IllegalArg,
1456 0 : "Failed parsing CoordSys: '%s'", pszCoordSys);
1457 0 : CSLDestroy(papszFields);
1458 0 : return -1;
1459 : }
1460 :
1461 : /*-----------------------------------------------------------------
1462 : * Fetch the datum information.
1463 : *----------------------------------------------------------------*/
1464 0 : int nDatum = 0;
1465 :
1466 0 : if( psProj->nProjId != 0 && CSLCount(papszNextField) > 0 )
1467 : {
1468 0 : nDatum = atoi(papszNextField[0]);
1469 0 : papszNextField++;
1470 : }
1471 :
1472 0 : if( (nDatum == 999 || nDatum == 9999)
1473 : && CSLCount(papszNextField) >= 4 )
1474 : {
1475 0 : psProj->nEllipsoidId = (GByte)atoi(papszFields[0]);
1476 0 : psProj->dDatumShiftX = atof(papszNextField[1]);
1477 0 : psProj->dDatumShiftY = atof(papszNextField[2]);
1478 0 : psProj->dDatumShiftZ = atof(papszNextField[3]);
1479 0 : papszNextField += 4;
1480 :
1481 0 : if( nDatum == 9999
1482 : && CSLCount(papszNextField) >= 5 )
1483 : {
1484 0 : psProj->adDatumParams[0] = atof(papszNextField[0]);
1485 0 : psProj->adDatumParams[1] = atof(papszNextField[1]);
1486 0 : psProj->adDatumParams[2] = atof(papszNextField[2]);
1487 0 : psProj->adDatumParams[3] = atof(papszNextField[3]);
1488 0 : psProj->adDatumParams[4] = atof(papszNextField[4]);
1489 0 : papszNextField += 5;
1490 : }
1491 : }
1492 0 : else if (nDatum != 999 && nDatum != 9999)
1493 : {
1494 : /*-----------------------------------------------------------------
1495 : * Find the datum, and collect it's parameters if possible.
1496 : *----------------------------------------------------------------*/
1497 : int iDatum;
1498 0 : MapInfoDatumInfo *psDatumInfo = NULL;
1499 :
1500 0 : for(iDatum=0; asDatumInfoList[iDatum].nMapInfoDatumID != -1; iDatum++)
1501 : {
1502 0 : if( asDatumInfoList[iDatum].nMapInfoDatumID == nDatum )
1503 : {
1504 0 : psDatumInfo = asDatumInfoList + iDatum;
1505 0 : break;
1506 : }
1507 : }
1508 :
1509 0 : if( asDatumInfoList[iDatum].nMapInfoDatumID == -1
1510 : && nDatum != 999 && nDatum != 9999 )
1511 : {
1512 : /* use WGS84 */
1513 0 : psDatumInfo = asDatumInfoList + 0;
1514 : }
1515 :
1516 0 : if( psDatumInfo != NULL )
1517 : {
1518 0 : psProj->nEllipsoidId = (GByte)psDatumInfo->nEllipsoid;
1519 0 : psProj->nDatumId = (GInt16)psDatumInfo->nMapInfoDatumID;
1520 0 : psProj->dDatumShiftX = psDatumInfo->dfShiftX;
1521 0 : psProj->dDatumShiftY = psDatumInfo->dfShiftY;
1522 0 : psProj->dDatumShiftZ = psDatumInfo->dfShiftZ;
1523 0 : psProj->adDatumParams[0] = psDatumInfo->dfDatumParm0;
1524 0 : psProj->adDatumParams[1] = psDatumInfo->dfDatumParm1;
1525 0 : psProj->adDatumParams[2] = psDatumInfo->dfDatumParm2;
1526 0 : psProj->adDatumParams[3] = psDatumInfo->dfDatumParm3;
1527 0 : psProj->adDatumParams[4] = psDatumInfo->dfDatumParm4;
1528 : }
1529 : }
1530 :
1531 : /*-----------------------------------------------------------------
1532 : * Fetch the units string.
1533 : *----------------------------------------------------------------*/
1534 0 : if( CSLCount(papszNextField) > 0 )
1535 : {
1536 0 : psProj->nUnitsId = (GByte)TABUnitIdFromString(papszNextField[0]);
1537 0 : papszNextField++;
1538 : }
1539 :
1540 : /*-----------------------------------------------------------------
1541 : * Finally the projection parameters.
1542 : *----------------------------------------------------------------*/
1543 0 : for(int iParam=0; iParam < 6 && CSLCount(papszNextField) > 0; iParam++)
1544 : {
1545 0 : psProj->adProjParams[iParam] = atof(papszNextField[0]);
1546 0 : papszNextField++;
1547 : }
1548 :
1549 0 : return 0;
1550 : }
1551 :
|