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: 2012-12-26 Functions: 9 8 88.9 %

       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                 : 

Generated by: LCOV version 1.7