LCOV - code coverage report
Current view: directory - ogr - ogr_srs_validate.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 298 179 60.1 %
Date: 2011-12-18 Functions: 9 8 88.9 %

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

Generated by: LCOV version 1.7