1 : /******************************************************************************
2 : * $Id: gxf_proj4.c 10645 2007-01-18 02:22:39Z warmerdam $
3 : *
4 : * Project: GXF Reader
5 : * Purpose: Handle GXF to PROJ.4 projection transformation.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1998, Global Geomatics
10 : * Copyright (c) 1998, Frank Warmerdam
11 : *
12 : * Permission is hereby granted, free of charge, to any person obtaining a
13 : * copy of this software and associated documentation files (the "Software"),
14 : * to deal in the Software without restriction, including without limitation
15 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 : * and/or sell copies of the Software, and to permit persons to whom the
17 : * Software is furnished to do so, subject to the following conditions:
18 : *
19 : * The above copyright notice and this permission notice shall be included
20 : * in all copies or substantial portions of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 : * DEALINGS IN THE SOFTWARE.
29 : ****************************************************************************/
30 :
31 : #include "gxfopen.h"
32 :
33 : CPL_CVSID("$Id: gxf_proj4.c 10645 2007-01-18 02:22:39Z warmerdam $");
34 :
35 : /************************************************************************/
36 : /* GXFGetMapProjectionAsPROJ4() */
37 : /************************************************************************/
38 :
39 : /**
40 : * Return the GXF Projection in PROJ.4 format.
41 : *
42 : * The returned string becomes owned by the caller, and should be freed
43 : * with CPLFree() or VSIFree(). The return value will be "unknown" if
44 : * no projection information is passed.
45 : *
46 : * The mapping of GXF projections to PROJ.4 format is not complete. Please
47 : * see the gxf_proj4.c code to better understand limitations of this
48 : * translation. Noteable PROJ.4 knows little about datums.
49 : *
50 : * For example, the following GXF definitions:
51 : * <pre>
52 : * #UNIT_LENGTH
53 : * m,1
54 : * #MAP_PROJECTION
55 : * "NAD83 / UTM zone 19N"
56 : * "GRS 1980",6378137,0.081819191,0
57 : * "Transverse Mercator",0,-69,0.9996,500000,0
58 : * </pre>
59 : *
60 : * Would translate to:
61 : * <pre>
62 : * +proj=tmerc +lat_0=0 +lon_0=-69 +k=0.9996 +x_0=500000 +y_0=0 +ellps=GRS80
63 : * </pre>
64 : *
65 : * @param hGXF handle to GXF file, as returned by GXFOpen().
66 : *
67 : * @return string containing PROJ.4 projection.
68 : */
69 :
70 0 : char *GXFGetMapProjectionAsPROJ4( GXFHandle hGXF )
71 :
72 : {
73 0 : GXFInfo_t *psGXF = (GXFInfo_t *) hGXF;
74 0 : char **papszMethods = NULL;
75 : char szPROJ4[512];
76 :
77 : /* -------------------------------------------------------------------- */
78 : /* If there was nothing in the file return "unknown". */
79 : /* -------------------------------------------------------------------- */
80 0 : if( CSLCount(psGXF->papszMapProjection) < 2 )
81 0 : return( CPLStrdup( "unknown" ) );
82 :
83 0 : szPROJ4[0] = '\0';
84 :
85 : /* -------------------------------------------------------------------- */
86 : /* Parse the third line, looking for known projection methods. */
87 : /* -------------------------------------------------------------------- */
88 0 : if( psGXF->papszMapProjection[2] != NULL )
89 0 : papszMethods = CSLTokenizeStringComplex(psGXF->papszMapProjection[2],
90 : ",", TRUE, TRUE );
91 :
92 : #ifdef DBMALLOC
93 : malloc_chain_check(1);
94 : #endif
95 :
96 0 : if( papszMethods == NULL
97 0 : || papszMethods[0] == NULL
98 0 : || EQUAL(papszMethods[0],"Geographic") )
99 : {
100 0 : strcat( szPROJ4, "+proj=longlat" );
101 : }
102 :
103 : #ifdef notdef
104 : else if( EQUAL(papszMethods[0],"Lambert Conic Conformal (1SP)")
105 : && CSLCount(papszMethods) > 5 )
106 : {
107 : /* notdef: It isn't clear that this 1SP + scale method is even
108 : supported by PROJ.4
109 : Later note: It is not. */
110 :
111 : strcat( szPROJ4, "+proj=lcc" );
112 :
113 : strcat( szPROJ4, " +lat_0=" );
114 : strcat( szPROJ4, papszMethods[1] );
115 :
116 : strcat( szPROJ4, " +lon_0=" );
117 : strcat( szPROJ4, papszMethods[2] );
118 :
119 : strcat( szPROJ4, " +k=" );
120 : strcat( szPROJ4, papszMethods[3] );
121 :
122 : strcat( szPROJ4, " +x_0=" );
123 : strcat( szPROJ4, papszMethods[4] );
124 :
125 : strcat( szPROJ4, " +y_0=" );
126 : strcat( szPROJ4, papszMethods[5] );
127 : }
128 : #endif
129 0 : else if( EQUAL(papszMethods[0],"Lambert Conic Conformal (2SP)")
130 0 : || EQUAL(papszMethods[0],"Lambert Conformal (2SP Belgium)") )
131 : {
132 : /* notdef: Note we are apparently losing whatever makes the
133 : Belgium variant different than normal LCC, but hopefully
134 : they are close! */
135 :
136 0 : strcat( szPROJ4, "+proj=lcc" );
137 :
138 0 : if( CSLCount(papszMethods) > 1 )
139 : {
140 0 : strcat( szPROJ4, " +lat_1=" );
141 0 : strcat( szPROJ4, papszMethods[1] );
142 : }
143 :
144 0 : if( CSLCount(papszMethods) > 2 )
145 : {
146 0 : strcat( szPROJ4, " +lat_2=" );
147 0 : strcat( szPROJ4, papszMethods[2] );
148 : }
149 :
150 0 : if( CSLCount(papszMethods) > 3 )
151 : {
152 0 : strcat( szPROJ4, " +lat_0=" );
153 0 : strcat( szPROJ4, papszMethods[3] );
154 : }
155 :
156 0 : if( CSLCount(papszMethods) > 4 )
157 : {
158 0 : strcat( szPROJ4, " +lon_0=" );
159 0 : strcat( szPROJ4, papszMethods[4] );
160 : }
161 :
162 0 : if( CSLCount(papszMethods) > 5 )
163 : {
164 0 : strcat( szPROJ4, " +x_0=" );
165 0 : strcat( szPROJ4, papszMethods[5] );
166 : }
167 :
168 0 : if( CSLCount(papszMethods) > 6 )
169 : {
170 0 : strcat( szPROJ4, " +y_0=" );
171 0 : strcat( szPROJ4, papszMethods[6] );
172 : }
173 : }
174 :
175 0 : else if( EQUAL(papszMethods[0],"Mercator (1SP)")
176 0 : && CSLCount(papszMethods) > 5 )
177 : {
178 : /* notdef: it isn't clear that +proj=merc support a scale of other
179 : than 1.0 in PROJ.4 */
180 :
181 0 : strcat( szPROJ4, "+proj=merc" );
182 :
183 0 : strcat( szPROJ4, " +lat_ts=" );
184 0 : strcat( szPROJ4, papszMethods[1] );
185 :
186 0 : strcat( szPROJ4, " +lon_0=" );
187 0 : strcat( szPROJ4, papszMethods[2] );
188 :
189 0 : strcat( szPROJ4, " +k=" );
190 0 : strcat( szPROJ4, papszMethods[3] );
191 :
192 0 : strcat( szPROJ4, " +x_0=" );
193 0 : strcat( szPROJ4, papszMethods[4] );
194 :
195 0 : strcat( szPROJ4, " +y_0=" );
196 0 : strcat( szPROJ4, papszMethods[5] );
197 : }
198 :
199 0 : else if( EQUAL(papszMethods[0],"Mercator (2SP)")
200 0 : && CSLCount(papszMethods) > 4 )
201 : {
202 : /* notdef: it isn't clear that +proj=merc support a scale of other
203 : than 1.0 in PROJ.4 */
204 :
205 0 : strcat( szPROJ4, "+proj=merc" );
206 :
207 0 : strcat( szPROJ4, " +lat_ts=" );
208 0 : strcat( szPROJ4, papszMethods[1] );
209 :
210 0 : strcat( szPROJ4, " +lon_0=" );
211 0 : strcat( szPROJ4, papszMethods[2] );
212 :
213 0 : strcat( szPROJ4, " +x_0=" );
214 0 : strcat( szPROJ4, papszMethods[3] );
215 :
216 0 : strcat( szPROJ4, " +y_0=" );
217 0 : strcat( szPROJ4, papszMethods[4] );
218 : }
219 :
220 0 : else if( EQUAL(papszMethods[0],"Hotine Oblique Mercator")
221 0 : && CSLCount(papszMethods) > 7 )
222 : {
223 : /* Note that only the second means of specifying omerc is supported
224 : by this code in GXF. */
225 0 : strcat( szPROJ4, "+proj=omerc" );
226 :
227 0 : strcat( szPROJ4, " +lat_0=" );
228 0 : strcat( szPROJ4, papszMethods[1] );
229 :
230 0 : strcat( szPROJ4, " +lonc=" );
231 0 : strcat( szPROJ4, papszMethods[2] );
232 :
233 0 : strcat( szPROJ4, " +alpha=" );
234 0 : strcat( szPROJ4, papszMethods[3] );
235 :
236 0 : if( atof(papszMethods[4]) < 0.00001 )
237 : {
238 0 : strcat( szPROJ4, " +not_rot" );
239 : }
240 : else
241 : {
242 : #ifdef notdef
243 : if( atof(papszMethods[4]) + atof(papszMethods[3]) < 0.00001 )
244 : /* ok */;
245 : else
246 : /* notdef: no way to specify arbitrary angles! */;
247 : #endif
248 : }
249 :
250 0 : strcat( szPROJ4, " +k=" );
251 0 : strcat( szPROJ4, papszMethods[5] );
252 :
253 0 : strcat( szPROJ4, " +x_0=" );
254 0 : strcat( szPROJ4, papszMethods[6] );
255 :
256 0 : strcat( szPROJ4, " +y_0=" );
257 0 : strcat( szPROJ4, papszMethods[7] );
258 : }
259 :
260 0 : else if( EQUAL(papszMethods[0],"Laborde Oblique Mercator")
261 0 : && CSLCount(papszMethods) > 6 )
262 : {
263 0 : strcat( szPROJ4, "+proj=labrd" );
264 :
265 0 : strcat( szPROJ4, " +lat_0=" );
266 0 : strcat( szPROJ4, papszMethods[1] );
267 :
268 0 : strcat( szPROJ4, " +lon_0=" );
269 0 : strcat( szPROJ4, papszMethods[2] );
270 :
271 0 : strcat( szPROJ4, " +azi=" );
272 0 : strcat( szPROJ4, papszMethods[3] );
273 :
274 0 : strcat( szPROJ4, " +k=" );
275 0 : strcat( szPROJ4, papszMethods[4] );
276 :
277 0 : strcat( szPROJ4, " +x_0=" );
278 0 : strcat( szPROJ4, papszMethods[5] );
279 :
280 0 : strcat( szPROJ4, " +y_0=" );
281 0 : strcat( szPROJ4, papszMethods[6] );
282 : }
283 :
284 0 : else if( EQUAL(papszMethods[0],"New Zealand Map Grid")
285 0 : && CSLCount(papszMethods) > 4 )
286 : {
287 0 : strcat( szPROJ4, "+proj=nzmg" );
288 :
289 0 : strcat( szPROJ4, " +lat_0=" );
290 0 : strcat( szPROJ4, papszMethods[1] );
291 :
292 0 : strcat( szPROJ4, " +lon_0=" );
293 0 : strcat( szPROJ4, papszMethods[2] );
294 :
295 0 : strcat( szPROJ4, " +x_0=" );
296 0 : strcat( szPROJ4, papszMethods[3] );
297 :
298 0 : strcat( szPROJ4, " +y_0=" );
299 0 : strcat( szPROJ4, papszMethods[4] );
300 : }
301 :
302 0 : else if( EQUAL(papszMethods[0],"New Zealand Map Grid")
303 0 : && CSLCount(papszMethods) > 4 )
304 : {
305 0 : strcat( szPROJ4, "+proj=nzmg" );
306 :
307 0 : strcat( szPROJ4, " +lat_0=" );
308 0 : strcat( szPROJ4, papszMethods[1] );
309 :
310 0 : strcat( szPROJ4, " +lon_0=" );
311 0 : strcat( szPROJ4, papszMethods[2] );
312 :
313 0 : strcat( szPROJ4, " +x_0=" );
314 0 : strcat( szPROJ4, papszMethods[3] );
315 :
316 0 : strcat( szPROJ4, " +y_0=" );
317 0 : strcat( szPROJ4, papszMethods[4] );
318 : }
319 :
320 0 : else if( EQUAL(papszMethods[0],"Oblique Stereographic")
321 0 : && CSLCount(papszMethods) > 5 )
322 : {
323 : /* there is an option to produce +lat_ts, which we ignore */
324 :
325 0 : strcat( szPROJ4, "+proj=stere" );
326 :
327 0 : strcat( szPROJ4, " +lat_0=45" );
328 :
329 0 : strcat( szPROJ4, " +lat_ts=" );
330 0 : strcat( szPROJ4, papszMethods[1] );
331 :
332 0 : strcat( szPROJ4, " +lon_0=" );
333 0 : strcat( szPROJ4, papszMethods[2] );
334 :
335 0 : strcat( szPROJ4, " +k=" );
336 0 : strcat( szPROJ4, papszMethods[3] );
337 :
338 0 : strcat( szPROJ4, " +x_0=" );
339 0 : strcat( szPROJ4, papszMethods[4] );
340 :
341 0 : strcat( szPROJ4, " +y_0=" );
342 0 : strcat( szPROJ4, papszMethods[5] );
343 : }
344 :
345 0 : else if( EQUAL(papszMethods[0],"Polar Stereographic")
346 0 : && CSLCount(papszMethods) > 5 )
347 : {
348 : /* there is an option to produce +lat_ts, which we ignore */
349 :
350 0 : strcat( szPROJ4, "+proj=stere" );
351 :
352 0 : strcat( szPROJ4, " +lat_0=90" );
353 :
354 0 : strcat( szPROJ4, " +lat_ts=" );
355 0 : strcat( szPROJ4, papszMethods[1] );
356 :
357 0 : strcat( szPROJ4, " +lon_0=" );
358 0 : strcat( szPROJ4, papszMethods[2] );
359 :
360 0 : strcat( szPROJ4, " +k=" );
361 0 : strcat( szPROJ4, papszMethods[3] );
362 :
363 0 : strcat( szPROJ4, " +x_0=" );
364 0 : strcat( szPROJ4, papszMethods[4] );
365 :
366 0 : strcat( szPROJ4, " +y_0=" );
367 0 : strcat( szPROJ4, papszMethods[5] );
368 : }
369 :
370 0 : else if( EQUAL(papszMethods[0],"Swiss Oblique Cylindrical")
371 0 : && CSLCount(papszMethods) > 4 )
372 : {
373 : /* notdef: geotiff's geo_ctrans.inc says this is the same as
374 : ObliqueMercator_Rosenmund, which GG's geotiff support just
375 : maps directly to +proj=omerc, though I find that questionable. */
376 :
377 0 : strcat( szPROJ4, "+proj=omerc" );
378 :
379 0 : strcat( szPROJ4, " +lat_0=" );
380 0 : strcat( szPROJ4, papszMethods[1] );
381 :
382 0 : strcat( szPROJ4, " +lonc=" );
383 0 : strcat( szPROJ4, papszMethods[2] );
384 :
385 0 : strcat( szPROJ4, " +x_0=" );
386 0 : strcat( szPROJ4, papszMethods[3] );
387 :
388 0 : strcat( szPROJ4, " +y_0=" );
389 0 : strcat( szPROJ4, papszMethods[4] );
390 : }
391 :
392 0 : else if( EQUAL(papszMethods[0],"Transverse Mercator")
393 0 : && CSLCount(papszMethods) > 5 )
394 : {
395 : /* notdef: geotiff's geo_ctrans.inc says this is the same as
396 : ObliqueMercator_Rosenmund, which GG's geotiff support just
397 : maps directly to +proj=omerc, though I find that questionable. */
398 :
399 0 : strcat( szPROJ4, "+proj=tmerc" );
400 :
401 0 : strcat( szPROJ4, " +lat_0=" );
402 0 : strcat( szPROJ4, papszMethods[1] );
403 :
404 0 : strcat( szPROJ4, " +lon_0=" );
405 0 : strcat( szPROJ4, papszMethods[2] );
406 :
407 0 : strcat( szPROJ4, " +k=" );
408 0 : strcat( szPROJ4, papszMethods[3] );
409 :
410 0 : strcat( szPROJ4, " +x_0=" );
411 0 : strcat( szPROJ4, papszMethods[4] );
412 :
413 0 : strcat( szPROJ4, " +y_0=" );
414 0 : strcat( szPROJ4, papszMethods[5] );
415 : }
416 :
417 0 : else if( EQUAL(papszMethods[0],"Transverse Mercator (South Oriented)")
418 0 : && CSLCount(papszMethods) > 5 )
419 : {
420 : /* notdef: I don't know how south oriented is different from
421 : normal, and I don't find any mention of it in Geotiff;s geo_ctrans.
422 : Translating as tmerc, but that is presumably wrong. */
423 :
424 0 : strcat( szPROJ4, "+proj=tmerc" );
425 :
426 0 : strcat( szPROJ4, " +lat_0=" );
427 0 : strcat( szPROJ4, papszMethods[1] );
428 :
429 0 : strcat( szPROJ4, " +lon_0=" );
430 0 : strcat( szPROJ4, papszMethods[2] );
431 :
432 0 : strcat( szPROJ4, " +k=" );
433 0 : strcat( szPROJ4, papszMethods[3] );
434 :
435 0 : strcat( szPROJ4, " +x_0=" );
436 0 : strcat( szPROJ4, papszMethods[4] );
437 :
438 0 : strcat( szPROJ4, " +y_0=" );
439 0 : strcat( szPROJ4, papszMethods[5] );
440 : }
441 :
442 0 : else if( EQUAL(papszMethods[0],"*Equidistant Conic")
443 0 : && CSLCount(papszMethods) > 6 )
444 : {
445 0 : strcat( szPROJ4, "+proj=eqdc" );
446 :
447 0 : strcat( szPROJ4, " +lat_1=" );
448 0 : strcat( szPROJ4, papszMethods[1] );
449 :
450 0 : strcat( szPROJ4, " +lat_2=" );
451 0 : strcat( szPROJ4, papszMethods[2] );
452 :
453 0 : strcat( szPROJ4, " +lat_0=" );
454 0 : strcat( szPROJ4, papszMethods[3] );
455 :
456 0 : strcat( szPROJ4, " +lon_0=" );
457 0 : strcat( szPROJ4, papszMethods[4] );
458 :
459 0 : strcat( szPROJ4, " +x_0=" );
460 0 : strcat( szPROJ4, papszMethods[5] );
461 :
462 0 : strcat( szPROJ4, " +y_0=" );
463 0 : strcat( szPROJ4, papszMethods[6] );
464 : }
465 :
466 0 : else if( EQUAL(papszMethods[0],"*Polyconic")
467 0 : && CSLCount(papszMethods) > 5 )
468 : {
469 0 : strcat( szPROJ4, "+proj=poly" );
470 :
471 0 : strcat( szPROJ4, " +lat_0=" );
472 0 : strcat( szPROJ4, papszMethods[1] );
473 :
474 0 : strcat( szPROJ4, " +lon_0=" );
475 0 : strcat( szPROJ4, papszMethods[2] );
476 :
477 : #ifdef notdef
478 : /*not supported by PROJ.4 */
479 : strcat( szPROJ4, " +k=" );
480 : strcat( szPROJ4, papszMethods[3] );
481 : #endif
482 0 : strcat( szPROJ4, " +x_0=" );
483 0 : strcat( szPROJ4, papszMethods[4] );
484 :
485 0 : strcat( szPROJ4, " +y_0=" );
486 0 : strcat( szPROJ4, papszMethods[5] );
487 : }
488 :
489 : else
490 : {
491 0 : strcat( szPROJ4, "unknown" );
492 : }
493 :
494 0 : CSLDestroy( papszMethods );
495 :
496 : /* -------------------------------------------------------------------- */
497 : /* Now get the ellipsoid parameters. For a bunch of common */
498 : /* ones we preserve the name. For the rest we just carry over */
499 : /* the parameters. */
500 : /* -------------------------------------------------------------------- */
501 0 : if( CSLCount(psGXF->papszMapProjection) > 1 )
502 : {
503 : char **papszTokens;
504 :
505 0 : papszTokens = CSLTokenizeStringComplex(psGXF->papszMapProjection[1],
506 : ",", TRUE, TRUE );
507 :
508 :
509 0 : if( EQUAL(papszTokens[0],"WGS 84") )
510 0 : strcat( szPROJ4, " +ellps=WGS84" );
511 0 : else if( EQUAL(papszTokens[0],"*WGS 72") )
512 0 : strcat( szPROJ4, " +ellps=WGS72" );
513 0 : else if( EQUAL(papszTokens[0],"*WGS 66") )
514 0 : strcat( szPROJ4, " +ellps=WGS66" );
515 0 : else if( EQUAL(papszTokens[0],"*WGS 60") )
516 0 : strcat( szPROJ4, " +ellps=WGS60" );
517 0 : else if( EQUAL(papszTokens[0],"Clarke 1866") )
518 0 : strcat( szPROJ4, " +ellps=clrk66" );
519 0 : else if( EQUAL(papszTokens[0],"Clarke 1880") )
520 0 : strcat( szPROJ4, " +ellps=clrk80" );
521 0 : else if( EQUAL(papszTokens[0],"GRS 1980") )
522 0 : strcat( szPROJ4, " +ellps=GRS80" );
523 0 : else if( CSLCount( papszTokens ) > 2 )
524 : {
525 0 : sprintf( szPROJ4+strlen(szPROJ4),
526 : " +a=%s +e=%s",
527 0 : papszTokens[1], papszTokens[2] );
528 : }
529 : }
530 :
531 : /* -------------------------------------------------------------------- */
532 : /* Extract the units specification. */
533 : /* -------------------------------------------------------------------- */
534 0 : if( psGXF->pszUnitName != NULL )
535 : {
536 0 : if( EQUAL(psGXF->pszUnitName,"ft") )
537 : {
538 0 : strcat( szPROJ4, " +units=ft" );
539 : }
540 0 : else if( EQUAL(psGXF->pszUnitName,"ftUS") )
541 : {
542 0 : strcat( szPROJ4, " +units=us-ft" );
543 : }
544 0 : else if( EQUAL(psGXF->pszUnitName,"km") )
545 : {
546 0 : strcat( szPROJ4, " +units=km" );
547 : }
548 0 : else if( EQUAL(psGXF->pszUnitName,"mm") )
549 : {
550 0 : strcat( szPROJ4, " +units=mm" );
551 : }
552 0 : else if( EQUAL(psGXF->pszUnitName,"in") )
553 : {
554 0 : strcat( szPROJ4, " +units=in" );
555 : }
556 0 : else if( EQUAL(psGXF->pszUnitName,"ftInd") )
557 : {
558 0 : strcat( szPROJ4, " +units=ind-ft" );
559 : }
560 0 : else if( EQUAL(psGXF->pszUnitName,"lk") )
561 : {
562 0 : strcat( szPROJ4, " +units=link" );
563 : }
564 : }
565 :
566 0 : return( CPLStrdup( szPROJ4 ) );
567 : }
568 :
569 :
570 : /************************************************************************/
571 : /* GXFGetPROJ4Position() */
572 : /* */
573 : /* Get the same information as GXFGetPosition(), but adjust */
574 : /* to units to meters if we don't ``know'' the indicated */
575 : /* units. */
576 : /************************************************************************/
577 :
578 0 : CPLErr GXFGetPROJ4Position( GXFHandle hGXF,
579 : double * pdfXOrigin, double * pdfYOrigin,
580 : double * pdfXPixelSize, double * pdfYPixelSize,
581 : double * pdfRotation )
582 :
583 : {
584 0 : GXFInfo_t *psGXF = (GXFInfo_t *) hGXF;
585 : char *pszProj;
586 :
587 : /* -------------------------------------------------------------------- */
588 : /* Get the raw position. */
589 : /* -------------------------------------------------------------------- */
590 0 : if( GXFGetPosition( hGXF,
591 : pdfXOrigin, pdfYOrigin,
592 : pdfXPixelSize, pdfYPixelSize,
593 : pdfRotation ) == CE_Failure )
594 0 : return( CE_Failure );
595 :
596 : /* -------------------------------------------------------------------- */
597 : /* Do we know the units in PROJ.4? Get the PROJ.4 string, and */
598 : /* check for a +units definition. */
599 : /* -------------------------------------------------------------------- */
600 0 : pszProj = GXFGetMapProjectionAsPROJ4( hGXF );
601 0 : if( strstr(pszProj,"+unit") == NULL && psGXF->pszUnitName != NULL )
602 : {
603 0 : if( pdfXOrigin != NULL )
604 0 : *pdfXOrigin *= psGXF->dfUnitToMeter;
605 0 : if( pdfYOrigin != NULL )
606 0 : *pdfYOrigin *= psGXF->dfUnitToMeter;
607 0 : if( pdfXPixelSize != NULL )
608 0 : *pdfXPixelSize *= psGXF->dfUnitToMeter;
609 0 : if( pdfYPixelSize != NULL )
610 0 : *pdfYPixelSize *= psGXF->dfUnitToMeter;
611 : }
612 0 : CPLFree( pszProj );
613 :
614 0 : return( CE_None );
615 : }
|