1 : /******************************************************************************
2 : * $Id: ogr_srs_validate.cpp 24323 2012-04-27 05:45:18Z warmerdam $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Implementation of the OGRSpatialReference::Validate() method and
6 : * related infrastructure.
7 : * Author: Frank Warmerdam, warmerdam@pobox.com
8 : *
9 : ******************************************************************************
10 : * Copyright (c) 2001, Frank Warmerdam <warmerdam@pobox.com>
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 "ogr_spatialref.h"
32 : #include "ogr_p.h"
33 :
34 : CPL_CVSID("$Id: ogr_srs_validate.cpp 24323 2012-04-27 05:45:18Z warmerdam $");
35 :
36 : /* why would fipszone and zone be paramers when they relate to a composite
37 : projection which renders done into a non-zoned projection? */
38 :
39 : static const char *papszParameters[] =
40 : {
41 : SRS_PP_CENTRAL_MERIDIAN,
42 : SRS_PP_SCALE_FACTOR,
43 : SRS_PP_STANDARD_PARALLEL_1,
44 : SRS_PP_STANDARD_PARALLEL_2,
45 : SRS_PP_LONGITUDE_OF_CENTER,
46 : SRS_PP_LATITUDE_OF_CENTER,
47 : SRS_PP_LONGITUDE_OF_ORIGIN,
48 : SRS_PP_LATITUDE_OF_ORIGIN,
49 : SRS_PP_FALSE_EASTING,
50 : SRS_PP_FALSE_NORTHING,
51 : SRS_PP_AZIMUTH,
52 : SRS_PP_LONGITUDE_OF_POINT_1,
53 : SRS_PP_LATITUDE_OF_POINT_1,
54 : SRS_PP_LONGITUDE_OF_POINT_2,
55 : SRS_PP_LATITUDE_OF_POINT_2,
56 : SRS_PP_LONGITUDE_OF_POINT_3,
57 : SRS_PP_LATITUDE_OF_POINT_3,
58 : SRS_PP_LANDSAT_NUMBER,
59 : SRS_PP_PATH_NUMBER,
60 : SRS_PP_PERSPECTIVE_POINT_HEIGHT,
61 : SRS_PP_FIPSZONE,
62 : SRS_PP_ZONE,
63 : SRS_PP_RECTIFIED_GRID_ANGLE,
64 : SRS_PP_SATELLITE_HEIGHT,
65 : SRS_PP_PSEUDO_STD_PARALLEL_1,
66 : SRS_PP_LATITUDE_OF_1ST_POINT,
67 : SRS_PP_LONGITUDE_OF_1ST_POINT,
68 : SRS_PP_LATITUDE_OF_2ND_POINT,
69 : SRS_PP_LONGITUDE_OF_2ND_POINT,
70 : NULL
71 : };
72 :
73 : // the following projection lists are incomplete. they will likely
74 : // change after the CT RPF response. Examples show alternate forms with
75 : // underscores instead of spaces. Should we use the EPSG names were available?
76 : // Plate-Caree has an accent in the spec!
77 :
78 : static const char *papszProjectionSupported[] =
79 : {
80 : SRS_PT_CASSINI_SOLDNER,
81 : SRS_PT_BONNE,
82 : SRS_PT_EQUIDISTANT_CONIC,
83 : SRS_PT_EQUIRECTANGULAR,
84 : SRS_PT_ECKERT_I,
85 : SRS_PT_ECKERT_II,
86 : SRS_PT_ECKERT_III,
87 : SRS_PT_ECKERT_IV,
88 : SRS_PT_ECKERT_V,
89 : SRS_PT_ECKERT_VI,
90 : SRS_PT_MERCATOR_1SP,
91 : SRS_PT_MERCATOR_2SP,
92 : SRS_PT_MOLLWEIDE,
93 : SRS_PT_ROBINSON,
94 : SRS_PT_ALBERS_CONIC_EQUAL_AREA,
95 : SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP,
96 : SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP,
97 : SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM,
98 : SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA,
99 : SRS_PT_TRANSVERSE_MERCATOR,
100 : SRS_PT_TRANSVERSE_MERCATOR_SOUTH_ORIENTED,
101 : SRS_PT_OBLIQUE_STEREOGRAPHIC,
102 : SRS_PT_POLAR_STEREOGRAPHIC,
103 : SRS_PT_HOTINE_OBLIQUE_MERCATOR,
104 : SRS_PT_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN,
105 : SRS_PT_HOTINE_OBLIQUE_MERCATOR_AZIMUTH_CENTER,
106 : SRS_PT_LABORDE_OBLIQUE_MERCATOR,
107 : SRS_PT_SWISS_OBLIQUE_CYLINDRICAL,
108 : SRS_PT_AZIMUTHAL_EQUIDISTANT,
109 : SRS_PT_MILLER_CYLINDRICAL,
110 : SRS_PT_NEW_ZEALAND_MAP_GRID,
111 : SRS_PT_SINUSOIDAL,
112 : SRS_PT_STEREOGRAPHIC,
113 : SRS_PT_GNOMONIC,
114 : SRS_PT_GALL_STEREOGRAPHIC,
115 : SRS_PT_ORTHOGRAPHIC,
116 : SRS_PT_POLYCONIC,
117 : SRS_PT_VANDERGRINTEN,
118 : SRS_PT_GEOSTATIONARY_SATELLITE,
119 : SRS_PT_TWO_POINT_EQUIDISTANT,
120 : SRS_PT_IMW_POLYCONIC,
121 : SRS_PT_WAGNER_I,
122 : SRS_PT_WAGNER_II,
123 : SRS_PT_WAGNER_III,
124 : SRS_PT_WAGNER_IV,
125 : SRS_PT_WAGNER_V,
126 : SRS_PT_WAGNER_VI,
127 : SRS_PT_WAGNER_VII,
128 : SRS_PT_GAUSSSCHREIBERTMERCATOR,
129 : SRS_PT_KROVAK,
130 : SRS_PT_CYLINDRICAL_EQUAL_AREA,
131 : SRS_PT_GOODE_HOMOLOSINE,
132 : SRS_PT_IGH,
133 : NULL
134 : };
135 :
136 : static const char *papszProjectionUnsupported[] =
137 : {
138 : SRS_PT_NEW_ZEALAND_MAP_GRID,
139 : SRS_PT_TUNISIA_MINING_GRID,
140 : NULL
141 : };
142 :
143 : /*
144 : ** List of supported projections with the PARAMETERS[] acceptable for each.
145 : */
146 : static const char *papszProjWithParms[] = {
147 :
148 : SRS_PT_TRANSVERSE_MERCATOR,
149 : SRS_PP_LATITUDE_OF_ORIGIN,
150 : SRS_PP_CENTRAL_MERIDIAN,
151 : SRS_PP_SCALE_FACTOR,
152 : SRS_PP_FALSE_EASTING,
153 : SRS_PP_FALSE_NORTHING,
154 : NULL,
155 :
156 : SRS_PT_TRANSVERSE_MERCATOR_SOUTH_ORIENTED,
157 : SRS_PP_LATITUDE_OF_ORIGIN,
158 : SRS_PP_CENTRAL_MERIDIAN,
159 : SRS_PP_SCALE_FACTOR,
160 : SRS_PP_FALSE_EASTING,
161 : SRS_PP_FALSE_NORTHING,
162 : NULL,
163 :
164 : SRS_PT_TUNISIA_MINING_GRID,
165 : SRS_PP_LATITUDE_OF_ORIGIN,
166 : SRS_PP_CENTRAL_MERIDIAN,
167 : SRS_PP_FALSE_EASTING,
168 : SRS_PP_FALSE_NORTHING,
169 : NULL,
170 :
171 : SRS_PT_ALBERS_CONIC_EQUAL_AREA,
172 : SRS_PP_LATITUDE_OF_CENTER,
173 : SRS_PP_LONGITUDE_OF_CENTER,
174 : SRS_PP_STANDARD_PARALLEL_1,
175 : SRS_PP_STANDARD_PARALLEL_2,
176 : SRS_PP_FALSE_EASTING,
177 : SRS_PP_FALSE_NORTHING,
178 : NULL,
179 :
180 : SRS_PT_AZIMUTHAL_EQUIDISTANT,
181 : SRS_PP_LATITUDE_OF_CENTER,
182 : SRS_PP_LONGITUDE_OF_CENTER,
183 : SRS_PP_FALSE_EASTING,
184 : SRS_PP_FALSE_NORTHING,
185 : NULL,
186 :
187 : SRS_PT_BONNE,
188 : SRS_PP_STANDARD_PARALLEL_1,
189 : SRS_PP_CENTRAL_MERIDIAN,
190 : SRS_PP_FALSE_EASTING,
191 : SRS_PP_FALSE_NORTHING,
192 : NULL,
193 :
194 : SRS_PT_CYLINDRICAL_EQUAL_AREA,
195 : SRS_PP_STANDARD_PARALLEL_1,
196 : SRS_PP_CENTRAL_MERIDIAN,
197 : SRS_PP_FALSE_EASTING,
198 : SRS_PP_FALSE_NORTHING,
199 : NULL,
200 :
201 : SRS_PT_CASSINI_SOLDNER,
202 : SRS_PP_LATITUDE_OF_ORIGIN,
203 : SRS_PP_CENTRAL_MERIDIAN,
204 : SRS_PP_FALSE_EASTING,
205 : SRS_PP_FALSE_NORTHING,
206 : NULL,
207 :
208 : SRS_PT_EQUIDISTANT_CONIC,
209 : SRS_PP_STANDARD_PARALLEL_1,
210 : SRS_PP_STANDARD_PARALLEL_2,
211 : SRS_PP_LATITUDE_OF_CENTER,
212 : SRS_PP_LONGITUDE_OF_CENTER,
213 : SRS_PP_FALSE_EASTING,
214 : SRS_PP_FALSE_NORTHING,
215 : NULL,
216 :
217 : SRS_PT_ECKERT_I,
218 : SRS_PP_CENTRAL_MERIDIAN,
219 : SRS_PP_FALSE_EASTING,
220 : SRS_PP_FALSE_NORTHING,
221 : NULL,
222 :
223 : SRS_PT_ECKERT_II,
224 : SRS_PP_CENTRAL_MERIDIAN,
225 : SRS_PP_FALSE_EASTING,
226 : SRS_PP_FALSE_NORTHING,
227 : NULL,
228 :
229 : SRS_PT_ECKERT_III,
230 : SRS_PP_CENTRAL_MERIDIAN,
231 : SRS_PP_FALSE_EASTING,
232 : SRS_PP_FALSE_NORTHING,
233 : NULL,
234 :
235 : SRS_PT_ECKERT_IV,
236 : SRS_PP_CENTRAL_MERIDIAN,
237 : SRS_PP_FALSE_EASTING,
238 : SRS_PP_FALSE_NORTHING,
239 : NULL,
240 :
241 : SRS_PT_ECKERT_V,
242 : SRS_PP_CENTRAL_MERIDIAN,
243 : SRS_PP_FALSE_EASTING,
244 : SRS_PP_FALSE_NORTHING,
245 : NULL,
246 :
247 : SRS_PT_ECKERT_VI,
248 : SRS_PP_CENTRAL_MERIDIAN,
249 : SRS_PP_FALSE_EASTING,
250 : SRS_PP_FALSE_NORTHING,
251 : NULL,
252 :
253 : SRS_PT_EQUIRECTANGULAR,
254 : SRS_PP_LATITUDE_OF_ORIGIN,
255 : SRS_PP_CENTRAL_MERIDIAN,
256 : SRS_PP_STANDARD_PARALLEL_1,
257 : SRS_PP_FALSE_EASTING,
258 : SRS_PP_FALSE_NORTHING,
259 : NULL,
260 :
261 : SRS_PT_GALL_STEREOGRAPHIC,
262 : SRS_PP_CENTRAL_MERIDIAN,
263 : SRS_PP_FALSE_EASTING,
264 : SRS_PP_FALSE_NORTHING,
265 : NULL,
266 :
267 : SRS_PT_GNOMONIC,
268 : SRS_PP_LATITUDE_OF_ORIGIN,
269 : SRS_PP_CENTRAL_MERIDIAN,
270 : SRS_PP_FALSE_EASTING,
271 : SRS_PP_FALSE_NORTHING,
272 : NULL,
273 :
274 : SRS_PT_HOTINE_OBLIQUE_MERCATOR,
275 : SRS_PP_LATITUDE_OF_CENTER,
276 : SRS_PP_LONGITUDE_OF_CENTER,
277 : SRS_PP_AZIMUTH,
278 : SRS_PP_RECTIFIED_GRID_ANGLE,
279 : SRS_PP_SCALE_FACTOR,
280 : SRS_PP_FALSE_EASTING,
281 : SRS_PP_FALSE_NORTHING,
282 : NULL,
283 :
284 : SRS_PT_HOTINE_OBLIQUE_MERCATOR_AZIMUTH_CENTER,
285 : SRS_PP_LATITUDE_OF_CENTER,
286 : SRS_PP_LONGITUDE_OF_CENTER,
287 : SRS_PP_AZIMUTH,
288 : SRS_PP_RECTIFIED_GRID_ANGLE,
289 : SRS_PP_SCALE_FACTOR,
290 : SRS_PP_FALSE_EASTING,
291 : SRS_PP_FALSE_NORTHING,
292 : NULL,
293 :
294 : SRS_PT_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN,
295 : SRS_PP_LATITUDE_OF_CENTER,
296 : SRS_PP_LATITUDE_OF_POINT_1,
297 : SRS_PP_LONGITUDE_OF_POINT_1,
298 : SRS_PP_LATITUDE_OF_POINT_2,
299 : SRS_PP_LONGITUDE_OF_POINT_2
300 : SRS_PP_SCALE_FACTOR,
301 : SRS_PP_FALSE_EASTING,
302 : SRS_PP_FALSE_NORTHING,
303 : NULL,
304 :
305 : SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA,
306 : SRS_PP_LATITUDE_OF_CENTER,
307 : SRS_PP_LONGITUDE_OF_CENTER,
308 : SRS_PP_FALSE_EASTING,
309 : SRS_PP_FALSE_NORTHING,
310 : NULL,
311 :
312 : SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP,
313 : SRS_PP_STANDARD_PARALLEL_1,
314 : SRS_PP_STANDARD_PARALLEL_2,
315 : SRS_PP_LATITUDE_OF_ORIGIN,
316 : SRS_PP_CENTRAL_MERIDIAN,
317 : SRS_PP_FALSE_EASTING,
318 : SRS_PP_FALSE_NORTHING,
319 : NULL,
320 :
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 :
329 : SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM,
330 : SRS_PP_STANDARD_PARALLEL_1,
331 : SRS_PP_STANDARD_PARALLEL_2,
332 : SRS_PP_LATITUDE_OF_ORIGIN,
333 : SRS_PP_CENTRAL_MERIDIAN,
334 : SRS_PP_FALSE_EASTING,
335 : SRS_PP_FALSE_NORTHING,
336 : NULL,
337 :
338 : SRS_PT_MILLER_CYLINDRICAL,
339 : SRS_PP_LATITUDE_OF_CENTER,
340 : SRS_PP_LONGITUDE_OF_CENTER,
341 : SRS_PP_FALSE_EASTING,
342 : SRS_PP_FALSE_NORTHING,
343 : NULL,
344 :
345 : SRS_PT_MERCATOR_1SP,
346 : SRS_PP_LATITUDE_OF_ORIGIN,
347 : SRS_PP_CENTRAL_MERIDIAN,
348 : SRS_PP_SCALE_FACTOR,
349 : SRS_PP_FALSE_EASTING,
350 : SRS_PP_FALSE_NORTHING,
351 : NULL,
352 :
353 : SRS_PT_MERCATOR_2SP,
354 : SRS_PP_STANDARD_PARALLEL_1,
355 : SRS_PP_LATITUDE_OF_ORIGIN,
356 : SRS_PP_CENTRAL_MERIDIAN,
357 : SRS_PP_FALSE_EASTING,
358 : SRS_PP_FALSE_NORTHING,
359 : NULL,
360 :
361 : SRS_PT_MOLLWEIDE,
362 : SRS_PP_CENTRAL_MERIDIAN,
363 : SRS_PP_FALSE_EASTING,
364 : SRS_PP_FALSE_NORTHING,
365 : NULL,
366 :
367 : SRS_PT_NEW_ZEALAND_MAP_GRID,
368 : SRS_PP_LATITUDE_OF_ORIGIN,
369 : SRS_PP_CENTRAL_MERIDIAN,
370 : SRS_PP_FALSE_EASTING,
371 : SRS_PP_FALSE_NORTHING,
372 : NULL,
373 :
374 : SRS_PT_ORTHOGRAPHIC,
375 : SRS_PP_LATITUDE_OF_ORIGIN,
376 : SRS_PP_CENTRAL_MERIDIAN,
377 : SRS_PP_FALSE_EASTING,
378 : SRS_PP_FALSE_NORTHING,
379 : NULL,
380 :
381 : SRS_PT_POLYCONIC,
382 : SRS_PP_LATITUDE_OF_ORIGIN,
383 : SRS_PP_CENTRAL_MERIDIAN,
384 : SRS_PP_FALSE_EASTING,
385 : SRS_PP_FALSE_NORTHING,
386 : NULL,
387 :
388 : SRS_PT_POLAR_STEREOGRAPHIC,
389 : SRS_PP_LATITUDE_OF_ORIGIN,
390 : SRS_PP_CENTRAL_MERIDIAN,
391 : SRS_PP_SCALE_FACTOR,
392 : SRS_PP_FALSE_EASTING,
393 : SRS_PP_FALSE_NORTHING,
394 : NULL,
395 :
396 : SRS_PT_ROBINSON,
397 : SRS_PP_LONGITUDE_OF_CENTER,
398 : SRS_PP_FALSE_EASTING,
399 : SRS_PP_FALSE_NORTHING,
400 : NULL,
401 :
402 : SRS_PT_SINUSOIDAL,
403 : SRS_PP_LONGITUDE_OF_CENTER,
404 : SRS_PP_FALSE_EASTING,
405 : SRS_PP_FALSE_NORTHING,
406 : NULL,
407 :
408 : SRS_PT_STEREOGRAPHIC,
409 : SRS_PP_LATITUDE_OF_ORIGIN,
410 : SRS_PP_CENTRAL_MERIDIAN,
411 : SRS_PP_SCALE_FACTOR,
412 : SRS_PP_FALSE_EASTING,
413 : SRS_PP_FALSE_NORTHING,
414 : NULL,
415 :
416 : SRS_PT_SWISS_OBLIQUE_CYLINDRICAL,
417 : SRS_PP_LATITUDE_OF_CENTER,
418 : SRS_PP_CENTRAL_MERIDIAN,
419 : SRS_PP_FALSE_EASTING,
420 : SRS_PP_FALSE_NORTHING,
421 : NULL,
422 :
423 : SRS_PT_OBLIQUE_STEREOGRAPHIC,
424 : SRS_PP_LATITUDE_OF_ORIGIN,
425 : SRS_PP_CENTRAL_MERIDIAN,
426 : SRS_PP_SCALE_FACTOR,
427 : SRS_PP_FALSE_EASTING,
428 : SRS_PP_FALSE_NORTHING,
429 : NULL,
430 :
431 : SRS_PT_VANDERGRINTEN,
432 : SRS_PP_CENTRAL_MERIDIAN,
433 : SRS_PP_FALSE_EASTING,
434 : SRS_PP_FALSE_NORTHING,
435 : NULL,
436 :
437 : SRS_PT_GEOSTATIONARY_SATELLITE,
438 : SRS_PP_CENTRAL_MERIDIAN,
439 : SRS_PP_SATELLITE_HEIGHT,
440 : SRS_PP_FALSE_EASTING,
441 : SRS_PP_FALSE_NORTHING,
442 : NULL,
443 :
444 : SRS_PT_KROVAK,
445 : SRS_PP_LATITUDE_OF_CENTER,
446 : SRS_PP_LONGITUDE_OF_CENTER,
447 : SRS_PP_AZIMUTH,
448 : SRS_PP_PSEUDO_STD_PARALLEL_1,
449 : SRS_PP_SCALE_FACTOR,
450 : SRS_PP_FALSE_EASTING,
451 : SRS_PP_FALSE_NORTHING,
452 : NULL,
453 :
454 : SRS_PT_TWO_POINT_EQUIDISTANT,
455 : SRS_PP_LATITUDE_OF_1ST_POINT,
456 : SRS_PP_LONGITUDE_OF_1ST_POINT,
457 : SRS_PP_LATITUDE_OF_2ND_POINT,
458 : SRS_PP_LONGITUDE_OF_2ND_POINT,
459 : SRS_PP_FALSE_EASTING,
460 : SRS_PP_FALSE_NORTHING,
461 : NULL,
462 :
463 : SRS_PT_IMW_POLYCONIC,
464 : SRS_PP_LATITUDE_OF_1ST_POINT,
465 : SRS_PP_LATITUDE_OF_2ND_POINT,
466 : SRS_PP_CENTRAL_MERIDIAN,
467 : SRS_PP_FALSE_EASTING,
468 : SRS_PP_FALSE_NORTHING,
469 : NULL,
470 :
471 : SRS_PT_WAGNER_I,
472 : SRS_PP_FALSE_EASTING,
473 : SRS_PP_FALSE_NORTHING,
474 : NULL,
475 :
476 : SRS_PT_WAGNER_II,
477 : SRS_PP_FALSE_EASTING,
478 : SRS_PP_FALSE_NORTHING,
479 : NULL,
480 :
481 : SRS_PT_WAGNER_III,
482 : SRS_PP_LATITUDE_OF_ORIGIN,
483 : SRS_PP_FALSE_EASTING,
484 : SRS_PP_FALSE_NORTHING,
485 : NULL,
486 :
487 : SRS_PT_WAGNER_IV,
488 : SRS_PP_FALSE_EASTING,
489 : SRS_PP_FALSE_NORTHING,
490 : NULL,
491 :
492 : SRS_PT_WAGNER_V,
493 : SRS_PP_FALSE_EASTING,
494 : SRS_PP_FALSE_NORTHING,
495 : NULL,
496 :
497 : SRS_PT_WAGNER_VI,
498 : SRS_PP_FALSE_EASTING,
499 : SRS_PP_FALSE_NORTHING,
500 : NULL,
501 :
502 : SRS_PT_WAGNER_VII,
503 : SRS_PP_FALSE_EASTING,
504 : SRS_PP_FALSE_NORTHING,
505 : NULL,
506 :
507 : SRS_PT_GAUSSSCHREIBERTMERCATOR,
508 : SRS_PP_LATITUDE_OF_ORIGIN,
509 : SRS_PP_CENTRAL_MERIDIAN,
510 : SRS_PP_SCALE_FACTOR,
511 : SRS_PP_FALSE_EASTING,
512 : SRS_PP_FALSE_NORTHING,
513 : NULL,
514 :
515 : SRS_PT_GOODE_HOMOLOSINE,
516 : SRS_PP_CENTRAL_MERIDIAN,
517 : SRS_PP_FALSE_EASTING,
518 : SRS_PP_FALSE_NORTHING,
519 : NULL,
520 :
521 : SRS_PT_IGH,
522 : NULL,
523 :
524 : NULL
525 : };
526 :
527 : static const char *papszAliasGroupList[] = {
528 : SRS_PP_LATITUDE_OF_ORIGIN,
529 : SRS_PP_LATITUDE_OF_CENTER,
530 : NULL,
531 : SRS_PP_CENTRAL_MERIDIAN,
532 : SRS_PP_LONGITUDE_OF_CENTER,
533 : SRS_PP_LONGITUDE_OF_ORIGIN,
534 : NULL,
535 : NULL
536 : };
537 :
538 :
539 : /************************************************************************/
540 : /* Validate() */
541 : /************************************************************************/
542 :
543 : /**
544 : * \brief Validate SRS tokens.
545 : *
546 : * This method attempts to verify that the spatial reference system is
547 : * well formed, and consists of known tokens. The validation is not
548 : * comprehensive.
549 : *
550 : * This method is the same as the C function OSRValidate().
551 : *
552 : * @return OGRERR_NONE if all is fine, OGRERR_CORRUPT_DATA if the SRS is
553 : * not well formed, and OGRERR_UNSUPPORTED_SRS if the SRS is well formed,
554 : * but contains non-standard PROJECTION[] values.
555 : */
556 :
557 63 : OGRErr OGRSpatialReference::Validate()
558 :
559 : {
560 : /* -------------------------------------------------------------------- */
561 : /* Validate root node. */
562 : /* -------------------------------------------------------------------- */
563 63 : if( poRoot == NULL )
564 : {
565 : CPLDebug( "OGRSpatialReference::Validate",
566 0 : "No root pointer.\n" );
567 0 : return OGRERR_CORRUPT_DATA;
568 : }
569 :
570 63 : return Validate(poRoot);
571 : }
572 :
573 :
574 65 : OGRErr OGRSpatialReference::Validate(OGR_SRSNode *poRoot)
575 : {
576 65 : if( !EQUAL(poRoot->GetValue(),"GEOGCS")
577 : && !EQUAL(poRoot->GetValue(),"PROJCS")
578 : && !EQUAL(poRoot->GetValue(),"LOCAL_CS")
579 : && !EQUAL(poRoot->GetValue(),"GEOCCS")
580 : && !EQUAL(poRoot->GetValue(),"VERT_CS")
581 : && !EQUAL(poRoot->GetValue(),"COMPD_CS"))
582 : {
583 : CPLDebug( "OGRSpatialReference::Validate",
584 : "Unrecognised root node `%s'\n",
585 0 : poRoot->GetValue() );
586 0 : return OGRERR_CORRUPT_DATA;
587 : }
588 :
589 : /* -------------------------------------------------------------------- */
590 : /* For a COMPD_CS, validate subparameters and head & tail cs */
591 : /* -------------------------------------------------------------------- */
592 65 : if( EQUAL(poRoot->GetValue(),"COMPD_CS") )
593 : {
594 : OGR_SRSNode *poNode;
595 : int i;
596 :
597 4 : for( i = 1; i < poRoot->GetChildCount(); i++ )
598 : {
599 3 : poNode = poRoot->GetChild(i);
600 :
601 3 : if( EQUAL(poNode->GetValue(),"GEOGCS") ||
602 : EQUAL(poNode->GetValue(),"PROJCS") ||
603 : EQUAL(poNode->GetValue(),"LOCAL_CS") ||
604 : EQUAL(poNode->GetValue(),"GEOCCS") ||
605 : EQUAL(poNode->GetValue(),"VERT_CS") ||
606 : EQUAL(poNode->GetValue(),"COMPD_CS") )
607 : {
608 2 : OGRErr eErr = Validate(poNode);
609 2 : if (eErr != OGRERR_NONE)
610 0 : return eErr;
611 : }
612 1 : else if( EQUAL(poNode->GetValue(),"AUTHORITY") )
613 : {
614 1 : OGRErr eErr = ValidateAuthority(poNode);
615 1 : if (eErr != OGRERR_NONE)
616 0 : return eErr;
617 : }
618 : else
619 : {
620 : CPLDebug( "OGRSpatialReference::Validate",
621 : "Unexpected child for COMPD_CS `%s'.\n",
622 0 : poNode->GetValue() );
623 :
624 0 : return OGRERR_CORRUPT_DATA;
625 : }
626 : }
627 :
628 1 : return OGRERR_NONE;
629 : }
630 :
631 : /* -------------------------------------------------------------------- */
632 : /* Validate VERT_CS */
633 : /* -------------------------------------------------------------------- */
634 64 : if( EQUAL(poRoot->GetValue(),"VERT_CS") )
635 : {
636 : OGR_SRSNode *poNode;
637 : int i;
638 1 : int bGotVertDatum = FALSE;
639 1 : int bGotUnit = FALSE;
640 1 : int nCountAxis = 0;
641 :
642 5 : for( i = 1; i < poRoot->GetChildCount(); i++ )
643 : {
644 4 : poNode = poRoot->GetChild(i);
645 :
646 4 : if( EQUAL(poNode->GetValue(),"VERT_DATUM") )
647 : {
648 1 : OGRErr eErr = ValidateVertDatum(poNode);
649 1 : if (eErr != OGRERR_NONE)
650 0 : return eErr;
651 1 : bGotVertDatum = TRUE;
652 : }
653 3 : else if( EQUAL(poNode->GetValue(),"UNIT") )
654 : {
655 1 : OGRErr eErr = ValidateUnit(poNode);
656 1 : if (eErr != OGRERR_NONE)
657 0 : return eErr;
658 1 : bGotUnit = TRUE;
659 : }
660 2 : else if( EQUAL(poNode->GetValue(),"AXIS") )
661 : {
662 1 : OGRErr eErr = ValidateAxis(poNode);
663 1 : if (eErr != OGRERR_NONE)
664 0 : return eErr;
665 1 : nCountAxis ++;
666 : }
667 1 : else if( EQUAL(poNode->GetValue(),"AUTHORITY") )
668 : {
669 1 : OGRErr eErr = ValidateAuthority(poNode);
670 1 : if (eErr != OGRERR_NONE)
671 0 : return eErr;
672 : }
673 : else
674 : {
675 : CPLDebug( "OGRSpatialReference::Validate",
676 : "Unexpected child for VERT_CS `%s'.\n",
677 0 : poNode->GetValue() );
678 :
679 0 : return OGRERR_CORRUPT_DATA;
680 : }
681 : }
682 :
683 1 : if (!bGotVertDatum)
684 : {
685 : CPLDebug( "OGRSpatialReference::Validate",
686 0 : "No VERT_DATUM child in VERT_CS.\n" );
687 :
688 0 : return OGRERR_CORRUPT_DATA;
689 : }
690 :
691 1 : if (!bGotUnit)
692 : {
693 : CPLDebug( "OGRSpatialReference::Validate",
694 0 : "No UNIT child in VERT_CS.\n" );
695 :
696 0 : return OGRERR_CORRUPT_DATA;
697 : }
698 :
699 1 : if (nCountAxis > 1)
700 : {
701 : CPLDebug( "OGRSpatialReference::Validate",
702 0 : "Too many AXIS children in VERT_CS.\n" );
703 :
704 0 : return OGRERR_CORRUPT_DATA;
705 : }
706 1 : return OGRERR_NONE;
707 : }
708 :
709 : /* -------------------------------------------------------------------- */
710 : /* Validate GEOCCS */
711 : /* -------------------------------------------------------------------- */
712 63 : if( EQUAL(poRoot->GetValue(),"GEOCCS") )
713 : {
714 : OGR_SRSNode *poNode;
715 : int i;
716 4 : int bGotDatum = FALSE;
717 4 : int bGotPrimeM = FALSE;
718 4 : int bGotUnit = FALSE;
719 4 : int nCountAxis = 0;
720 :
721 27 : for( i = 1; i < poRoot->GetChildCount(); i++ )
722 : {
723 23 : poNode = poRoot->GetChild(i);
724 :
725 23 : if( EQUAL(poNode->GetValue(),"DATUM") )
726 : {
727 4 : bGotDatum = TRUE;
728 : }
729 19 : else if( EQUAL(poNode->GetValue(),"PRIMEM") )
730 : {
731 4 : bGotPrimeM = TRUE;
732 :
733 4 : if( poNode->GetChildCount() < 2
734 : || poNode->GetChildCount() > 3 )
735 : {
736 : CPLDebug( "OGRSpatialReference::Validate",
737 : "PRIMEM has wrong number of children (%d),"
738 : "not 2 or 3 as expected.\n",
739 0 : poNode->GetChildCount() );
740 :
741 0 : return OGRERR_CORRUPT_DATA;
742 : }
743 : }
744 15 : else if( EQUAL(poNode->GetValue(),"UNIT") )
745 : {
746 3 : OGRErr eErr = ValidateUnit(poNode);
747 3 : if (eErr != OGRERR_NONE)
748 0 : return eErr;
749 3 : bGotUnit = TRUE;
750 : }
751 12 : else if( EQUAL(poNode->GetValue(),"AXIS") )
752 : {
753 9 : OGRErr eErr = ValidateAxis(poNode);
754 9 : if (eErr != OGRERR_NONE)
755 0 : return eErr;
756 9 : nCountAxis ++;
757 : }
758 3 : else if( EQUAL(poNode->GetValue(),"AUTHORITY") )
759 : {
760 3 : OGRErr eErr = ValidateAuthority(poNode);
761 3 : if (eErr != OGRERR_NONE)
762 0 : return eErr;
763 : }
764 : else
765 : {
766 : CPLDebug( "OGRSpatialReference::Validate",
767 : "Unexpected child for GEOCCS `%s'.\n",
768 0 : poNode->GetValue() );
769 :
770 0 : return OGRERR_CORRUPT_DATA;
771 : }
772 : }
773 :
774 4 : if (!bGotDatum)
775 : {
776 : CPLDebug( "OGRSpatialReference::Validate",
777 0 : "No DATUM child in GEOCCS.\n" );
778 :
779 0 : return OGRERR_CORRUPT_DATA;
780 : }
781 :
782 4 : if (!bGotPrimeM)
783 : {
784 : CPLDebug( "OGRSpatialReference::Validate",
785 0 : "No PRIMEM child in GEOCCS.\n" );
786 :
787 0 : return OGRERR_CORRUPT_DATA;
788 : }
789 :
790 4 : if (!bGotUnit)
791 : {
792 : CPLDebug( "OGRSpatialReference::Validate",
793 1 : "No UNIT child in GEOCCS.\n" );
794 :
795 1 : return OGRERR_CORRUPT_DATA;
796 : }
797 :
798 3 : if (nCountAxis != 0 && nCountAxis != 3 )
799 : {
800 : CPLDebug( "OGRSpatialReference::Validate",
801 0 : "Wrong number of AXIS children in GEOCCS.\n" );
802 :
803 0 : return OGRERR_CORRUPT_DATA;
804 : }
805 : }
806 :
807 : /* -------------------------------------------------------------------- */
808 : /* For a PROJCS, validate subparameters (other than GEOGCS). */
809 : /* -------------------------------------------------------------------- */
810 62 : if( EQUAL(poRoot->GetValue(),"PROJCS") )
811 : {
812 : OGR_SRSNode *poNode;
813 : int i;
814 :
815 420 : for( i = 1; i < poRoot->GetChildCount(); i++ )
816 : {
817 363 : poNode = poRoot->GetChild(i);
818 :
819 363 : if( EQUAL(poNode->GetValue(),"GEOGCS") )
820 : {
821 : /* validated elsewhere */
822 : }
823 306 : else if( EQUAL(poNode->GetValue(),"UNIT") )
824 : {
825 9 : OGRErr eErr = ValidateUnit(poNode);
826 9 : if (eErr != OGRERR_NONE)
827 0 : return eErr;
828 : }
829 297 : else if( EQUAL(poNode->GetValue(),"PARAMETER") )
830 : {
831 232 : if( poNode->GetChildCount() != 2 )
832 : {
833 : CPLDebug( "OGRSpatialReference::Validate",
834 : "PARAMETER has wrong number of children (%d),"
835 : "not 2 as expected.\n",
836 0 : poNode->GetChildCount() );
837 :
838 0 : return OGRERR_CORRUPT_DATA;
839 : }
840 232 : else if( CSLFindString( (char **)papszParameters,
841 : poNode->GetChild(0)->GetValue()) == -1)
842 : {
843 : CPLDebug( "OGRSpatialReference::Validate",
844 : "Unrecognised PARAMETER `%s'.\n",
845 0 : poNode->GetChild(0)->GetValue() );
846 :
847 0 : return OGRERR_UNSUPPORTED_SRS;
848 : }
849 : }
850 65 : else if( EQUAL(poNode->GetValue(),"PROJECTION") )
851 : {
852 57 : if( poNode->GetChildCount() != 1 && poNode->GetChildCount() != 2 )
853 : {
854 : CPLDebug( "OGRSpatialReference::Validate",
855 : "PROJECTION has wrong number of children (%d),"
856 : "not 1 or 2 as expected.\n",
857 0 : poNode->GetChildCount() );
858 :
859 0 : return OGRERR_CORRUPT_DATA;
860 : }
861 57 : else if( CSLFindString( (char **)papszProjectionSupported,
862 : poNode->GetChild(0)->GetValue()) == -1
863 : && CSLFindString( (char **)papszProjectionUnsupported,
864 : poNode->GetChild(0)->GetValue()) == -1)
865 : {
866 : CPLDebug( "OGRSpatialReference::Validate",
867 : "Unrecognised PROJECTION `%s'.\n",
868 0 : poNode->GetChild(0)->GetValue() );
869 :
870 0 : return OGRERR_UNSUPPORTED_SRS;
871 : }
872 57 : else if( CSLFindString( (char **)papszProjectionSupported,
873 : poNode->GetChild(0)->GetValue()) == -1)
874 : {
875 : CPLDebug( "OGRSpatialReference::Validate",
876 : "Unsupported, but recognised PROJECTION `%s'.\n",
877 0 : poNode->GetChild(0)->GetValue() );
878 :
879 0 : return OGRERR_UNSUPPORTED_SRS;
880 : }
881 :
882 57 : if (poNode->GetChildCount() == 2)
883 : {
884 0 : poNode = poNode->GetChild(1);
885 0 : if( EQUAL(poNode->GetValue(),"AUTHORITY") )
886 : {
887 0 : OGRErr eErr = ValidateAuthority(poNode);
888 0 : if (eErr != OGRERR_NONE)
889 0 : return eErr;
890 : }
891 : else
892 : {
893 : CPLDebug( "OGRSpatialReference::Validate",
894 : "Unexpected child for PROJECTION `%s'.\n",
895 0 : poNode->GetValue() );
896 :
897 0 : return OGRERR_CORRUPT_DATA;
898 : }
899 : }
900 : }
901 8 : else if( EQUAL(poNode->GetValue(),"AUTHORITY") )
902 : {
903 2 : OGRErr eErr = ValidateAuthority(poNode);
904 2 : if (eErr != OGRERR_NONE)
905 0 : return eErr;
906 : }
907 6 : else if( EQUAL(poNode->GetValue(),"AXIS") )
908 : {
909 4 : OGRErr eErr = ValidateAxis(poNode);
910 4 : if (eErr != OGRERR_NONE)
911 0 : return eErr;
912 : }
913 2 : else if( EQUAL(poNode->GetValue(),"EXTENSION") )
914 : {
915 : // We do not try to control the sub-organization of
916 : // EXTENSION nodes.
917 : }
918 : else
919 : {
920 : CPLDebug( "OGRSpatialReference::Validate",
921 : "Unexpected child for PROJCS `%s'.\n",
922 0 : poNode->GetValue() );
923 :
924 0 : return OGRERR_CORRUPT_DATA;
925 : }
926 : }
927 : }
928 :
929 : /* -------------------------------------------------------------------- */
930 : /* Validate GEOGCS if found. */
931 : /* -------------------------------------------------------------------- */
932 62 : OGR_SRSNode *poGEOGCS = poRoot->GetNode( "GEOGCS" );
933 :
934 62 : if( poGEOGCS != NULL )
935 : {
936 : OGR_SRSNode *poNode;
937 : int i;
938 :
939 242 : for( i = 1; i < poGEOGCS->GetChildCount(); i++ )
940 : {
941 184 : poNode = poGEOGCS->GetChild(i);
942 :
943 184 : if( EQUAL(poNode->GetValue(),"DATUM") )
944 : {
945 : /* validated elsewhere */
946 : }
947 125 : else if( EQUAL(poNode->GetValue(),"PRIMEM") )
948 : {
949 59 : if( poNode->GetChildCount() < 2
950 : || poNode->GetChildCount() > 3 )
951 : {
952 : CPLDebug( "OGRSpatialReference::Validate",
953 : "PRIMEM has wrong number of children (%d),"
954 : "not 2 or 3 as expected.\n",
955 0 : poNode->GetChildCount() );
956 :
957 0 : return OGRERR_CORRUPT_DATA;
958 : }
959 : }
960 66 : else if( EQUAL(poNode->GetValue(),"UNIT") )
961 : {
962 59 : OGRErr eErr = ValidateUnit(poNode);
963 59 : if (eErr != OGRERR_NONE)
964 0 : return eErr;
965 : }
966 7 : else if( EQUAL(poNode->GetValue(),"AXIS") )
967 : {
968 2 : OGRErr eErr = ValidateAxis(poNode);
969 2 : if (eErr != OGRERR_NONE)
970 0 : return eErr;
971 : }
972 5 : else if( EQUAL(poNode->GetValue(),"AUTHORITY") )
973 : {
974 4 : OGRErr eErr = ValidateAuthority(poNode);
975 4 : if (eErr != OGRERR_NONE)
976 0 : return eErr;
977 : }
978 : else
979 : {
980 : CPLDebug( "OGRSpatialReference::Validate",
981 : "Unexpected child for GEOGCS `%s'.\n",
982 1 : poNode->GetValue() );
983 :
984 1 : return OGRERR_CORRUPT_DATA;
985 : }
986 : }
987 :
988 58 : if( poGEOGCS->GetNode("DATUM") == NULL )
989 : {
990 : CPLDebug( "OGRSpatialReference::Validate",
991 0 : "No DATUM child in GEOGCS.\n" );
992 :
993 0 : return OGRERR_CORRUPT_DATA;
994 : }
995 : }
996 :
997 : /* -------------------------------------------------------------------- */
998 : /* Validate DATUM/SPHEROID. */
999 : /* -------------------------------------------------------------------- */
1000 61 : OGR_SRSNode *poDATUM = poRoot->GetNode( "DATUM" );
1001 :
1002 61 : if( poDATUM != NULL )
1003 : {
1004 : OGR_SRSNode *poSPHEROID;
1005 61 : int bGotSpheroid = FALSE;
1006 : int i;
1007 :
1008 61 : if( poDATUM->GetChildCount() == 0 )
1009 : {
1010 : CPLDebug( "OGRSpatialReference::Validate",
1011 0 : "DATUM has no children." );
1012 :
1013 0 : return OGRERR_CORRUPT_DATA;
1014 : }
1015 :
1016 133 : for( i = 1; i < poDATUM->GetChildCount(); i++ )
1017 : {
1018 : OGR_SRSNode *poNode;
1019 72 : poNode = poDATUM->GetChild(i);
1020 :
1021 72 : if( EQUAL(poNode->GetValue(),"SPHEROID") )
1022 : {
1023 61 : poSPHEROID = poDATUM->GetChild(1);
1024 61 : bGotSpheroid = TRUE;
1025 :
1026 61 : if( poSPHEROID->GetChildCount() != 3
1027 : && poSPHEROID->GetChildCount() != 4 )
1028 : {
1029 : CPLDebug( "OGRSpatialReference::Validate",
1030 : "SPHEROID has wrong number of children (%d),"
1031 : "not 3 or 4 as expected.\n",
1032 0 : poSPHEROID->GetChildCount() );
1033 :
1034 0 : return OGRERR_CORRUPT_DATA;
1035 : }
1036 61 : else if( CPLAtof(poSPHEROID->GetChild(1)->GetValue()) == 0.0 )
1037 : {
1038 : CPLDebug( "OGRSpatialReference::Validate",
1039 : "SPHEROID semi-major axis is zero (%s)!\n",
1040 0 : poSPHEROID->GetChild(1)->GetValue() );
1041 0 : return OGRERR_CORRUPT_DATA;
1042 : }
1043 : }
1044 11 : else if( EQUAL(poNode->GetValue(),"AUTHORITY") )
1045 : {
1046 7 : OGRErr eErr = ValidateAuthority(poNode);
1047 7 : if (eErr != OGRERR_NONE)
1048 0 : return eErr;
1049 : }
1050 4 : else if( EQUAL(poNode->GetValue(),"TOWGS84") )
1051 : {
1052 4 : if( poNode->GetChildCount() != 3
1053 : && poNode->GetChildCount() != 7)
1054 : {
1055 : CPLDebug( "OGRSpatialReference::Validate",
1056 : "TOWGS84 has wrong number of children (%d), not 3 or 7.\n",
1057 0 : poNode->GetChildCount() );
1058 0 : return OGRERR_CORRUPT_DATA;
1059 : }
1060 : }
1061 : else
1062 : {
1063 : CPLDebug( "OGRSpatialReference::Validate",
1064 : "Unexpected child for DATUM `%s'.\n",
1065 0 : poNode->GetValue() );
1066 :
1067 0 : return OGRERR_CORRUPT_DATA;
1068 : }
1069 : }
1070 :
1071 61 : if( !bGotSpheroid )
1072 : {
1073 : CPLDebug( "OGRSpatialReference::Validate",
1074 0 : "No SPHEROID child in DATUM.\n" );
1075 :
1076 0 : return OGRERR_CORRUPT_DATA;
1077 : }
1078 : }
1079 :
1080 : /* -------------------------------------------------------------------- */
1081 : /* If this is projected, try to validate the detailed set of */
1082 : /* parameters used for the projection. */
1083 : /* -------------------------------------------------------------------- */
1084 : OGRErr eErr;
1085 :
1086 61 : eErr = ValidateProjection(poRoot);
1087 61 : if( eErr != OGRERR_NONE )
1088 0 : return eErr;
1089 :
1090 61 : return OGRERR_NONE;
1091 : }
1092 :
1093 : /************************************************************************/
1094 : /* OSRValidate() */
1095 : /************************************************************************/
1096 : /**
1097 : * \brief Validate SRS tokens.
1098 : *
1099 : * This function is the same as the C++ method OGRSpatialReference::Validate().
1100 : */
1101 61 : OGRErr OSRValidate( OGRSpatialReferenceH hSRS )
1102 :
1103 : {
1104 61 : VALIDATE_POINTER1( hSRS, "OSRValidate", CE_Failure );
1105 :
1106 61 : return ((OGRSpatialReference *) hSRS)->Validate();
1107 : }
1108 :
1109 : /************************************************************************/
1110 : /* IsAliasFor() */
1111 : /************************************************************************/
1112 :
1113 : /**
1114 : * \brief Return whether the first string passed in an acceptable alias for the
1115 : * second string according to the AliasGroupList
1116 : *
1117 : * @param pszParm1 first string
1118 : * @param pszParm2 second string
1119 : *
1120 : * @return TRUE if both strings are aliases according to the AliasGroupList, FALSE otherwise
1121 : */
1122 0 : int OGRSpatialReference::IsAliasFor( const char *pszParm1,
1123 : const char *pszParm2 )
1124 :
1125 : {
1126 : int iGroup;
1127 :
1128 : /* -------------------------------------------------------------------- */
1129 : /* Look for a group containing pszParm1. */
1130 : /* -------------------------------------------------------------------- */
1131 0 : for( iGroup = 0; papszAliasGroupList[iGroup] != NULL; iGroup++ )
1132 : {
1133 : int i;
1134 :
1135 0 : for( i = iGroup; papszAliasGroupList[i] != NULL; i++ )
1136 : {
1137 0 : if( EQUAL(pszParm1,papszAliasGroupList[i]) )
1138 0 : break;
1139 : }
1140 :
1141 0 : if( papszAliasGroupList[i] == NULL )
1142 0 : iGroup = i;
1143 : else
1144 0 : break;
1145 : }
1146 :
1147 : /* -------------------------------------------------------------------- */
1148 : /* Does this group also contain pszParm2? */
1149 : /* -------------------------------------------------------------------- */
1150 0 : while( papszAliasGroupList[iGroup] != NULL )
1151 : {
1152 0 : if( EQUAL(papszAliasGroupList[iGroup++],pszParm2) )
1153 0 : return TRUE;
1154 : }
1155 :
1156 0 : return FALSE;
1157 : }
1158 :
1159 : /************************************************************************/
1160 : /* ValidateProjection() */
1161 : /************************************************************************/
1162 :
1163 : /**
1164 : * \brief Validate the current PROJECTION's arguments.
1165 : *
1166 : * @return OGRERR_NONE if the PROJECTION's arguments validate, an error code
1167 : * otherwise
1168 : */
1169 61 : OGRErr OGRSpatialReference::ValidateProjection(OGR_SRSNode *poRoot)
1170 : {
1171 61 : OGR_SRSNode *poPROJCS = poRoot->GetNode( "PROJCS" );
1172 :
1173 61 : if( poPROJCS == NULL )
1174 4 : return OGRERR_NONE;
1175 :
1176 57 : if( poPROJCS->GetNode( "PROJECTION" ) == NULL )
1177 : {
1178 : CPLDebug( "OGRSpatialReference::Validate",
1179 0 : "PROJCS does not have PROJECTION subnode." );
1180 0 : return OGRERR_CORRUPT_DATA;
1181 : }
1182 :
1183 : /* -------------------------------------------------------------------- */
1184 : /* Find the matching group in the proj and parms table. */
1185 : /* -------------------------------------------------------------------- */
1186 : const char *pszProjection;
1187 : int iOffset;
1188 :
1189 57 : pszProjection = poPROJCS->GetNode("PROJECTION")->GetChild(0)->GetValue();
1190 :
1191 1434 : for( iOffset = 0;
1192 1377 : papszProjWithParms[iOffset] != NULL
1193 : && !EQUAL(papszProjWithParms[iOffset],pszProjection); )
1194 : {
1195 9732 : while( papszProjWithParms[iOffset] != NULL )
1196 7092 : iOffset++;
1197 1320 : iOffset++;
1198 : }
1199 :
1200 57 : if( papszProjWithParms[iOffset] == NULL )
1201 0 : return OGRERR_UNSUPPORTED_SRS;
1202 :
1203 57 : iOffset++;
1204 :
1205 : /* -------------------------------------------------------------------- */
1206 : /* Check all parameters, and verify they are in the permitted */
1207 : /* list. */
1208 : /* -------------------------------------------------------------------- */
1209 : int iNode;
1210 :
1211 477 : for( iNode = 0; iNode < poPROJCS->GetChildCount(); iNode++ )
1212 : {
1213 420 : OGR_SRSNode *poParm = poPROJCS->GetChild(iNode);
1214 : int i;
1215 : const char *pszParmName;
1216 :
1217 420 : if( !EQUAL(poParm->GetValue(),"PARAMETER") )
1218 188 : continue;
1219 :
1220 232 : pszParmName = poParm->GetChild(0)->GetValue();
1221 :
1222 653 : for( i = iOffset; papszProjWithParms[i] != NULL; i++ )
1223 : {
1224 653 : if( EQUAL(papszProjWithParms[i],pszParmName) )
1225 232 : break;
1226 : }
1227 :
1228 : /* This parameter is not an exact match, is it an alias? */
1229 232 : if( papszProjWithParms[i] == NULL )
1230 : {
1231 0 : for( i = iOffset; papszProjWithParms[i] != NULL; i++ )
1232 : {
1233 0 : if( IsAliasFor(papszProjWithParms[i],pszParmName) )
1234 0 : break;
1235 : }
1236 :
1237 0 : if( papszProjWithParms[i] == NULL )
1238 : {
1239 : CPLDebug( "OGRSpatialReference::Validate",
1240 : "PARAMETER %s for PROJECTION %s is not permitted.",
1241 0 : pszParmName, pszProjection );
1242 0 : return OGRERR_CORRUPT_DATA;
1243 : }
1244 : else
1245 : {
1246 : CPLDebug( "OGRSpatialReference::Validate",
1247 : "PARAMETER %s for PROJECTION %s is an alias for %s.",
1248 : pszParmName, pszProjection,
1249 0 : papszProjWithParms[i] );
1250 0 : return OGRERR_CORRUPT_DATA;
1251 : }
1252 : }
1253 : }
1254 :
1255 57 : return OGRERR_NONE;
1256 : }
1257 :
1258 : /************************************************************************/
1259 : /* ValidateVertDatum() */
1260 : /************************************************************************/
1261 :
1262 : /**
1263 : * \brief Validate the current VERT_DATUM's arguments.
1264 : *
1265 : * @return OGRERR_NONE if the VERT_DATUM's arguments validate, an error code
1266 : * otherwise
1267 : */
1268 1 : OGRErr OGRSpatialReference::ValidateVertDatum(OGR_SRSNode *poRoot)
1269 : {
1270 1 : if ( !EQUAL(poRoot->GetValue(), "VERT_DATUM") )
1271 0 : return OGRERR_NONE;
1272 :
1273 1 : if (poRoot->GetChildCount() < 2 )
1274 : {
1275 : CPLDebug( "OGRSpatialReference::Validate",
1276 0 : "Invalid number of children : %d", poRoot->GetChildCount() );
1277 0 : return OGRERR_CORRUPT_DATA;
1278 : }
1279 :
1280 1 : if (atoi(poRoot->GetChild(1)->GetValue()) == 0)
1281 : {
1282 : CPLDebug( "OGRSpatialReference::Validate",
1283 : "Invalid value for datum type (%s) : must be a number\n",
1284 0 : poRoot->GetChild(1)->GetValue());
1285 0 : return OGRERR_CORRUPT_DATA;
1286 : }
1287 :
1288 : OGR_SRSNode *poNode;
1289 : int i;
1290 :
1291 2 : for( i = 2; i < poRoot->GetChildCount(); i++ )
1292 : {
1293 1 : poNode = poRoot->GetChild(i);
1294 :
1295 1 : if( EQUAL(poNode->GetValue(),"AUTHORITY") )
1296 : {
1297 1 : OGRErr eErr = ValidateAuthority(poNode);
1298 1 : if (eErr != OGRERR_NONE)
1299 0 : return eErr;
1300 : }
1301 0 : else if( EQUAL(poNode->GetValue(),"EXTENSION") )
1302 : {
1303 : // We do not try to control the sub-organization of
1304 : // EXTENSION nodes.
1305 : }
1306 : else
1307 : {
1308 : CPLDebug( "OGRSpatialReference::Validate",
1309 : "Unexpected child for VERT_DATUM `%s'.\n",
1310 0 : poNode->GetValue() );
1311 :
1312 0 : return OGRERR_CORRUPT_DATA;
1313 : }
1314 : }
1315 :
1316 1 : return OGRERR_NONE;
1317 : }
1318 :
1319 : /************************************************************************/
1320 : /* ValidateAuthority() */
1321 : /************************************************************************/
1322 :
1323 : /**
1324 : * \brief Validate the current AUTHORITY's arguments.
1325 : *
1326 : * @return OGRERR_NONE if the AUTHORITY's arguments validate, an error code
1327 : * otherwise
1328 : */
1329 19 : OGRErr OGRSpatialReference::ValidateAuthority(OGR_SRSNode *poRoot)
1330 : {
1331 19 : if ( !EQUAL(poRoot->GetValue(), "AUTHORITY") )
1332 0 : return OGRERR_NONE;
1333 :
1334 19 : if( poRoot->GetChildCount() != 2 )
1335 : {
1336 : CPLDebug( "OGRSpatialReference::Validate",
1337 : "AUTHORITY has wrong number of children (%d), not 2.\n",
1338 0 : poRoot->GetChildCount() );
1339 0 : return OGRERR_CORRUPT_DATA;
1340 : }
1341 :
1342 19 : return OGRERR_NONE;
1343 : }
1344 :
1345 : /************************************************************************/
1346 : /* ValidateAxis() */
1347 : /************************************************************************/
1348 :
1349 : /**
1350 : * \brief Validate the current AXIS's arguments.
1351 : *
1352 : * @return OGRERR_NONE if the AXIS's arguments validate, an error code
1353 : * otherwise
1354 : */
1355 16 : OGRErr OGRSpatialReference::ValidateAxis(OGR_SRSNode *poRoot)
1356 : {
1357 16 : if ( !EQUAL(poRoot->GetValue(), "AXIS") )
1358 0 : return OGRERR_NONE;
1359 :
1360 16 : if( poRoot->GetChildCount() != 2 )
1361 : {
1362 : CPLDebug( "OGRSpatialReference::Validate",
1363 : "AXIS has wrong number of children (%d), not 2.\n",
1364 0 : poRoot->GetChildCount() );
1365 0 : return OGRERR_CORRUPT_DATA;
1366 : }
1367 :
1368 16 : return OGRERR_NONE;
1369 : }
1370 :
1371 :
1372 : /************************************************************************/
1373 : /* ValidateUnit() */
1374 : /************************************************************************/
1375 :
1376 : /**
1377 : * \brief Validate the current UNIT's arguments.
1378 : *
1379 : * @return OGRERR_NONE if the UNIT's arguments validate, an error code
1380 : * otherwise
1381 : */
1382 72 : OGRErr OGRSpatialReference::ValidateUnit(OGR_SRSNode *poRoot)
1383 : {
1384 72 : if ( !EQUAL(poRoot->GetValue(), "UNIT") )
1385 0 : return OGRERR_NONE;
1386 :
1387 72 : if( poRoot->GetChildCount() != 2
1388 : && poRoot->GetChildCount() != 3 )
1389 : {
1390 : CPLDebug( "OGRSpatialReference::Validate",
1391 : "UNIT has wrong number of children (%d), not 2.\n",
1392 0 : poRoot->GetChildCount() );
1393 0 : return OGRERR_CORRUPT_DATA;
1394 : }
1395 72 : else if( CPLAtof(poRoot->GetChild(1)->GetValue()) == 0.0 )
1396 : {
1397 : CPLDebug( "OGRSpatialReference::Validate",
1398 : "UNIT does not appear to have meaningful"
1399 : "coefficient (%s).\n",
1400 0 : poRoot->GetChild(1)->GetValue() );
1401 0 : return OGRERR_CORRUPT_DATA;
1402 : }
1403 :
1404 72 : return OGRERR_NONE;
1405 : }
1406 :
|