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