1 : /******************************************************************************
2 : * $Id: gxf_ogcwkt.c 16107 2009-01-18 09:43:05Z rouault $
3 : *
4 : * Project: GXF Reader
5 : * Purpose: Handle GXF to OGC WKT projection transformation.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1999, Frank Warmerdam
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "gxfopen.h"
31 :
32 : CPL_CVSID("$Id: gxf_ogcwkt.c 16107 2009-01-18 09:43:05Z rouault $");
33 :
34 : /* -------------------------------------------------------------------- */
35 : /* the following #defines come from ogr_spatialref.h in the GDAL/OGR */
36 : /* distribution (see http://gdal.velocet.ca/projects/opengis) and */
37 : /* should be kept in sync with that file. */
38 : /* -------------------------------------------------------------------- */
39 :
40 : #define SRS_PT_ALBERS_CONIC_EQUAL_AREA \
41 : "Albers_Conic_Equal_Area"
42 : #define SRS_PT_AZIMUTHAL_EQUIDISTANT "Azimuthal_Equidistant"
43 : #define SRS_PT_CASSINI_SOLDNER "Cassini_Soldner"
44 : #define SRS_PT_CYLINDRICAL_EQUAL_AREA "Cylindrical_Equal_Area"
45 : #define SRS_PT_ECKERT_IV "Eckert_IV"
46 : #define SRS_PT_ECKERT_VI "Eckert_VI"
47 : #define SRS_PT_EQUIDISTANT_CONIC "Equidistant_Conic"
48 : #define SRS_PT_EQUIRECTANGULAR "Equirectangular"
49 : #define SRS_PT_GALL_STEREOGRAPHIC "Gall_Stereographic"
50 : #define SRS_PT_GNOMONIC "Gnomonic"
51 : #define SRS_PT_HOTINE_OBLIQUE_MERCATOR \
52 : "Hotine_Oblique_Mercator"
53 : #define SRS_PT_LABORDE_OBLIQUE_MERCATOR \
54 : "Laborde_Oblique_Mercator"
55 : #define SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP \
56 : "Lambert_Conformal_Conic_1SP"
57 : #define SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP \
58 : "Lambert_Conformal_Conic_2SP"
59 : #define SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM \
60 : "Lambert_Conformal_Conic_2SP_Belgium"
61 : #define SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA \
62 : "Lambert_Azimuthal_Equal_Area"
63 : #define SRS_PT_MERCATOR_1SP "Mercator_1SP"
64 : #define SRS_PT_MERCATOR_2SP "Mercator_2SP"
65 : #define SRS_PT_MILLER_CYLINDRICAL "Miller_Cylindrical"
66 : #define SRS_PT_MOLLWEIDE "Mollweide"
67 : #define SRS_PT_NEW_ZEALAND_MAP_GRID \
68 : "New_Zealand_Map_Grid"
69 : #define SRS_PT_OBLIQUE_STEREOGRAPHIC \
70 : "Oblique_Stereographic"
71 : #define SRS_PT_ORTHOGRAPHIC "Orthographic"
72 : #define SRS_PT_POLAR_STEREOGRAPHIC \
73 : "Polar_Stereographic"
74 : #define SRS_PT_POLYCONIC "Polyconic"
75 : #define SRS_PT_ROBINSON "Robinson"
76 : #define SRS_PT_SINUSOIDAL "Sinusoidal"
77 : #define SRS_PT_STEREOGRAPHIC "Stereographic"
78 : #define SRS_PT_SWISS_OBLIQUE_CYLINDRICAL \
79 : "Swiss_Oblique_Cylindrical"
80 : #define SRS_PT_TRANSVERSE_MERCATOR \
81 : "Transverse_Mercator"
82 : #define SRS_PT_TRANSVERSE_MERCATOR_SOUTH_ORIENTED \
83 : "Transverse_Mercator_South_Orientated"
84 : #define SRS_PT_TUNISIA_MINING_GRID \
85 : "Tunisia_Mining_Grid"
86 : #define SRS_PT_VANDERGRINTEN "VanDerGrinten"
87 :
88 : #define SRS_PP_CENTRAL_MERIDIAN "central_meridian"
89 : #define SRS_PP_SCALE_FACTOR "scale_factor"
90 : #define SRS_PP_STANDARD_PARALLEL_1 "standard_parallel_1"
91 : #define SRS_PP_STANDARD_PARALLEL_2 "standard_parallel_2"
92 : #define SRS_PP_LONGITUDE_OF_CENTER "longitude_of_center"
93 : #define SRS_PP_LATITUDE_OF_CENTER "latitude_of_center"
94 : #define SRS_PP_LONGITUDE_OF_ORIGIN "longitude_of_origin"
95 : #define SRS_PP_LATITUDE_OF_ORIGIN "latitude_of_origin"
96 : #define SRS_PP_FALSE_EASTING "false_easting"
97 : #define SRS_PP_FALSE_NORTHING "false_northing"
98 : #define SRS_PP_AZIMUTH "azimuth"
99 : #define SRS_PP_LONGITUDE_OF_POINT_1 "longitude_of_point_1"
100 : #define SRS_PP_LATITUDE_OF_POINT_1 "latitude_of_point_1"
101 : #define SRS_PP_LONGITUDE_OF_POINT_2 "longitude_of_point_2"
102 : #define SRS_PP_LATITUDE_OF_POINT_2 "latitude_of_point_2"
103 : #define SRS_PP_LONGITUDE_OF_POINT_3 "longitude_of_point_3"
104 : #define SRS_PP_LATITUDE_OF_POINT_3 "latitude_of_point_3"
105 : #define SRS_PP_RECTIFIED_GRID_ANGLE "rectified_grid_angle"
106 :
107 : /* -------------------------------------------------------------------- */
108 : /* This table was copied from gt_wkt_srs.cpp in the libgeotiff */
109 : /* distribution. Please keep changes in sync. */
110 : /* -------------------------------------------------------------------- */
111 : static char *papszDatumEquiv[] =
112 : {
113 : "Militar_Geographische_Institut",
114 : "Militar_Geographische_Institute",
115 : "World_Geodetic_System_1984",
116 : "WGS_1984",
117 : "WGS_72_Transit_Broadcast_Ephemeris",
118 : "WGS_1972_Transit_Broadcast_Ephemeris",
119 : "World_Geodetic_System_1972",
120 : "WGS_1972",
121 : "European_Terrestrial_Reference_System_89",
122 : "European_Reference_System_1989",
123 : NULL
124 : };
125 :
126 : /************************************************************************/
127 : /* WKTMassageDatum() */
128 : /* */
129 : /* Massage an EPSG datum name into WMT format. Also transform */
130 : /* specific exception cases into WKT versions. */
131 : /* */
132 : /* This function was copied from the gt_wkt_srs.cpp file in the */
133 : /* libgeotiff distribution. Please keep changes in sync. */
134 : /************************************************************************/
135 :
136 5 : static void WKTMassageDatum( char ** ppszDatum )
137 :
138 : {
139 : int i, j;
140 5 : char *pszDatum = *ppszDatum;
141 :
142 : /* -------------------------------------------------------------------- */
143 : /* Translate non-alphanumeric values to underscores. */
144 : /* -------------------------------------------------------------------- */
145 45 : for( i = 0; pszDatum[i] != '\0'; i++ )
146 : {
147 110 : if( !(pszDatum[i] >= 'A' && pszDatum[i] <= 'Z')
148 25 : && !(pszDatum[i] >= 'a' && pszDatum[i] <= 'z')
149 45 : && !(pszDatum[i] >= '0' && pszDatum[i] <= '9') )
150 : {
151 5 : pszDatum[i] = '_';
152 : }
153 : }
154 :
155 : /* -------------------------------------------------------------------- */
156 : /* Remove repeated and trailing underscores. */
157 : /* -------------------------------------------------------------------- */
158 40 : for( i = 1, j = 0; pszDatum[i] != '\0'; i++ )
159 : {
160 35 : if( pszDatum[j] == '_' && pszDatum[i] == '_' )
161 0 : continue;
162 :
163 35 : pszDatum[++j] = pszDatum[i];
164 : }
165 5 : if( pszDatum[j] == '_' )
166 0 : pszDatum[j] = '\0';
167 : else
168 5 : pszDatum[j+1] = '\0';
169 :
170 : /* -------------------------------------------------------------------- */
171 : /* Search for datum equivelences. Specific massaged names get */
172 : /* mapped to OpenGIS specified names. */
173 : /* -------------------------------------------------------------------- */
174 30 : for( i = 0; papszDatumEquiv[i] != NULL; i += 2 )
175 : {
176 25 : if( EQUAL(*ppszDatum,papszDatumEquiv[i]) )
177 : {
178 0 : CPLFree( *ppszDatum );
179 0 : *ppszDatum = CPLStrdup( papszDatumEquiv[i+1] );
180 0 : break;
181 : }
182 : }
183 5 : }
184 :
185 : /************************************************************************/
186 : /* OGCWKTSetProj() */
187 : /************************************************************************/
188 :
189 4 : static void OGCWKTSetProj( char * pszProjection, char ** papszMethods,
190 : const char * pszTransformName,
191 : const char * pszParm1,
192 : const char * pszParm2,
193 : const char * pszParm3,
194 : const char * pszParm4,
195 : const char * pszParm5,
196 : const char * pszParm6,
197 : const char * pszParm7 )
198 :
199 : {
200 4 : int iParm, nCount = CSLCount(papszMethods);
201 : const char *apszParmNames[8];
202 :
203 4 : apszParmNames[0] = pszParm1;
204 4 : apszParmNames[1] = pszParm2;
205 4 : apszParmNames[2] = pszParm3;
206 4 : apszParmNames[3] = pszParm4;
207 4 : apszParmNames[4] = pszParm5;
208 4 : apszParmNames[5] = pszParm6;
209 4 : apszParmNames[6] = pszParm7;
210 4 : apszParmNames[7] = NULL;
211 :
212 4 : sprintf( pszProjection,
213 : "PROJECTION[\"%s\"]",
214 : pszTransformName );
215 :
216 24 : for( iParm = 0; iParm < nCount-1 && apszParmNames[iParm] != NULL; iParm++ )
217 : {
218 20 : sprintf( pszProjection + strlen(pszProjection),
219 : ",PARAMETER[\"%s\",%s]",
220 : apszParmNames[iParm],
221 20 : papszMethods[iParm+1] );
222 : }
223 4 : }
224 :
225 :
226 : /************************************************************************/
227 : /* GXFGetMapProjectionAsOGCWKT() */
228 : /************************************************************************/
229 :
230 : /**
231 : * Return the GXF Projection in OpenGIS Well Known Text format.
232 : *
233 : * The returned string becomes owned by the caller, and should be freed
234 : * with CPLFree() or VSIFree(). The return value will be "" if
235 : * no projection information is passed.
236 : *
237 : * The mapping of GXF projections to OGC WKT format is not complete. Please
238 : * see the gxf_ogcwkt.c code to better understand limitations of this
239 : * translation. More information about OGC WKT format can be found in
240 : * the OpenGIS Simple Features specification for OLEDB/COM found on the
241 : * OpenGIS web site at <a href="http://www.opengis.org/">www.opengis.org</a>.
242 : * The translation uses some code cribbed from the OGR library, about which
243 : * more can be learned from <a href="http://gdal.velocet.ca/projects/opengis/">
244 : * http://gdal.velocet.ca/projects/opengis/</a>.
245 : *
246 : * For example, the following GXF definitions:
247 : * <pre>
248 : * #UNIT_LENGTH
249 : * m,1
250 : * #MAP_PROJECTION
251 : * "NAD83 / UTM zone 19N"
252 : * "GRS 1980",6378137,0.081819191,0
253 : * "Transverse Mercator",0,-69,0.9996,500000,0
254 : * </pre>
255 : *
256 : * Would translate to (without the nice formatting):
257 : * <pre>
258 : PROJCS["NAD83 / UTM zone 19N",
259 : GEOGCS["GRS 1980",
260 : DATUM["GRS_1980",
261 : SPHEROID["GRS 1980",6378137,298.257222413684]],
262 : PRIMEM["unnamed",0],
263 : UNIT["degree",0.0174532925199433]],
264 : PROJECTION["Transverse_Mercator"],
265 : PARAMETER["latitude_of_origin",0],
266 : PARAMETER["central_meridian",-69],
267 : PARAMETER["scale_factor",0.9996],
268 : PARAMETER["false_easting",500000],
269 : PARAMETER["false_northing",0],
270 : UNIT["m",1]]
271 : * </pre>
272 : *
273 : * @param hGXF handle to GXF file, as returned by GXFOpen().
274 : *
275 : * @return string containing OGC WKT projection.
276 : */
277 :
278 7 : char *GXFGetMapProjectionAsOGCWKT( GXFHandle hGXF )
279 :
280 : {
281 7 : GXFInfo_t *psGXF = (GXFInfo_t *) hGXF;
282 7 : char **papszMethods = NULL;
283 : char szWKT[1024];
284 : char szGCS[512];
285 : char szProjection[512];
286 :
287 : /* -------------------------------------------------------------------- */
288 : /* If there was nothing in the file return "unknown". */
289 : /* -------------------------------------------------------------------- */
290 7 : if( CSLCount(psGXF->papszMapProjection) < 2 )
291 2 : return( CPLStrdup( "" ) );
292 :
293 5 : strcpy( szWKT, "" );
294 5 : strcpy( szGCS, "" );
295 5 : strcpy( szProjection, "" );
296 :
297 : /* -------------------------------------------------------------------- */
298 : /* Parse the third line, looking for known projection methods. */
299 : /* -------------------------------------------------------------------- */
300 5 : if( psGXF->papszMapProjection[2] != NULL )
301 5 : papszMethods = CSLTokenizeStringComplex(psGXF->papszMapProjection[2],
302 : ",", TRUE, TRUE );
303 :
304 : #ifdef DBMALLOC
305 : malloc_chain_check(1);
306 : #endif
307 :
308 : /* -------------------------------------------------------------------- */
309 : /* Create the PROJCS. */
310 : /* -------------------------------------------------------------------- */
311 14 : if( papszMethods == NULL
312 5 : || papszMethods[0] == NULL
313 4 : || EQUAL(papszMethods[0],"Geographic") )
314 : {
315 : /* do nothing */
316 : }
317 :
318 4 : else if( EQUAL(papszMethods[0],"Lambert Conic Conformal (1SP)") )
319 : {
320 0 : OGCWKTSetProj( szProjection, papszMethods,
321 : SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP,
322 : SRS_PP_LATITUDE_OF_ORIGIN,
323 : SRS_PP_CENTRAL_MERIDIAN,
324 : SRS_PP_SCALE_FACTOR,
325 : SRS_PP_FALSE_EASTING,
326 : SRS_PP_FALSE_NORTHING,
327 : NULL,
328 : NULL );
329 : }
330 :
331 4 : else if( EQUAL(papszMethods[0],"Lambert Conic Conformal (2SP)") )
332 : {
333 1 : OGCWKTSetProj( szProjection, papszMethods,
334 : SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP,
335 : SRS_PP_STANDARD_PARALLEL_1,
336 : SRS_PP_STANDARD_PARALLEL_2,
337 : SRS_PP_LATITUDE_OF_ORIGIN,
338 : SRS_PP_CENTRAL_MERIDIAN,
339 : SRS_PP_FALSE_EASTING,
340 : SRS_PP_FALSE_NORTHING,
341 : NULL );
342 : }
343 :
344 3 : else if( EQUAL(papszMethods[0],"Lambert Conformal (2SP Belgium)") )
345 : {
346 0 : OGCWKTSetProj( szProjection, papszMethods,
347 : SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM,
348 : SRS_PP_STANDARD_PARALLEL_1,
349 : SRS_PP_STANDARD_PARALLEL_2,
350 : SRS_PP_LATITUDE_OF_ORIGIN,
351 : SRS_PP_CENTRAL_MERIDIAN,
352 : SRS_PP_FALSE_EASTING,
353 : SRS_PP_FALSE_NORTHING,
354 : NULL );
355 : }
356 :
357 3 : else if( EQUAL(papszMethods[0],"Mercator (1SP)"))
358 : {
359 0 : OGCWKTSetProj( szProjection, papszMethods,
360 : SRS_PT_MERCATOR_1SP,
361 : SRS_PP_LATITUDE_OF_ORIGIN,
362 : SRS_PP_CENTRAL_MERIDIAN,
363 : SRS_PP_SCALE_FACTOR,
364 : SRS_PP_FALSE_EASTING,
365 : SRS_PP_FALSE_NORTHING,
366 : NULL,
367 : NULL );
368 : }
369 :
370 3 : else if( EQUAL(papszMethods[0],"Mercator (2SP)"))
371 : {
372 0 : OGCWKTSetProj( szProjection, papszMethods,
373 : SRS_PT_MERCATOR_2SP,
374 : SRS_PP_LATITUDE_OF_ORIGIN,/* should it be StdParalle1?*/
375 : SRS_PP_CENTRAL_MERIDIAN,
376 : SRS_PP_FALSE_EASTING,
377 : SRS_PP_FALSE_NORTHING,
378 : NULL,
379 : NULL,
380 : NULL );
381 : }
382 :
383 3 : else if( EQUAL(papszMethods[0],"Laborde Oblique Mercator") )
384 : {
385 0 : OGCWKTSetProj( szProjection, papszMethods,
386 : SRS_PT_LABORDE_OBLIQUE_MERCATOR,
387 : SRS_PP_LATITUDE_OF_CENTER,
388 : SRS_PP_LONGITUDE_OF_CENTER,
389 : SRS_PP_AZIMUTH,
390 : SRS_PP_SCALE_FACTOR,
391 : SRS_PP_FALSE_EASTING,
392 : SRS_PP_FALSE_NORTHING,
393 : NULL );
394 :
395 : }
396 :
397 3 : else if( EQUAL(papszMethods[0],"Hotine Oblique Mercator") )
398 : {
399 0 : OGCWKTSetProj( szProjection, papszMethods,
400 : SRS_PT_HOTINE_OBLIQUE_MERCATOR,
401 : SRS_PP_LATITUDE_OF_CENTER,
402 : SRS_PP_LONGITUDE_OF_CENTER,
403 : SRS_PP_AZIMUTH,
404 : SRS_PP_RECTIFIED_GRID_ANGLE,
405 : SRS_PP_SCALE_FACTOR, /* not in normal formulation */
406 : SRS_PP_FALSE_EASTING,
407 : SRS_PP_FALSE_NORTHING );
408 : }
409 :
410 3 : else if( EQUAL(papszMethods[0],"New Zealand Map Grid") )
411 :
412 : {
413 0 : OGCWKTSetProj( szProjection, papszMethods,
414 : SRS_PT_NEW_ZEALAND_MAP_GRID,
415 : SRS_PP_LATITUDE_OF_ORIGIN,
416 : SRS_PP_CENTRAL_MERIDIAN,
417 : SRS_PP_FALSE_EASTING,
418 : SRS_PP_FALSE_NORTHING,
419 : NULL,
420 : NULL,
421 : NULL );
422 : }
423 :
424 3 : else if( EQUAL(papszMethods[0],"Oblique Stereographic") )
425 : {
426 0 : OGCWKTSetProj( szProjection, papszMethods,
427 : SRS_PT_OBLIQUE_STEREOGRAPHIC,
428 : SRS_PP_LATITUDE_OF_ORIGIN,
429 : SRS_PP_CENTRAL_MERIDIAN,
430 : SRS_PP_SCALE_FACTOR,
431 : SRS_PP_FALSE_EASTING,
432 : SRS_PP_FALSE_NORTHING,
433 : NULL,
434 : NULL );
435 : }
436 :
437 3 : else if( EQUAL(papszMethods[0],"Polar Stereographic") )
438 : {
439 0 : OGCWKTSetProj( szProjection, papszMethods,
440 : SRS_PT_POLAR_STEREOGRAPHIC,
441 : SRS_PP_LATITUDE_OF_ORIGIN,
442 : SRS_PP_CENTRAL_MERIDIAN,
443 : SRS_PP_SCALE_FACTOR,
444 : SRS_PP_FALSE_EASTING,
445 : SRS_PP_FALSE_NORTHING,
446 : NULL,
447 : NULL );
448 : }
449 :
450 3 : else if( EQUAL(papszMethods[0],"Swiss Oblique Cylindrical") )
451 : {
452 0 : OGCWKTSetProj( szProjection, papszMethods,
453 : SRS_PT_SWISS_OBLIQUE_CYLINDRICAL,
454 : SRS_PP_LATITUDE_OF_CENTER,
455 : SRS_PP_LONGITUDE_OF_CENTER,
456 : SRS_PP_FALSE_EASTING,
457 : SRS_PP_FALSE_NORTHING,
458 : NULL,
459 : NULL,
460 : NULL );
461 : }
462 :
463 3 : else if( EQUAL(papszMethods[0],"Transverse Mercator") )
464 : {
465 3 : OGCWKTSetProj( szProjection, papszMethods,
466 : SRS_PT_TRANSVERSE_MERCATOR,
467 : SRS_PP_LATITUDE_OF_ORIGIN,
468 : SRS_PP_CENTRAL_MERIDIAN,
469 : SRS_PP_SCALE_FACTOR,
470 : SRS_PP_FALSE_EASTING,
471 : SRS_PP_FALSE_NORTHING,
472 : NULL,
473 : NULL );
474 : }
475 :
476 0 : else if( EQUAL(papszMethods[0],"Transverse Mercator (South Oriented)")
477 0 : || EQUAL(papszMethods[0],"Transverse Mercator (South Orientated)"))
478 : {
479 0 : OGCWKTSetProj( szProjection, papszMethods,
480 : SRS_PT_TRANSVERSE_MERCATOR_SOUTH_ORIENTED,
481 : SRS_PP_LATITUDE_OF_ORIGIN,
482 : SRS_PP_CENTRAL_MERIDIAN,
483 : SRS_PP_SCALE_FACTOR,
484 : SRS_PP_FALSE_EASTING,
485 : SRS_PP_FALSE_NORTHING,
486 : NULL,
487 : NULL );
488 : }
489 :
490 0 : else if( EQUAL(papszMethods[0],"*Albers Conic") )
491 : {
492 0 : OGCWKTSetProj( szProjection, papszMethods,
493 : SRS_PT_ALBERS_CONIC_EQUAL_AREA,
494 : SRS_PP_STANDARD_PARALLEL_1,
495 : SRS_PP_STANDARD_PARALLEL_2,
496 : SRS_PP_LATITUDE_OF_CENTER,
497 : SRS_PP_LONGITUDE_OF_CENTER,
498 : SRS_PP_FALSE_EASTING,
499 : SRS_PP_FALSE_NORTHING,
500 : NULL );
501 : }
502 :
503 0 : else if( EQUAL(papszMethods[0],"*Equidistant Conic") )
504 : {
505 0 : OGCWKTSetProj( szProjection, papszMethods,
506 : SRS_PT_EQUIDISTANT_CONIC,
507 : SRS_PP_STANDARD_PARALLEL_1,
508 : SRS_PP_STANDARD_PARALLEL_2,
509 : SRS_PP_LATITUDE_OF_CENTER,
510 : SRS_PP_LONGITUDE_OF_CENTER,
511 : SRS_PP_FALSE_EASTING,
512 : SRS_PP_FALSE_NORTHING,
513 : NULL );
514 : }
515 :
516 0 : else if( EQUAL(papszMethods[0],"*Polyconic") )
517 : {
518 0 : OGCWKTSetProj( szProjection, papszMethods,
519 : SRS_PT_POLYCONIC,
520 : SRS_PP_LATITUDE_OF_ORIGIN,
521 : SRS_PP_CENTRAL_MERIDIAN,
522 : SRS_PP_SCALE_FACTOR, /* not normally expected */
523 : SRS_PP_FALSE_EASTING,
524 : SRS_PP_FALSE_NORTHING,
525 : NULL,
526 : NULL );
527 : }
528 :
529 5 : CSLDestroy( papszMethods );
530 :
531 :
532 : /* -------------------------------------------------------------------- */
533 : /* Extract the linear Units specification. */
534 : /* -------------------------------------------------------------------- */
535 5 : if( psGXF->pszUnitName != NULL && strlen(szProjection) > 0 )
536 : {
537 4 : sprintf( szProjection+strlen(szProjection),
538 : ",UNIT[\"%s\",%.15g]",
539 : psGXF->pszUnitName, psGXF->dfUnitToMeter );
540 : }
541 :
542 : /* -------------------------------------------------------------------- */
543 : /* Build GEOGCS. There are still "issues" with the generation */
544 : /* of the GEOGCS/Datum and Spheroid names. Of these, only the */
545 : /* datum name is really significant. */
546 : /* -------------------------------------------------------------------- */
547 5 : if( CSLCount(psGXF->papszMapProjection) > 1 )
548 : {
549 : char **papszTokens;
550 :
551 5 : papszTokens = CSLTokenizeStringComplex(psGXF->papszMapProjection[1],
552 : ",", TRUE, TRUE );
553 :
554 :
555 5 : if( CSLCount(papszTokens) > 2 )
556 : {
557 5 : double dfMajor = atof(papszTokens[1]);
558 5 : double dfEccentricity = atof(papszTokens[2]);
559 : double dfInvFlattening, dfMinor;
560 : char *pszOGCDatum;
561 :
562 : /* translate eccentricity to inv flattening. */
563 5 : if( dfEccentricity == 0.0 )
564 0 : dfInvFlattening = 0.0;
565 : else
566 : {
567 5 : dfMinor = dfMajor * pow(1.0-dfEccentricity*dfEccentricity,0.5);
568 5 : dfInvFlattening = 1.0 / (1 - dfMinor/dfMajor);
569 : }
570 :
571 5 : pszOGCDatum = CPLStrdup(papszTokens[0]);
572 5 : WKTMassageDatum( &pszOGCDatum );
573 :
574 5 : sprintf( szGCS,
575 : "GEOGCS[\"%s\","
576 : "DATUM[\"%s\","
577 : "SPHEROID[\"%s\",%s,%.15g]],",
578 : papszTokens[0],
579 : pszOGCDatum,
580 : papszTokens[0], /* this is datum, but should be ellipse*/
581 5 : papszTokens[1],
582 : dfInvFlattening );
583 5 : CPLFree( pszOGCDatum );
584 : }
585 :
586 5 : if( CSLCount(papszTokens) > 3 )
587 5 : sprintf( szGCS + strlen(szGCS),
588 : "PRIMEM[\"unnamed\",%s],",
589 5 : papszTokens[3] );
590 :
591 5 : strcat( szGCS, "UNIT[\"degree\",0.0174532925199433]]" );
592 :
593 5 : CSLDestroy( papszTokens );
594 : }
595 :
596 : /* -------------------------------------------------------------------- */
597 : /* Put this all together into a full projection. */
598 : /* -------------------------------------------------------------------- */
599 5 : if( strlen(szProjection) > 0 )
600 : {
601 4 : if( psGXF->papszMapProjection[0][0] == '"' )
602 4 : sprintf( szWKT,
603 : "PROJCS[%s,%s,%s]",
604 : psGXF->papszMapProjection[0],
605 : szGCS,
606 : szProjection );
607 : else
608 0 : sprintf( szWKT,
609 : "PROJCS[\"%s\",%s,%s]",
610 : psGXF->papszMapProjection[0],
611 : szGCS,
612 : szProjection );
613 :
614 : }
615 : else
616 : {
617 1 : strcpy( szWKT, szGCS );
618 : }
619 :
620 5 : return( CPLStrdup( szWKT ) );
621 : }
622 :
|