LCOV - code coverage report
Current view: directory - ogr - ogrspatialreference.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 1999 1526 76.3 %
Date: 2012-12-26 Functions: 242 170 70.2 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrspatialreference.cpp 25016 2012-09-30 12:03:23Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  The OGRSpatialReference class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1999,  Les Technologies SoftMap Inc.
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "ogr_spatialref.h"
      31                 : #include "ogr_p.h"
      32                 : #include "cpl_csv.h"
      33                 : #include "cpl_http.h"
      34                 : #include "cpl_atomic_ops.h"
      35                 : 
      36                 : CPL_CVSID("$Id: ogrspatialreference.cpp 25016 2012-09-30 12:03:23Z rouault $");
      37                 : 
      38                 : // The current opinion is that WKT longitudes like central meridian
      39                 : // should be relative to greenwich, not the prime meridian in use. 
      40                 : // Define the following if they should be relative to the prime meridian
      41                 : // of then geogcs.
      42                 : #undef WKT_LONGITUDE_RELATIVE_TO_PM
      43                 : 
      44                 : /************************************************************************/
      45                 : /*                           OGRPrintDouble()                           */
      46                 : /************************************************************************/
      47                 : 
      48          165478 : void OGRPrintDouble( char * pszStrBuf, double dfValue )
      49                 : 
      50                 : {
      51          165478 :     sprintf( pszStrBuf, "%.16g", dfValue );
      52                 : 
      53          165478 :     int nLen = strlen(pszStrBuf);
      54                 : 
      55                 :     // The following hack is intended to truncate some "precision" in cases
      56                 :     // that appear to be roundoff error. 
      57          165478 :     if( nLen > 15 
      58                 :         && (strcmp(pszStrBuf+nLen-6,"999999") == 0
      59                 :             || strcmp(pszStrBuf+nLen-6,"000001") == 0) )
      60                 :     {
      61            1111 :         sprintf( pszStrBuf, "%.15g", dfValue );
      62                 :     }
      63                 : 
      64                 :     // force to user periods regardless of locale.
      65          165478 :     if( strchr( pszStrBuf, ',' ) != NULL )
      66                 :     {
      67               0 :         char *pszDelim = strchr( pszStrBuf, ',' );
      68               0 :         *pszDelim = '.';
      69                 :     }
      70          165478 : }
      71                 : 
      72                 : /************************************************************************/
      73                 : /*                        OGRSpatialReference()                         */
      74                 : /************************************************************************/
      75                 : 
      76                 : /**
      77                 :  * \brief Constructor.
      78                 :  *
      79                 :  * This constructor takes an optional string argument which if passed
      80                 :  * should be a WKT representation of an SRS.  Passing this is equivalent
      81                 :  * to not passing it, and then calling importFromWkt() with the WKT string.
      82                 :  *
      83                 :  * Note that newly created objects are given a reference count of one. 
      84                 :  *
      85                 :  * The C function OSRNewSpatialReference() does the same thing as this
      86                 :  * constructor. 
      87                 :  *
      88                 :  * @param pszWKT well known text definition to which the object should
      89                 :  * be initialized, or NULL (the default). 
      90                 :  */
      91                 : 
      92           82034 : OGRSpatialReference::OGRSpatialReference( const char * pszWKT )
      93                 : 
      94                 : {
      95           82034 :     bNormInfoSet = FALSE;
      96           82034 :     nRefCount = 1;
      97           82034 :     poRoot = NULL;
      98                 : 
      99           82034 :     if( pszWKT != NULL )
     100            2136 :         importFromWkt( (char **) &pszWKT );
     101           82034 : }
     102                 : 
     103                 : /************************************************************************/
     104                 : /*                       OSRNewSpatialReference()                       */
     105                 : /************************************************************************/
     106                 : 
     107                 : /**
     108                 :  * \brief Constructor.
     109                 :  *
     110                 :  * This function is the same as OGRSpatialReference::OGRSpatialReference()
     111                 :  */
     112           15983 : OGRSpatialReferenceH CPL_STDCALL OSRNewSpatialReference( const char *pszWKT )
     113                 : 
     114                 : {
     115                 :     OGRSpatialReference * poSRS;
     116                 : 
     117           15983 :     poSRS = new OGRSpatialReference();
     118                 : 
     119           31909 :     if( pszWKT != NULL && strlen(pszWKT) > 0 )
     120                 :     {
     121             279 :         if( poSRS->importFromWkt( (char **) (&pszWKT) ) != OGRERR_NONE )
     122                 :         {
     123               0 :             delete poSRS;
     124               0 :             poSRS = NULL;
     125                 :         }
     126                 :     }
     127                 : 
     128           15983 :     return (OGRSpatialReferenceH) poSRS;
     129                 : }
     130                 : 
     131                 : /************************************************************************/
     132                 : /*                        OGRSpatialReference()                         */
     133                 : /*                                                                      */
     134                 : /*      Simple copy constructor.  See also Clone().                     */
     135                 : /************************************************************************/
     136                 : 
     137              87 : OGRSpatialReference::OGRSpatialReference(const OGRSpatialReference &oOther)
     138                 : 
     139                 : {
     140              87 :     bNormInfoSet = FALSE;
     141              87 :     nRefCount = 1;
     142              87 :     poRoot = NULL;
     143                 : 
     144              87 :     if( oOther.poRoot != NULL )
     145              87 :         poRoot = oOther.poRoot->Clone();
     146              87 : }
     147                 : 
     148                 : /************************************************************************/
     149                 : /*                        ~OGRSpatialReference()                        */
     150                 : /************************************************************************/
     151                 : 
     152                 : /**
     153                 :  * \brief OGRSpatialReference destructor. 
     154                 :  *
     155                 :  * The C function OSRDestroySpatialReference() does the same thing as this
     156                 :  * method. Preferred C++ method : OGRSpatialReference::DestroySpatialReference() 
     157                 :   *
     158                 :  * @deprecated
     159                 :  */
     160                 : 
     161           82121 : OGRSpatialReference::~OGRSpatialReference()
     162                 : 
     163                 : {
     164           82121 :     if( poRoot != NULL )
     165           77991 :         delete poRoot;
     166           82121 : }
     167                 : 
     168                 : /************************************************************************/
     169                 : /*                      DestroySpatialReference()                       */
     170                 : /************************************************************************/
     171                 : 
     172                 : /**
     173                 :  * \brief OGRSpatialReference destructor. 
     174                 :  *
     175                 :  * This static method will destroy a OGRSpatialReference.  It is
     176                 :  * equivalent to calling delete on the object, but it ensures that the
     177                 :  * deallocation is properly executed within the OGR libraries heap on
     178                 :  * platforms where this can matter (win32).  
     179                 :  *
     180                 :  * This function is the same as OSRDestroySpatialReference()
     181                 :  *
     182                 :  * @param poSRS the object to delete
     183                 :  *
     184                 :  * @since GDAL 1.7.0
     185                 :  */
     186                 :  
     187             172 : void OGRSpatialReference::DestroySpatialReference(OGRSpatialReference* poSRS)
     188                 : {
     189             172 :     delete poSRS;
     190             172 : }
     191                 : 
     192                 : /************************************************************************/
     193                 : /*                     OSRDestroySpatialReference()                     */
     194                 : /************************************************************************/
     195                 : 
     196                 : /**
     197                 :  * \brief OGRSpatialReference destructor. 
     198                 :  *
     199                 :  * This function is the same as OGRSpatialReference::~OGRSpatialReference()
     200                 :  * and OGRSpatialReference::DestroySpatialReference()
     201                 :  *
     202                 :  * @param hSRS the object to delete
     203                 :  */
     204           44918 : void CPL_STDCALL OSRDestroySpatialReference( OGRSpatialReferenceH hSRS )
     205                 : 
     206                 : {
     207           44918 :     delete ((OGRSpatialReference *) hSRS);
     208           44918 : }
     209                 : 
     210                 : /************************************************************************/
     211                 : /*                               Clear()                                */
     212                 : /************************************************************************/
     213                 : 
     214                 : /**
     215                 :  * \brief Wipe current definition.
     216                 :  *
     217                 :  * Returns OGRSpatialReference to a state with no definition, as it 
     218                 :  * exists when first created.  It does not affect reference counts.
     219                 :  */
     220                 : 
     221           25989 : void OGRSpatialReference::Clear()
     222                 : 
     223                 : {
     224           25989 :     if( poRoot )
     225             869 :         delete poRoot;
     226                 : 
     227           25989 :     poRoot = NULL;
     228                 : 
     229           25989 :     bNormInfoSet = FALSE;
     230           25989 :     dfFromGreenwich = 1.0;
     231           25989 :     dfToMeter = 1.0;
     232           25989 :     dfToDegrees = 1.0;
     233           25989 : }
     234                 : 
     235                 : /************************************************************************/
     236                 : /*                             operator=()                              */
     237                 : /************************************************************************/
     238                 : 
     239                 : OGRSpatialReference &
     240               4 : OGRSpatialReference::operator=(const OGRSpatialReference &oSource)
     241                 : 
     242                 : {
     243               4 :     Clear();
     244                 :     
     245               4 :     if( oSource.poRoot != NULL )
     246               4 :         poRoot = oSource.poRoot->Clone();
     247                 : 
     248               4 :     return *this;
     249                 : }
     250                 : 
     251                 : /************************************************************************/
     252                 : /*                             Reference()                              */
     253                 : /************************************************************************/
     254                 : 
     255                 : /**
     256                 :  * \brief Increments the reference count by one.
     257                 :  *
     258                 :  * The reference count is used keep track of the number of OGRGeometry objects
     259                 :  * referencing this SRS.
     260                 :  *
     261                 :  * The method does the same thing as the C function OSRReference(). 
     262                 :  *
     263                 :  * @return the updated reference count.
     264                 :  */
     265                 : 
     266          768667 : int OGRSpatialReference::Reference()
     267                 : 
     268                 : {
     269          768667 :     return CPLAtomicInc(&nRefCount);
     270                 : }
     271                 : 
     272                 : /************************************************************************/
     273                 : /*                            OSRReference()                            */
     274                 : /************************************************************************/
     275                 : 
     276                 : /**
     277                 :  * \brief Increments the reference count by one.
     278                 :  *
     279                 :  * This function is the same as OGRSpatialReference::Reference()
     280                 :  */
     281             233 : int OSRReference( OGRSpatialReferenceH hSRS )
     282                 : 
     283                 : {
     284             233 :     VALIDATE_POINTER1( hSRS, "OSRReference", 0 );
     285                 : 
     286             233 :     return ((OGRSpatialReference *) hSRS)->Reference();
     287                 : }
     288                 : 
     289                 : /************************************************************************/
     290                 : /*                            Dereference()                             */
     291                 : /************************************************************************/
     292                 : 
     293                 : /**
     294                 :  * \brief Decrements the reference count by one.
     295                 :  *
     296                 :  * The method does the same thing as the C function OSRDereference(). 
     297                 :  *
     298                 :  * @return the updated reference count.
     299                 :  */
     300                 : 
     301          818227 : int OGRSpatialReference::Dereference()
     302                 : 
     303                 : {
     304          818227 :     if( nRefCount <= 0 )
     305                 :         CPLDebug( "OSR", 
     306                 :                   "Dereference() called on an object with refcount %d,"
     307                 :                   "likely already destroyed!", 
     308               0 :                   nRefCount );
     309          818227 :     return CPLAtomicDec(&nRefCount);
     310                 : }
     311                 : 
     312                 : /************************************************************************/
     313                 : /*                           OSRDereference()                           */
     314                 : /************************************************************************/
     315                 : 
     316                 : /**
     317                 :  * \brief Decrements the reference count by one.
     318                 :  *
     319                 :  * This function is the same as OGRSpatialReference::Dereference()
     320                 :  */
     321           44900 : int OSRDereference( OGRSpatialReferenceH hSRS )
     322                 : 
     323                 : {
     324           44900 :     VALIDATE_POINTER1( hSRS, "OSRDereference", 0 );
     325                 : 
     326           44900 :     return ((OGRSpatialReference *) hSRS)->Dereference();
     327                 : }
     328                 : 
     329                 : /************************************************************************/
     330                 : /*                         GetReferenceCount()                          */
     331                 : /************************************************************************/
     332                 : 
     333                 : /**
     334                 :  * \fn int OGRSpatialReference::GetReferenceCount() const;
     335                 :  *
     336                 :  * \brief Fetch current reference count.
     337                 :  *
     338                 :  * @return the current reference count.
     339                 :  */
     340                 : 
     341                 : /************************************************************************/
     342                 : /*                              Release()                               */
     343                 : /************************************************************************/
     344                 : 
     345                 : /**
     346                 :  * \brief Decrements the reference count by one, and destroy if zero.
     347                 :  *
     348                 :  * The method does the same thing as the C function OSRRelease(). 
     349                 :  */
     350                 : 
     351          772366 : void OGRSpatialReference::Release()
     352                 : 
     353                 : {
     354          772366 :     CPLAssert( NULL != this );
     355                 : 
     356          772366 :     if( Dereference() <= 0 ) 
     357            3908 :         delete this;
     358          772366 : }
     359                 : 
     360                 : /************************************************************************/
     361                 : /*                             OSRRelease()                             */
     362                 : /************************************************************************/
     363                 : 
     364                 : /**
     365                 :  * \brief Decrements the reference count by one, and destroy if zero.
     366                 :  *
     367                 :  * This function is the same as OGRSpatialReference::Release()
     368                 :  */
     369               7 : void OSRRelease( OGRSpatialReferenceH hSRS )
     370                 : 
     371                 : {
     372               7 :     VALIDATE_POINTER0( hSRS, "OSRRelease" );
     373                 : 
     374               7 :     ((OGRSpatialReference *) hSRS)->Release();
     375                 : }
     376                 : 
     377                 : /************************************************************************/
     378                 : /*                              SetRoot()                               */
     379                 : /************************************************************************/
     380                 : 
     381                 : /**
     382                 :  * \brief Set the root SRS node.
     383                 :  *
     384                 :  * If the object has an existing tree of OGR_SRSNodes, they are destroyed
     385                 :  * as part of assigning the new root.  Ownership of the passed OGR_SRSNode is
     386                 :  * is assumed by the OGRSpatialReference.
     387                 :  *
     388                 :  * @param poNewRoot object to assign as root.
     389                 :  */
     390                 : 
     391           32032 : void OGRSpatialReference::SetRoot( OGR_SRSNode * poNewRoot )
     392                 : 
     393                 : {
     394           32032 :     if( poRoot != NULL )
     395               1 :         delete poRoot;
     396                 : 
     397           32032 :     poRoot = poNewRoot;
     398           32032 : }
     399                 : 
     400                 : /************************************************************************/
     401                 : /*                            GetAttrNode()                             */
     402                 : /************************************************************************/
     403                 : 
     404                 : /**
     405                 :  * \brief Find named node in tree.
     406                 :  *
     407                 :  * This method does a pre-order traversal of the node tree searching for
     408                 :  * a node with this exact value (case insensitive), and returns it.  Leaf
     409                 :  * nodes are not considered, under the assumption that they are just
     410                 :  * attribute value nodes.
     411                 :  *
     412                 :  * If a node appears more than once in the tree (such as UNIT for instance),
     413                 :  * the first encountered will be returned.  Use GetNode() on a subtree to be
     414                 :  * more specific. 
     415                 :  *
     416                 :  * @param pszNodePath the name of the node to search for.  May contain multiple
     417                 :  * components such as "GEOGCS|UNIT".
     418                 :  *
     419                 :  * @return a pointer to the node found, or NULL if none.
     420                 :  */
     421                 : 
     422         1532155 : OGR_SRSNode *OGRSpatialReference::GetAttrNode( const char * pszNodePath )
     423                 : 
     424                 : {
     425                 :     char        **papszPathTokens;
     426                 :     OGR_SRSNode *poNode;
     427                 : 
     428         1532155 :     papszPathTokens = CSLTokenizeStringComplex(pszNodePath, "|", TRUE, FALSE);
     429                 : 
     430         1532155 :     if( CSLCount( papszPathTokens ) < 1 )
     431                 :     {
     432               0 :         CSLDestroy(papszPathTokens);
     433               0 :         return NULL;
     434                 :     }
     435                 : 
     436         1532155 :     poNode = GetRoot();
     437         3198491 :     for( int i = 0; poNode != NULL && papszPathTokens[i] != NULL; i++ )
     438                 :     {
     439         1666336 :         poNode = poNode->GetNode( papszPathTokens[i] );
     440                 :     }
     441                 : 
     442         1532155 :     CSLDestroy( papszPathTokens );
     443                 : 
     444         1532155 :     return poNode;
     445                 : }
     446                 : 
     447                 : const OGR_SRSNode *
     448          865736 : OGRSpatialReference::GetAttrNode( const char * pszNodePath ) const
     449                 : 
     450                 : {
     451                 :     OGR_SRSNode *poNode;
     452                 : 
     453          865736 :     poNode = ((OGRSpatialReference *) this)->GetAttrNode(pszNodePath);
     454                 : 
     455          865736 :     return poNode;
     456                 : }
     457                 : 
     458                 : /************************************************************************/
     459                 : /*                            GetAttrValue()                            */
     460                 : /************************************************************************/
     461                 : 
     462                 : /**
     463                 :  * \brief Fetch indicated attribute of named node.
     464                 :  *
     465                 :  * This method uses GetAttrNode() to find the named node, and then extracts
     466                 :  * the value of the indicated child.  Thus a call to GetAttrValue("UNIT",1)
     467                 :  * would return the second child of the UNIT node, which is normally the
     468                 :  * length of the linear unit in meters.
     469                 :  *
     470                 :  * This method does the same thing as the C function OSRGetAttrValue().
     471                 :  *
     472                 :  * @param pszNodeName the tree node to look for (case insensitive).
     473                 :  * @param iAttr the child of the node to fetch (zero based).
     474                 :  *
     475                 :  * @return the requested value, or NULL if it fails for any reason. 
     476                 :  */
     477                 : 
     478          412363 : const char *OGRSpatialReference::GetAttrValue( const char * pszNodeName,
     479                 :                                                int iAttr ) const
     480                 : 
     481                 : {
     482                 :     const OGR_SRSNode *poNode;
     483                 : 
     484          412363 :     poNode = GetAttrNode( pszNodeName );
     485          412363 :     if( poNode == NULL )
     486           21372 :         return NULL;
     487                 : 
     488          390991 :     if( iAttr < 0 || iAttr >= poNode->GetChildCount() )
     489               0 :         return NULL;
     490                 : 
     491          390991 :     return poNode->GetChild(iAttr)->GetValue();
     492                 : }
     493                 : 
     494                 : /************************************************************************/
     495                 : /*                          OSRGetAttrValue()                           */
     496                 : /************************************************************************/
     497                 : 
     498                 : /**
     499                 :  * \brief Fetch indicated attribute of named node.
     500                 :  *
     501                 :  * This function is the same as OGRSpatialReference::GetAttrValue()
     502                 :  */
     503           20450 : const char * CPL_STDCALL OSRGetAttrValue( OGRSpatialReferenceH hSRS,
     504                 :                              const char * pszKey, int iChild )
     505                 : 
     506                 : {
     507           20450 :     VALIDATE_POINTER1( hSRS, "OSRGetAttrValue", NULL );
     508                 : 
     509           20450 :     return ((OGRSpatialReference *) hSRS)->GetAttrValue( pszKey, iChild );
     510                 : }
     511                 : 
     512                 : /************************************************************************/
     513                 : /*                               Clone()                                */
     514                 : /************************************************************************/
     515                 : 
     516                 : /**
     517                 :  * \brief Make a duplicate of this OGRSpatialReference.
     518                 :  *
     519                 :  * This method is the same as the C function OSRClone().
     520                 :  *
     521                 :  * @return a new SRS, which becomes the responsibility of the caller.
     522                 :  */
     523                 : 
     524           30711 : OGRSpatialReference *OGRSpatialReference::Clone() const
     525                 : 
     526                 : {
     527                 :     OGRSpatialReference *poNewRef;
     528                 : 
     529           30711 :     poNewRef = new OGRSpatialReference();
     530                 : 
     531           30711 :     if( poRoot != NULL )
     532           30711 :         poNewRef->poRoot = poRoot->Clone();
     533                 : 
     534           30711 :     return poNewRef;
     535                 : }
     536                 : 
     537                 : /************************************************************************/
     538                 : /*                              OSRClone()                              */
     539                 : /************************************************************************/
     540                 : 
     541                 : /**
     542                 :  * \brief Make a duplicate of this OGRSpatialReference.
     543                 :  *
     544                 :  * This function is the same as OGRSpatialReference::Clone()
     545                 :  */
     546           28841 : OGRSpatialReferenceH CPL_STDCALL OSRClone( OGRSpatialReferenceH hSRS )
     547                 : 
     548                 : {
     549           28841 :     VALIDATE_POINTER1( hSRS, "OSRClone", NULL );
     550                 : 
     551           28841 :     return (OGRSpatialReferenceH) ((OGRSpatialReference *) hSRS)->Clone();
     552                 : }
     553                 : 
     554                 : /************************************************************************/
     555                 : /*                            dumpReadable()                            */
     556                 : /*                                                                      */
     557                 : /*      Dump pretty wkt to stdout, mostly for debugging.                */
     558                 : /************************************************************************/
     559                 : 
     560               0 : void OGRSpatialReference::dumpReadable()
     561                 : 
     562                 : {
     563               0 :     char *pszPrettyWkt = NULL;
     564                 : 
     565               0 :     exportToPrettyWkt( &pszPrettyWkt, FALSE );
     566               0 :     printf( "%s\n", pszPrettyWkt );
     567               0 :     CPLFree( pszPrettyWkt );
     568               0 : }
     569                 : 
     570                 : /************************************************************************/
     571                 : /*                         exportToPrettyWkt()                          */
     572                 : /************************************************************************/
     573                 : 
     574                 : /**
     575                 :  * Convert this SRS into a a nicely formatted WKT string for display to a person.
     576                 :  *
     577                 :  * Note that the returned WKT string should be freed with OGRFree() or
     578                 :  * CPLFree() when no longer needed.  It is the responsibility of the caller.
     579                 :  *
     580                 :  * This method is the same as the C function OSRExportToPrettyWkt().
     581                 :  *
     582                 :  * @param ppszResult the resulting string is returned in this pointer.
     583                 :  * @param bSimplify TRUE if the AXIS, AUTHORITY and EXTENSION nodes should be stripped off
     584                 :  *
     585                 :  * @return currently OGRERR_NONE is always returned, but the future it
     586                 :  * is possible error conditions will develop. 
     587                 :  */
     588                 : 
     589              69 : OGRErr OGRSpatialReference::exportToPrettyWkt( char ** ppszResult, 
     590                 :                                                int bSimplify ) const
     591                 : 
     592                 : {
     593              69 :     if( poRoot == NULL )
     594                 :     {
     595               0 :         *ppszResult = CPLStrdup("");
     596               0 :         return OGRERR_NONE;
     597                 :     }
     598                 : 
     599              69 :     if( bSimplify )
     600                 :     {
     601               1 :         OGRSpatialReference *poSimpleClone = Clone();
     602                 :         OGRErr eErr;
     603                 : 
     604               1 :         poSimpleClone->GetRoot()->StripNodes( "AXIS" );
     605               1 :         poSimpleClone->GetRoot()->StripNodes( "AUTHORITY" );
     606               1 :         poSimpleClone->GetRoot()->StripNodes( "EXTENSION" );
     607               1 :         eErr = poSimpleClone->GetRoot()->exportToPrettyWkt( ppszResult, 1 );
     608               1 :         delete poSimpleClone;
     609               1 :         return eErr;
     610                 :     }
     611                 :     else
     612              68 :         return poRoot->exportToPrettyWkt( ppszResult, 1 );
     613                 : }
     614                 : 
     615                 : /************************************************************************/
     616                 : /*                        OSRExportToPrettyWkt()                        */
     617                 : /************************************************************************/
     618                 : 
     619                 : 
     620                 : /**
     621                 :  * \brief Convert this SRS into a a nicely formatted WKT string for display to a person.
     622                 :  *
     623                 :  * This function is the same as OGRSpatialReference::exportToPrettyWkt().
     624                 :  */
     625                 : 
     626              55 : OGRErr CPL_STDCALL OSRExportToPrettyWkt( OGRSpatialReferenceH hSRS, char ** ppszReturn,
     627                 :                              int bSimplify)
     628                 : 
     629                 : {
     630              55 :     VALIDATE_POINTER1( hSRS, "OSRExportToPrettyWkt", CE_Failure );
     631                 : 
     632              55 :     *ppszReturn = NULL;
     633                 : 
     634                 :     return ((OGRSpatialReference *) hSRS)->exportToPrettyWkt( ppszReturn,
     635              55 :                                                               bSimplify );
     636                 : }
     637                 : 
     638                 : /************************************************************************/
     639                 : /*                            exportToWkt()                             */
     640                 : /************************************************************************/
     641                 : 
     642                 : /**
     643                 :  * \brief Convert this SRS into WKT format.
     644                 :  *
     645                 :  * Note that the returned WKT string should be freed with OGRFree() or
     646                 :  * CPLFree() when no longer needed.  It is the responsibility of the caller.
     647                 :  *
     648                 :  * This method is the same as the C function OSRExportToWkt().
     649                 :  *
     650                 :  * @param ppszResult the resulting string is returned in this pointer.
     651                 :  *
     652                 :  * @return currently OGRERR_NONE is always returned, but the future it
     653                 :  * is possible error conditions will develop. 
     654                 :  */
     655                 :  
     656           77311 : OGRErr OGRSpatialReference::exportToWkt( char ** ppszResult ) const
     657                 : 
     658                 : {
     659           77311 :     if( poRoot == NULL )
     660                 :     {
     661              40 :         *ppszResult = CPLStrdup("");
     662              40 :         return OGRERR_NONE;
     663                 :     }
     664                 :     else
     665                 :     {
     666           77271 :         return poRoot->exportToWkt(ppszResult);
     667                 :     }
     668                 : }
     669                 : 
     670                 : /************************************************************************/
     671                 : /*                           OSRExportToWkt()                           */
     672                 : /************************************************************************/
     673                 : 
     674                 : /** 
     675                 :  * \brief Convert this SRS into WKT format.
     676                 :  *
     677                 :  * This function is the same as OGRSpatialReference::exportToWkt().
     678                 :  */
     679                 : 
     680           61420 : OGRErr CPL_STDCALL OSRExportToWkt( OGRSpatialReferenceH hSRS,
     681                 :                                    char ** ppszReturn )
     682                 : 
     683                 : {
     684           61420 :     VALIDATE_POINTER1( hSRS, "OSRExportToWkt", CE_Failure );
     685                 : 
     686           61420 :     *ppszReturn = NULL;
     687                 : 
     688           61420 :     return ((OGRSpatialReference *) hSRS)->exportToWkt( ppszReturn );
     689                 : }
     690                 : 
     691                 : /************************************************************************/
     692                 : /*                           importFromWkt()                            */
     693                 : /************************************************************************/
     694                 : 
     695                 : /**
     696                 :  * \brief Import from WKT string.
     697                 :  *
     698                 :  * This method will wipe the existing SRS definition, and
     699                 :  * reassign it based on the contents of the passed WKT string.  Only as
     700                 :  * much of the input string as needed to construct this SRS is consumed from
     701                 :  * the input string, and the input string pointer
     702                 :  * is then updated to point to the remaining (unused) input.
     703                 :  *
     704                 :  * This method is the same as the C function OSRImportFromWkt().
     705                 :  *
     706                 :  * @param ppszInput Pointer to pointer to input.  The pointer is updated to
     707                 :  * point to remaining unused input text.
     708                 :  *
     709                 :  * @return OGRERR_NONE if import succeeds, or OGRERR_CORRUPT_DATA if it
     710                 :  * fails for any reason.
     711                 :  */
     712                 : 
     713           24748 : OGRErr OGRSpatialReference::importFromWkt( char ** ppszInput )
     714                 : 
     715                 : {
     716           24748 :     if ( !ppszInput || !*ppszInput )
     717               1 :         return OGRERR_FAILURE;
     718                 : 
     719           24747 :     Clear();
     720                 : 
     721           24747 :     poRoot = new OGR_SRSNode();
     722                 : 
     723           24747 :     OGRErr eErr = poRoot->importFromWkt( ppszInput ); 
     724           24747 :     if (eErr != OGRERR_NONE)
     725              22 :         return eErr;
     726                 : 
     727                 : /* -------------------------------------------------------------------- */
     728                 : /*      The following seems to try and detect and unconsumed            */
     729                 : /*      VERTCS[] coordinate system definition (ESRI style) and to       */
     730                 : /*      import and attach it to the existing root.  Likely we will      */
     731                 : /*      need to extend this somewhat to bring it into an acceptable     */
     732                 : /*      OGRSpatialReference organization at some point.                 */
     733                 : /* -------------------------------------------------------------------- */
     734           24725 :     if (strlen(*ppszInput) > 0 && strstr(*ppszInput, "VERTCS"))
     735                 :     {
     736               0 :         if(((*ppszInput)[0]) == ',')
     737               0 :             (*ppszInput)++;
     738               0 :         OGR_SRSNode *poNewChild = new OGR_SRSNode();
     739               0 :         poRoot->AddChild( poNewChild );
     740               0 :         return poNewChild->importFromWkt( ppszInput );
     741                 :     }
     742                 : 
     743           24725 :     return eErr;
     744                 : }
     745                 : 
     746                 : /************************************************************************/
     747                 : /*                          OSRImportFromWkt()                          */
     748                 : /************************************************************************/
     749                 : 
     750                 : /**
     751                 :  * \brief Import from WKT string.
     752                 :  *
     753                 :  * This function is the same as OGRSpatialReference::importFromWkt().
     754                 :  */
     755                 : 
     756            6049 : OGRErr OSRImportFromWkt( OGRSpatialReferenceH hSRS, char **ppszInput )
     757                 : 
     758                 : {
     759            6049 :     VALIDATE_POINTER1( hSRS, "OSRImportFromWkt", CE_Failure );
     760                 : 
     761            6049 :     return ((OGRSpatialReference *) hSRS)->importFromWkt( ppszInput );
     762                 : }
     763                 : 
     764                 : /************************************************************************/
     765                 : /*                              SetNode()                               */
     766                 : /************************************************************************/
     767                 : 
     768                 : /**
     769                 :  * \brief Set attribute value in spatial reference.
     770                 :  *
     771                 :  * Missing intermediate nodes in the path will be created if not already
     772                 :  * in existance.  If the attribute has no children one will be created and
     773                 :  * assigned the value otherwise the zeroth child will be assigned the value.
     774                 :  *
     775                 :  * This method does the same as the C function OSRSetAttrValue(). 
     776                 :  *
     777                 :  * @param pszNodePath full path to attribute to be set.  For instance
     778                 :  * "PROJCS|GEOGCS|UNIT".
     779                 :  * 
     780                 :  * @param pszNewNodeValue value to be assigned to node, such as "meter". 
     781                 :  * This may be NULL if you just want to force creation of the intermediate
     782                 :  * path.
     783                 :  *
     784                 :  * @return OGRERR_NONE on success. 
     785                 :  */
     786                 : 
     787           38062 : OGRErr OGRSpatialReference::SetNode( const char * pszNodePath,
     788                 :                                      const char * pszNewNodeValue )
     789                 : 
     790                 : {
     791                 :     char        **papszPathTokens;
     792                 :     int         i;
     793                 :     OGR_SRSNode *poNode;
     794                 : 
     795           38062 :     papszPathTokens = CSLTokenizeStringComplex(pszNodePath, "|", TRUE, FALSE);
     796                 : 
     797           38062 :     if( CSLCount( papszPathTokens ) < 1 )
     798               0 :         return OGRERR_FAILURE;
     799                 : 
     800           38062 :     if( GetRoot() == NULL || !EQUAL(papszPathTokens[0],GetRoot()->GetValue()) )
     801                 :     {
     802           17175 :         SetRoot( new OGR_SRSNode( papszPathTokens[0] ) );
     803                 :     }
     804                 : 
     805           38062 :     poNode = GetRoot();
     806           58709 :     for( i = 1; papszPathTokens[i] != NULL; i++ )
     807                 :     {
     808                 :         int     j;
     809                 :         
     810           77906 :         for( j = 0; j < poNode->GetChildCount(); j++ )
     811                 :         {
     812           60940 :             if( EQUAL(poNode->GetChild( j )->GetValue(),papszPathTokens[i]) )
     813                 :             {
     814            3681 :                 poNode = poNode->GetChild(j);
     815            3681 :                 j = -1;
     816            3681 :                 break;
     817                 :             }
     818                 :         }
     819                 : 
     820           20647 :         if( j != -1 )
     821                 :         {
     822           16966 :             OGR_SRSNode *poNewNode = new OGR_SRSNode( papszPathTokens[i] );
     823           16966 :             poNode->AddChild( poNewNode );
     824           16966 :             poNode = poNewNode;
     825                 :         }
     826                 :     }
     827                 : 
     828           38062 :     CSLDestroy( papszPathTokens );
     829                 : 
     830           38062 :     if( pszNewNodeValue != NULL )
     831                 :     {
     832           38062 :         if( poNode->GetChildCount() > 0 )
     833            3921 :             poNode->GetChild(0)->SetValue( pszNewNodeValue );
     834                 :         else
     835           34141 :             poNode->AddChild( new OGR_SRSNode( pszNewNodeValue ) );
     836                 :     }
     837                 : 
     838           38062 :     return OGRERR_NONE;
     839                 : }
     840                 : 
     841                 : /************************************************************************/
     842                 : /*                          OSRSetAttrValue()                           */
     843                 : /************************************************************************/
     844                 : 
     845                 : /**
     846                 :  * \brief Set attribute value in spatial reference.
     847                 :  *
     848                 :  * This function is the same as OGRSpatialReference::SetNode()
     849                 :  */
     850             621 : OGRErr CPL_STDCALL OSRSetAttrValue( OGRSpatialReferenceH hSRS, 
     851                 :                         const char * pszPath, const char * pszValue )
     852                 : 
     853                 : {
     854             621 :     VALIDATE_POINTER1( hSRS, "OSRSetAttrValue", CE_Failure );
     855                 : 
     856             621 :     return ((OGRSpatialReference *) hSRS)->SetNode( pszPath, pszValue );
     857                 : }
     858                 : 
     859                 : /************************************************************************/
     860                 : /*                              SetNode()                               */
     861                 : /************************************************************************/
     862                 : 
     863               0 : OGRErr OGRSpatialReference::SetNode( const char *pszNodePath,
     864                 :                                      double dfValue )
     865                 : 
     866                 : {
     867                 :     char        szValue[64];
     868                 : 
     869               0 :     if( ABS(dfValue - (int) dfValue) == 0.0 )
     870               0 :         sprintf( szValue, "%d", (int) dfValue );
     871                 :     else
     872               0 :         OGRPrintDouble( szValue, dfValue );
     873                 : 
     874               0 :     return SetNode( pszNodePath, szValue );
     875                 : }
     876                 : 
     877                 : /************************************************************************/
     878                 : /*                          SetAngularUnits()                           */
     879                 : /************************************************************************/
     880                 : 
     881                 : /**
     882                 :  * \brief Set the angular units for the geographic coordinate system.
     883                 :  *
     884                 :  * This method creates a UNIT subnode with the specified values as a
     885                 :  * child of the GEOGCS node. 
     886                 :  *
     887                 :  * This method does the same as the C function OSRSetAngularUnits(). 
     888                 :  *
     889                 :  * @param pszUnitsName the units name to be used.  Some preferred units
     890                 :  * names can be found in ogr_srs_api.h such as SRS_UA_DEGREE. 
     891                 :  *
     892                 :  * @param dfInRadians the value to multiple by an angle in the indicated
     893                 :  * units to transform to radians.  Some standard conversion factors can
     894                 :  * be found in ogr_srs_api.h. 
     895                 :  *
     896                 :  * @return OGRERR_NONE on success.
     897                 :  */
     898                 : 
     899              23 : OGRErr OGRSpatialReference::SetAngularUnits( const char * pszUnitsName,
     900                 :                                              double dfInRadians )
     901                 : 
     902                 : {
     903                 :     OGR_SRSNode *poCS;
     904                 :     OGR_SRSNode *poUnits;
     905                 :     char        szValue[128];
     906                 : 
     907              23 :     bNormInfoSet = FALSE;
     908                 : 
     909              23 :     poCS = GetAttrNode( "GEOGCS" );
     910                 : 
     911              23 :     if( poCS == NULL )
     912               0 :         return OGRERR_FAILURE;
     913                 : 
     914              23 :     OGRPrintDouble( szValue, dfInRadians );
     915                 : 
     916              23 :     if( poCS->FindChild( "UNIT" ) >= 0 )
     917                 :     {
     918              23 :         poUnits = poCS->GetChild( poCS->FindChild( "UNIT" ) );
     919              23 :         if (poUnits->GetChildCount() < 2)
     920               0 :             return OGRERR_FAILURE;
     921              23 :         poUnits->GetChild(0)->SetValue( pszUnitsName );
     922              23 :         poUnits->GetChild(1)->SetValue( szValue );
     923                 :     }
     924                 :     else
     925                 :     {
     926               0 :         poUnits = new OGR_SRSNode( "UNIT" );
     927               0 :         poUnits->AddChild( new OGR_SRSNode( pszUnitsName ) );
     928               0 :         poUnits->AddChild( new OGR_SRSNode( szValue ) );
     929                 :         
     930               0 :         poCS->AddChild( poUnits );
     931                 :     }
     932                 : 
     933              23 :     return OGRERR_NONE;
     934                 : }
     935                 : 
     936                 : /************************************************************************/
     937                 : /*                         OSRSetAngularUnits()                         */
     938                 : /************************************************************************/
     939                 : 
     940                 : /**
     941                 :  * \brief Set the angular units for the geographic coordinate system.
     942                 :  *
     943                 :  * This function is the same as OGRSpatialReference::SetAngularUnits()
     944                 :  */
     945               0 : OGRErr OSRSetAngularUnits( OGRSpatialReferenceH hSRS, 
     946                 :                            const char * pszUnits, double dfInRadians )
     947                 : 
     948                 : {
     949               0 :     VALIDATE_POINTER1( hSRS, "OSRSetAngularUnits", CE_Failure );
     950                 : 
     951                 :     return ((OGRSpatialReference *) hSRS)->SetAngularUnits( pszUnits, 
     952               0 :                                                             dfInRadians );
     953                 : }
     954                 : 
     955                 : /************************************************************************/
     956                 : /*                          GetAngularUnits()                           */
     957                 : /************************************************************************/
     958                 : 
     959                 : /**
     960                 :  * \brief Fetch angular geographic coordinate system units.
     961                 :  *
     962                 :  * If no units are available, a value of "degree" and SRS_UA_DEGREE_CONV 
     963                 :  * will be assumed.  This method only checks directly under the GEOGCS node
     964                 :  * for units.
     965                 :  *
     966                 :  * This method does the same thing as the C function OSRGetAngularUnits().
     967                 :  *
     968                 :  * @param ppszName a pointer to be updated with the pointer to the 
     969                 :  * units name.  The returned value remains internal to the OGRSpatialReference
     970                 :  * and shouldn't be freed, or modified.  It may be invalidated on the next
     971                 :  * OGRSpatialReference call. 
     972                 :  *
     973                 :  * @return the value to multiply by angular distances to transform them to 
     974                 :  * radians.
     975                 :  */
     976                 : 
     977           56954 : double OGRSpatialReference::GetAngularUnits( char ** ppszName ) const
     978                 : 
     979                 : {
     980           56954 :     const OGR_SRSNode *poCS = GetAttrNode( "GEOGCS" );
     981                 : 
     982           56954 :     if( ppszName != NULL )
     983             928 :         *ppszName = (char* ) "degree";
     984                 :         
     985           56954 :     if( poCS == NULL )
     986             332 :         return CPLAtof(SRS_UA_DEGREE_CONV);
     987                 : 
     988          226485 :     for( int iChild = 0; iChild < poCS->GetChildCount(); iChild++ )
     989                 :     {
     990          226482 :         const OGR_SRSNode     *poChild = poCS->GetChild(iChild);
     991                 :         
     992          226482 :         if( EQUAL(poChild->GetValue(),"UNIT")
     993                 :             && poChild->GetChildCount() >= 2 )
     994                 :         {
     995           56619 :             if( ppszName != NULL )
     996             925 :                 *ppszName = (char *) poChild->GetChild(0)->GetValue();
     997                 :             
     998           56619 :             return CPLAtof( poChild->GetChild(1)->GetValue() );
     999                 :         }
    1000                 :     }
    1001                 : 
    1002               3 :     return 1.0;
    1003                 : }
    1004                 : 
    1005                 : /************************************************************************/
    1006                 : /*                         OSRGetAngularUnits()                         */
    1007                 : /************************************************************************/
    1008                 : 
    1009                 : /**
    1010                 :  * \brief Fetch angular geographic coordinate system units.
    1011                 :  *
    1012                 :  * This function is the same as OGRSpatialReference::GetAngularUnits()
    1013                 :  */
    1014               0 : double OSRGetAngularUnits( OGRSpatialReferenceH hSRS, char ** ppszName )
    1015                 :     
    1016                 : {
    1017               0 :     VALIDATE_POINTER1( hSRS, "OSRGetAngularUnits", 0 );
    1018                 : 
    1019               0 :     return ((OGRSpatialReference *) hSRS)->GetAngularUnits( ppszName );
    1020                 : }
    1021                 : 
    1022                 : /************************************************************************/
    1023                 : /*                 SetLinearUnitsAndUpdateParameters()                  */
    1024                 : /************************************************************************/
    1025                 : 
    1026                 : /**
    1027                 :  * \brief Set the linear units for the projection.
    1028                 :  *
    1029                 :  * This method creates a UNIT subnode with the specified values as a
    1030                 :  * child of the PROJCS or LOCAL_CS node.   It works the same as the
    1031                 :  * SetLinearUnits() method, but it also updates all existing linear
    1032                 :  * projection parameter values from the old units to the new units. 
    1033                 :  *
    1034                 :  * @param pszName the units name to be used.  Some preferred units
    1035                 :  * names can be found in ogr_srs_api.h such as SRS_UL_METER, SRS_UL_FOOT 
    1036                 :  * and SRS_UL_US_FOOT. 
    1037                 :  *
    1038                 :  * @param dfInMeters the value to multiple by a length in the indicated
    1039                 :  * units to transform to meters.  Some standard conversion factors can
    1040                 :  * be found in ogr_srs_api.h. 
    1041                 :  *
    1042                 :  * @return OGRERR_NONE on success.
    1043                 :  */
    1044                 : 
    1045              20 : OGRErr OGRSpatialReference::SetLinearUnitsAndUpdateParameters(
    1046                 :     const char *pszName, double dfInMeters )
    1047                 : 
    1048                 : {
    1049              20 :     double dfOldInMeters = GetLinearUnits();
    1050              20 :     OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
    1051                 : 
    1052              20 :     if( dfInMeters == 0.0 )
    1053               0 :         return OGRERR_FAILURE;
    1054                 : 
    1055              20 :     if( dfInMeters == dfOldInMeters || poPROJCS == NULL )
    1056              16 :         return SetLinearUnits( pszName, dfInMeters );
    1057                 : 
    1058              52 :     for( int iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
    1059                 :     {
    1060              48 :         const OGR_SRSNode     *poChild = poPROJCS->GetChild(iChild);
    1061                 :         
    1062              48 :         if( EQUAL(poChild->GetValue(),"PARAMETER")
    1063                 :             && poChild->GetChildCount() > 1 )
    1064                 :         {
    1065              23 :             char *pszParmName = CPLStrdup(poChild->GetChild(0)->GetValue());
    1066                 :             
    1067              23 :             if( IsLinearParameter( pszParmName ) )
    1068                 :             {
    1069               8 :                 double dfOldValue = GetProjParm( pszParmName );
    1070                 : 
    1071                 :                 SetProjParm( pszParmName, 
    1072               8 :                              dfOldValue * dfOldInMeters / dfInMeters );
    1073                 :             }
    1074                 : 
    1075              23 :             CPLFree( pszParmName );
    1076                 :         }
    1077                 :     }
    1078                 : 
    1079               4 :     return SetLinearUnits( pszName, dfInMeters );
    1080                 : }
    1081                 : 
    1082                 : /************************************************************************/
    1083                 : /*                OSRSetLinearUnitsAndUpdateParameters()                */
    1084                 : /************************************************************************/
    1085                 : 
    1086                 : /**
    1087                 :  * \brief Set the linear units for the projection.
    1088                 :  *
    1089                 :  * This function is the same as OGRSpatialReference::SetLinearUnitsAndUpdateParameters()
    1090                 :  */
    1091               1 : OGRErr OSRSetLinearUnitsAndUpdateParameters( OGRSpatialReferenceH hSRS, 
    1092                 :                                              const char * pszUnits, 
    1093                 :                                              double dfInMeters )
    1094                 : 
    1095                 : {
    1096               1 :     VALIDATE_POINTER1( hSRS, "OSRSetLinearUnitsAndUpdateParameters", 
    1097                 :                        CE_Failure );
    1098                 : 
    1099                 :     return ((OGRSpatialReference *) hSRS)->
    1100               1 :         SetLinearUnitsAndUpdateParameters( pszUnits, dfInMeters );
    1101                 : }
    1102                 : 
    1103                 : /************************************************************************/
    1104                 : /*                           SetLinearUnits()                           */
    1105                 : /************************************************************************/
    1106                 : 
    1107                 : /**
    1108                 :  * \brief Set the linear units for the projection.
    1109                 :  *
    1110                 :  * This method creates a UNIT subnode with the specified values as a
    1111                 :  * child of the PROJCS, GEOCCS or LOCAL_CS node. 
    1112                 :  *
    1113                 :  * This method does the same as the C function OSRSetLinearUnits(). 
    1114                 :  *
    1115                 :  * @param pszUnitsName the units name to be used.  Some preferred units
    1116                 :  * names can be found in ogr_srs_api.h such as SRS_UL_METER, SRS_UL_FOOT 
    1117                 :  * and SRS_UL_US_FOOT. 
    1118                 :  *
    1119                 :  * @param dfInMeters the value to multiple by a length in the indicated
    1120                 :  * units to transform to meters.  Some standard conversion factors can
    1121                 :  * be found in ogr_srs_api.h. 
    1122                 :  *
    1123                 :  * @return OGRERR_NONE on success.
    1124                 :  */
    1125                 : 
    1126           17170 : OGRErr OGRSpatialReference::SetLinearUnits( const char * pszUnitsName,
    1127                 :                                             double dfInMeters )
    1128                 : 
    1129                 : {
    1130           17170 :     return SetTargetLinearUnits( NULL, pszUnitsName, dfInMeters );
    1131                 : }
    1132                 : 
    1133                 : /************************************************************************/
    1134                 : /*                         OSRSetLinearUnits()                          */
    1135                 : /************************************************************************/
    1136                 : 
    1137                 : /**
    1138                 :  * \brief Set the linear units for the projection.
    1139                 :  *
    1140                 :  * This function is the same as OGRSpatialReference::SetLinearUnits()
    1141                 :  */
    1142               2 : OGRErr OSRSetLinearUnits( OGRSpatialReferenceH hSRS, 
    1143                 :                           const char * pszUnits, double dfInMeters )
    1144                 : 
    1145                 : {
    1146               2 :     VALIDATE_POINTER1( hSRS, "OSRSetLinearUnits", CE_Failure );
    1147                 : 
    1148                 :     return ((OGRSpatialReference *) hSRS)->SetLinearUnits( pszUnits, 
    1149               2 :                                                            dfInMeters );
    1150                 : }
    1151                 : 
    1152                 : /************************************************************************/
    1153                 : /*                        SetTargetLinearUnits()                        */
    1154                 : /************************************************************************/
    1155                 : 
    1156                 : /**
    1157                 :  * \brief Set the linear units for the projection.
    1158                 :  *
    1159                 :  * This method creates a UNIT subnode with the specified values as a
    1160                 :  * child of the target node. 
    1161                 :  *
    1162                 :  * This method does the same as the C function OSRSetTargetLinearUnits(). 
    1163                 :  *
    1164                 :  * @param pszTargetKey the keyword to set the linear units for.  ie. "PROJCS" or "VERT_CS"
    1165                 :  *
    1166                 :  * @param pszUnitsName the units name to be used.  Some preferred units
    1167                 :  * names can be found in ogr_srs_api.h such as SRS_UL_METER, SRS_UL_FOOT 
    1168                 :  * and SRS_UL_US_FOOT. 
    1169                 :  *
    1170                 :  * @param dfInMeters the value to multiple by a length in the indicated
    1171                 :  * units to transform to meters.  Some standard conversion factors can
    1172                 :  * be found in ogr_srs_api.h. 
    1173                 :  *
    1174                 :  * @return OGRERR_NONE on success.
    1175                 :  *
    1176                 :  * @since OGR 1.9.0
    1177                 :  */
    1178                 : 
    1179           17179 : OGRErr OGRSpatialReference::SetTargetLinearUnits( const char *pszTargetKey,
    1180                 :                                                   const char * pszUnitsName,
    1181                 :                                                   double dfInMeters )
    1182                 : 
    1183                 : {
    1184                 :     OGR_SRSNode *poCS;
    1185                 :     OGR_SRSNode *poUnits;
    1186                 :     char        szValue[128];
    1187                 : 
    1188           17179 :     bNormInfoSet = FALSE;
    1189                 : 
    1190           17179 :     if( pszTargetKey == NULL )
    1191                 :     {
    1192           17170 :         poCS = GetAttrNode( "PROJCS" );
    1193                 : 
    1194           17170 :         if( poCS == NULL )
    1195              52 :             poCS = GetAttrNode( "LOCAL_CS" );
    1196           17170 :         if( poCS == NULL )
    1197               5 :             poCS = GetAttrNode( "GEOCCS" );
    1198           17170 :         if( poCS == NULL && IsVertical() )
    1199               0 :             poCS = GetAttrNode( "VERT_CS" );
    1200                 :     }
    1201                 :     else
    1202               9 :         poCS = GetAttrNode( pszTargetKey );
    1203                 : 
    1204           17179 :     if( poCS == NULL )
    1205               0 :         return OGRERR_FAILURE;
    1206                 : 
    1207           17179 :     if( dfInMeters == (int) dfInMeters )
    1208           14916 :         sprintf( szValue, "%d", (int) dfInMeters );
    1209                 :     else
    1210            2263 :         OGRPrintDouble( szValue, dfInMeters );
    1211                 : 
    1212           17179 :     if( poCS->FindChild( "UNIT" ) >= 0 )
    1213                 :     {
    1214             105 :         poUnits = poCS->GetChild( poCS->FindChild( "UNIT" ) );
    1215             105 :         if (poUnits->GetChildCount() < 2)
    1216               0 :             return OGRERR_FAILURE;
    1217             105 :         poUnits->GetChild(0)->SetValue( pszUnitsName );
    1218             105 :         poUnits->GetChild(1)->SetValue( szValue );
    1219             105 :         if( poUnits->FindChild( "AUTHORITY" ) != -1 )
    1220               6 :             poUnits->DestroyChild( poUnits->FindChild( "AUTHORITY" ) );
    1221                 :     }
    1222                 :     else
    1223                 :     {
    1224           17074 :         poUnits = new OGR_SRSNode( "UNIT" );
    1225           34148 :         poUnits->AddChild( new OGR_SRSNode( pszUnitsName ) );
    1226           34148 :         poUnits->AddChild( new OGR_SRSNode( szValue ) );
    1227                 :         
    1228           17074 :         poCS->AddChild( poUnits );
    1229                 :     }
    1230                 : 
    1231           17179 :     return OGRERR_NONE;
    1232                 : }
    1233                 : 
    1234                 : /************************************************************************/
    1235                 : /*                         OSRSetLinearUnits()                          */
    1236                 : /************************************************************************/
    1237                 : 
    1238                 : /**
    1239                 :  * \brief Set the linear units for the target node.
    1240                 :  *
    1241                 :  * This function is the same as OGRSpatialReference::SetTargetLinearUnits()
    1242                 :  *
    1243                 :  * @since OGR 1.9.0
    1244                 :  */
    1245               1 : OGRErr OSRSetTargetLinearUnits( OGRSpatialReferenceH hSRS, 
    1246                 :                                 const char *pszTargetKey,
    1247                 :                                 const char * pszUnits, double dfInMeters )
    1248                 : 
    1249                 : {
    1250               1 :     VALIDATE_POINTER1( hSRS, "OSRSetTargetLinearUnits", CE_Failure );
    1251                 : 
    1252                 :     return ((OGRSpatialReference *) hSRS)->
    1253               1 :         SetTargetLinearUnits( pszTargetKey, pszUnits, dfInMeters );
    1254                 : }
    1255                 : 
    1256                 : /************************************************************************/
    1257                 : /*                           GetLinearUnits()                           */
    1258                 : /************************************************************************/
    1259                 : 
    1260                 : /**
    1261                 :  * \brief Fetch linear projection units. 
    1262                 :  *
    1263                 :  * If no units are available, a value of "Meters" and 1.0 will be assumed.
    1264                 :  * This method only checks directly under the PROJCS, GEOCCS or LOCAL_CS node 
    1265                 :  * for units.
    1266                 :  *
    1267                 :  * This method does the same thing as the C function OSRGetLinearUnits()/
    1268                 :  *
    1269                 :  * @param ppszName a pointer to be updated with the pointer to the 
    1270                 :  * units name.  The returned value remains internal to the OGRSpatialReference
    1271                 :  * and shouldn't be freed, or modified.  It may be invalidated on the next
    1272                 :  * OGRSpatialReference call. 
    1273                 :  *
    1274                 :  * @return the value to multiply by linear distances to transform them to 
    1275                 :  * meters.
    1276                 :  */
    1277                 : 
    1278           90682 : double OGRSpatialReference::GetLinearUnits( char ** ppszName ) const
    1279                 : 
    1280                 : {
    1281           90682 :     return GetTargetLinearUnits( NULL, ppszName );
    1282                 : }
    1283                 : 
    1284                 : /************************************************************************/
    1285                 : /*                         OSRGetLinearUnits()                          */
    1286                 : /************************************************************************/
    1287                 : 
    1288                 : /**
    1289                 :  * \brief Fetch linear projection units. 
    1290                 :  *
    1291                 :  * This function is the same as OGRSpatialReference::GetLinearUnits()
    1292                 :  */
    1293               0 : double OSRGetLinearUnits( OGRSpatialReferenceH hSRS, char ** ppszName )
    1294                 :     
    1295                 : {
    1296               0 :     VALIDATE_POINTER1( hSRS, "OSRGetLinearUnits", 0 );
    1297                 : 
    1298               0 :     return ((OGRSpatialReference *) hSRS)->GetLinearUnits( ppszName );
    1299                 : }
    1300                 : 
    1301                 : /************************************************************************/
    1302                 : /*                        GetTargetLinearUnits()                        */
    1303                 : /************************************************************************/
    1304                 : 
    1305                 : /**
    1306                 :  * \brief Fetch linear units for target. 
    1307                 :  *
    1308                 :  * If no units are available, a value of "Meters" and 1.0 will be assumed.
    1309                 :  *
    1310                 :  * This method does the same thing as the C function OSRGetTargetLinearUnits()/
    1311                 :  *
    1312                 :  * @param pszTargetKey the key to look on. ie. "PROJCS" or "VERT_CS".
    1313                 :  * @param ppszName a pointer to be updated with the pointer to the 
    1314                 :  * units name.  The returned value remains internal to the OGRSpatialReference
    1315                 :  * and shouldn't be freed, or modified.  It may be invalidated on the next
    1316                 :  * OGRSpatialReference call. 
    1317                 :  *
    1318                 :  * @return the value to multiply by linear distances to transform them to 
    1319                 :  * meters.
    1320                 :  *
    1321                 :  * @since OGR 1.9.0
    1322                 :  */
    1323                 : 
    1324           90721 : double OGRSpatialReference::GetTargetLinearUnits( const char *pszTargetKey,
    1325                 :                                                   char ** ppszName ) const
    1326                 : 
    1327                 : {
    1328                 :     const OGR_SRSNode *poCS;
    1329                 : 
    1330           90721 :     if( pszTargetKey == NULL )
    1331                 :     {
    1332           90682 :         poCS = GetAttrNode( "PROJCS" );
    1333                 : 
    1334           90682 :         if( poCS == NULL )
    1335            1545 :             poCS = GetAttrNode( "LOCAL_CS" );
    1336           90682 :         if( poCS == NULL )
    1337            1512 :             poCS = GetAttrNode( "GEOCCS" );
    1338           90682 :         if( poCS == NULL && IsVertical() )
    1339               0 :             poCS = GetAttrNode( "VERT_CS" );
    1340                 :     }
    1341                 :     else
    1342              39 :         poCS = GetAttrNode( pszTargetKey );
    1343                 : 
    1344           90721 :     if( ppszName != NULL )
    1345            3038 :         *ppszName = (char*) "unknown";
    1346                 :         
    1347           90721 :     if( poCS == NULL )
    1348            1543 :         return 1.0;
    1349                 : 
    1350          709707 :     for( int iChild = 0; iChild < poCS->GetChildCount(); iChild++ )
    1351                 :     {
    1352          707666 :         const OGR_SRSNode     *poChild = poCS->GetChild(iChild);
    1353                 :         
    1354          707666 :         if( EQUAL(poChild->GetValue(),"UNIT")
    1355                 :             && poChild->GetChildCount() >= 2 )
    1356                 :         {
    1357           87137 :             if( ppszName != NULL )
    1358             903 :                 *ppszName = (char *) poChild->GetChild(0)->GetValue();
    1359                 :             
    1360           87137 :             return CPLAtof( poChild->GetChild(1)->GetValue() );
    1361                 :         }
    1362                 :     }
    1363                 : 
    1364            2041 :     return 1.0;
    1365                 : }
    1366                 : 
    1367                 : /************************************************************************/
    1368                 : /*                      OSRGetTargetLinearUnits()                       */
    1369                 : /************************************************************************/
    1370                 : 
    1371                 : /**
    1372                 :  * \brief Fetch linear projection units. 
    1373                 :  *
    1374                 :  * This function is the same as OGRSpatialReference::GetTargetLinearUnits()
    1375                 :  *
    1376                 :  * @since OGR 1.9.0
    1377                 :  */
    1378               0 : double OSRGetTargetLinearUnits( OGRSpatialReferenceH hSRS, 
    1379                 :                                 const char *pszTargetKey, 
    1380                 :                                 char ** ppszName )
    1381                 :     
    1382                 : {
    1383               0 :     VALIDATE_POINTER1( hSRS, "OSRGetTargetLinearUnits", 0 );
    1384                 : 
    1385                 :     return ((OGRSpatialReference *) hSRS)->GetTargetLinearUnits( pszTargetKey,
    1386               0 :                                                                  ppszName );
    1387                 : }
    1388                 : 
    1389                 : /************************************************************************/
    1390                 : /*                          GetPrimeMeridian()                          */
    1391                 : /************************************************************************/
    1392                 : 
    1393                 : /**
    1394                 :  * \brief Fetch prime meridian info.
    1395                 :  *
    1396                 :  * Returns the offset of the prime meridian from greenwich in degrees,
    1397                 :  * and the prime meridian name (if requested).   If no PRIMEM value exists
    1398                 :  * in the coordinate system definition a value of "Greenwich" and an
    1399                 :  * offset of 0.0 is assumed.
    1400                 :  *
    1401                 :  * If the prime meridian name is returned, the pointer is to an internal
    1402                 :  * copy of the name. It should not be freed, altered or depended on after
    1403                 :  * the next OGR call.
    1404                 :  *
    1405                 :  * This method is the same as the C function OSRGetPrimeMeridian().
    1406                 :  *
    1407                 :  * @param ppszName return location for prime meridian name.  If NULL, name
    1408                 :  * is not returned.
    1409                 :  *
    1410                 :  * @return the offset to the GEOGCS prime meridian from greenwich in decimal
    1411                 :  * degrees.
    1412                 :  */
    1413                 : 
    1414           49612 : double OGRSpatialReference::GetPrimeMeridian( char **ppszName ) const 
    1415                 : 
    1416                 : {
    1417           49612 :     const OGR_SRSNode *poPRIMEM = GetAttrNode( "PRIMEM" );
    1418                 : 
    1419           49612 :     if( poPRIMEM != NULL && poPRIMEM->GetChildCount() >= 2 
    1420                 :         && CPLAtof(poPRIMEM->GetChild(1)->GetValue()) != 0.0 )
    1421                 :     {
    1422            1119 :         if( ppszName != NULL )
    1423               0 :             *ppszName = (char *) poPRIMEM->GetChild(0)->GetValue();
    1424            1119 :         return CPLAtof(poPRIMEM->GetChild(1)->GetValue());
    1425                 :     }
    1426                 :     
    1427           48493 :     if( ppszName != NULL )
    1428               5 :         *ppszName = (char*) SRS_PM_GREENWICH;
    1429                 : 
    1430           48493 :     return 0.0;
    1431                 : }
    1432                 : 
    1433                 : /************************************************************************/
    1434                 : /*                        OSRGetPrimeMeridian()                         */
    1435                 : /************************************************************************/
    1436                 : 
    1437                 : /**
    1438                 :  * \brief Fetch prime meridian info.
    1439                 :  *
    1440                 :  * This function is the same as OGRSpatialReference::GetPrimeMeridian()
    1441                 :  */
    1442               1 : double OSRGetPrimeMeridian( OGRSpatialReferenceH hSRS, char **ppszName )
    1443                 : 
    1444                 : {
    1445               1 :     VALIDATE_POINTER1( hSRS, "OSRGetPrimeMeridian", 0 );
    1446                 : 
    1447               1 :     return ((OGRSpatialReference *) hSRS)->GetPrimeMeridian( ppszName );
    1448                 : }
    1449                 : 
    1450                 : /************************************************************************/
    1451                 : /*                             SetGeogCS()                              */
    1452                 : /************************************************************************/
    1453                 : 
    1454                 : /**
    1455                 :  * \brief Set geographic coordinate system. 
    1456                 :  *
    1457                 :  * This method is used to set the datum, ellipsoid, prime meridian and
    1458                 :  * angular units for a geographic coordinate system.  It can be used on it's
    1459                 :  * own to establish a geographic spatial reference, or applied to a 
    1460                 :  * projected coordinate system to establish the underlying geographic 
    1461                 :  * coordinate system. 
    1462                 :  *
    1463                 :  * This method does the same as the C function OSRSetGeogCS(). 
    1464                 :  *
    1465                 :  * @param pszGeogName user visible name for the geographic coordinate system
    1466                 :  * (not to serve as a key).
    1467                 :  * 
    1468                 :  * @param pszDatumName key name for this datum.  The OpenGIS specification 
    1469                 :  * lists some known values, and otherwise EPSG datum names with a standard
    1470                 :  * transformation are considered legal keys. 
    1471                 :  * 
    1472                 :  * @param pszSpheroidName user visible spheroid name (not to serve as a key)
    1473                 :  *
    1474                 :  * @param dfSemiMajor the semi major axis of the spheroid.
    1475                 :  * 
    1476                 :  * @param dfInvFlattening the inverse flattening for the spheroid.
    1477                 :  * This can be computed from the semi minor axis as 
    1478                 :  * 1/f = 1.0 / (1.0 - semiminor/semimajor).
    1479                 :  *
    1480                 :  * @param pszPMName the name of the prime merdidian (not to serve as a key)
    1481                 :  * If this is NULL a default value of "Greenwich" will be used. 
    1482                 :  * 
    1483                 :  * @param dfPMOffset the longitude of greenwich relative to this prime
    1484                 :  * meridian.
    1485                 :  *
    1486                 :  * @param pszAngularUnits the angular units name (see ogr_srs_api.h for some
    1487                 :  * standard names).  If NULL a value of "degrees" will be assumed. 
    1488                 :  * 
    1489                 :  * @param dfConvertToRadians value to multiply angular units by to transform
    1490                 :  * them to radians.  A value of SRS_UL_DEGREE_CONV will be used if
    1491                 :  * pszAngularUnits is NULL.
    1492                 :  *
    1493                 :  * @return OGRERR_NONE on success.
    1494                 :  */
    1495                 : 
    1496                 : OGRErr
    1497           24630 : OGRSpatialReference::SetGeogCS( const char * pszGeogName,
    1498                 :                                 const char * pszDatumName,
    1499                 :                                 const char * pszSpheroidName,
    1500                 :                                 double dfSemiMajor, double dfInvFlattening,
    1501                 :                                 const char * pszPMName, double dfPMOffset,
    1502                 :                                 const char * pszAngularUnits,
    1503                 :                                 double dfConvertToRadians )
    1504                 : 
    1505                 : {
    1506           24630 :     bNormInfoSet = FALSE;
    1507                 : 
    1508                 : /* -------------------------------------------------------------------- */
    1509                 : /*      For a geocentric coordinate system we want to set the datum     */
    1510                 : /*      and ellipsoid based on the GEOGCS.  Create the GEOGCS in a      */
    1511                 : /*      temporary srs and use the copy method which has special         */
    1512                 : /*      handling for GEOCCS.                                            */
    1513                 : /* -------------------------------------------------------------------- */
    1514           24630 :     if( IsGeocentric() )
    1515                 :     {
    1516               2 :         OGRSpatialReference oGCS;
    1517                 : 
    1518                 :         oGCS.SetGeogCS( pszGeogName, pszDatumName, pszSpheroidName,
    1519                 :                         dfSemiMajor, dfInvFlattening, 
    1520                 :                         pszPMName, dfPMOffset, 
    1521               2 :                         pszAngularUnits, dfConvertToRadians );
    1522               2 :         return CopyGeogCSFrom( &oGCS );
    1523                 :     }        
    1524                 : 
    1525                 : /* -------------------------------------------------------------------- */
    1526                 : /*      Do we already have a GEOGCS?  If so, blow it away so it can     */
    1527                 : /*      be properly replaced.                                           */
    1528                 : /* -------------------------------------------------------------------- */
    1529           24628 :     if( GetAttrNode( "GEOGCS" ) != NULL )
    1530                 :     {
    1531                 :         OGR_SRSNode *poCS;
    1532                 : 
    1533               0 :         if( EQUAL(GetRoot()->GetValue(),"GEOGCS") )
    1534               0 :             Clear();
    1535               0 :         else if( (poCS = GetAttrNode( "PROJCS" )) != NULL
    1536                 :                  && poCS->FindChild( "GEOGCS" ) != -1 )
    1537               0 :             poCS->DestroyChild( poCS->FindChild( "GEOGCS" ) );
    1538                 :         else
    1539               0 :             return OGRERR_FAILURE;
    1540                 :     }
    1541                 : 
    1542                 : /* -------------------------------------------------------------------- */
    1543                 : /*      Set defaults for various parameters.                            */
    1544                 : /* -------------------------------------------------------------------- */
    1545           24628 :     if( pszGeogName == NULL )
    1546               0 :         pszGeogName = "unnamed";
    1547                 : 
    1548           24628 :     if( pszPMName == NULL )
    1549             200 :         pszPMName = SRS_PM_GREENWICH;
    1550                 : 
    1551           24628 :     if( pszDatumName == NULL )
    1552             118 :         pszDatumName = "unknown";
    1553                 : 
    1554           24628 :     if( pszSpheroidName == NULL )
    1555               0 :         pszSpheroidName = "unnamed";
    1556                 : 
    1557           24628 :     if( pszAngularUnits == NULL )
    1558                 :     {
    1559             315 :         pszAngularUnits = SRS_UA_DEGREE;
    1560             315 :         dfConvertToRadians = CPLAtof(SRS_UA_DEGREE_CONV);
    1561                 :     }
    1562                 : 
    1563                 : /* -------------------------------------------------------------------- */
    1564                 : /*      Build the GEOGCS object.                                        */
    1565                 : /* -------------------------------------------------------------------- */
    1566                 :     char                szValue[128];
    1567                 :     OGR_SRSNode         *poGeogCS, *poSpheroid, *poDatum, *poPM, *poUnits;
    1568                 : 
    1569           24628 :     poGeogCS = new OGR_SRSNode( "GEOGCS" );
    1570           49256 :     poGeogCS->AddChild( new OGR_SRSNode( pszGeogName ) );
    1571                 :     
    1572                 : /* -------------------------------------------------------------------- */
    1573                 : /*      Setup the spheroid.                                             */
    1574                 : /* -------------------------------------------------------------------- */
    1575           49256 :     poSpheroid = new OGR_SRSNode( "SPHEROID" );
    1576           49256 :     poSpheroid->AddChild( new OGR_SRSNode( pszSpheroidName ) );
    1577                 : 
    1578           24628 :     OGRPrintDouble( szValue, dfSemiMajor );
    1579           49256 :     poSpheroid->AddChild( new OGR_SRSNode(szValue) );
    1580                 : 
    1581           24628 :     OGRPrintDouble( szValue, dfInvFlattening );
    1582           49256 :     poSpheroid->AddChild( new OGR_SRSNode(szValue) );
    1583                 : 
    1584                 : /* -------------------------------------------------------------------- */
    1585                 : /*      Setup the Datum.                                                */
    1586                 : /* -------------------------------------------------------------------- */
    1587           49256 :     poDatum = new OGR_SRSNode( "DATUM" );
    1588           49256 :     poDatum->AddChild( new OGR_SRSNode(pszDatumName) );
    1589           24628 :     poDatum->AddChild( poSpheroid );
    1590                 : 
    1591                 : /* -------------------------------------------------------------------- */
    1592                 : /*      Setup the prime meridian.                                       */
    1593                 : /* -------------------------------------------------------------------- */
    1594           24628 :     if( dfPMOffset == 0.0 )
    1595           24009 :         strcpy( szValue, "0" );
    1596                 :     else
    1597             619 :         OGRPrintDouble( szValue, dfPMOffset );
    1598                 :     
    1599           24628 :     poPM = new OGR_SRSNode( "PRIMEM" );
    1600           49256 :     poPM->AddChild( new OGR_SRSNode( pszPMName ) );
    1601           49256 :     poPM->AddChild( new OGR_SRSNode( szValue ) );
    1602                 : 
    1603                 : /* -------------------------------------------------------------------- */
    1604                 : /*      Setup the rotational units.                                     */
    1605                 : /* -------------------------------------------------------------------- */
    1606           24628 :     OGRPrintDouble( szValue, dfConvertToRadians );
    1607                 :     
    1608           49256 :     poUnits = new OGR_SRSNode( "UNIT" );
    1609           49256 :     poUnits->AddChild( new OGR_SRSNode(pszAngularUnits) );
    1610           49256 :     poUnits->AddChild( new OGR_SRSNode(szValue) );
    1611                 :     
    1612                 : /* -------------------------------------------------------------------- */
    1613                 : /*      Complete the GeogCS                                             */
    1614                 : /* -------------------------------------------------------------------- */
    1615           24628 :     poGeogCS->AddChild( poDatum );
    1616           24628 :     poGeogCS->AddChild( poPM );
    1617           24628 :     poGeogCS->AddChild( poUnits );
    1618                 : 
    1619                 : /* -------------------------------------------------------------------- */
    1620                 : /*      Attach below the PROJCS if there is one, or make this the root. */
    1621                 : /* -------------------------------------------------------------------- */
    1622           41441 :     if( GetRoot() != NULL && EQUAL(GetRoot()->GetValue(),"PROJCS") )
    1623           16813 :         poRoot->InsertChild( poGeogCS, 1 );
    1624                 :     else
    1625            7815 :         SetRoot( poGeogCS );
    1626                 : 
    1627           24628 :     return OGRERR_NONE;
    1628                 : }
    1629                 : 
    1630                 : /************************************************************************/
    1631                 : /*                            OSRSetGeogCS()                            */
    1632                 : /************************************************************************/
    1633                 : 
    1634                 : /**
    1635                 :  * \brief Set geographic coordinate system. 
    1636                 :  *
    1637                 :  * This function is the same as OGRSpatialReference::SetGeogCS()
    1638                 :  */
    1639               5 : OGRErr OSRSetGeogCS( OGRSpatialReferenceH hSRS,
    1640                 :                      const char * pszGeogName,
    1641                 :                      const char * pszDatumName,
    1642                 :                      const char * pszSpheroidName,
    1643                 :                      double dfSemiMajor, double dfInvFlattening,
    1644                 :                      const char * pszPMName, double dfPMOffset,
    1645                 :                      const char * pszAngularUnits,
    1646                 :                      double dfConvertToRadians )
    1647                 : 
    1648                 : {
    1649               5 :     VALIDATE_POINTER1( hSRS, "OSRSetGeogCS", CE_Failure );
    1650                 : 
    1651                 :     return ((OGRSpatialReference *) hSRS)->SetGeogCS( 
    1652                 :         pszGeogName, pszDatumName, 
    1653                 :         pszSpheroidName, dfSemiMajor, dfInvFlattening, 
    1654               5 :         pszPMName, dfPMOffset, pszAngularUnits, dfConvertToRadians );
    1655                 :                                                       
    1656                 : }
    1657                 : 
    1658                 : /************************************************************************/
    1659                 : /*                         SetWellKnownGeogCS()                         */
    1660                 : /************************************************************************/
    1661                 : 
    1662                 : /**
    1663                 :  * \brief Set a GeogCS based on well known name.
    1664                 :  *
    1665                 :  * This may be called on an empty OGRSpatialReference to make a geographic
    1666                 :  * coordinate system, or on something with an existing PROJCS node to 
    1667                 :  * set the underlying geographic coordinate system of a projected coordinate
    1668                 :  * system. 
    1669                 :  *
    1670                 :  * The following well known text values are currently supported:
    1671                 :  * <ul>
    1672                 :  * <li> "WGS84": same as "EPSG:4326" but has no dependence on EPSG data files.
    1673                 :  * <li> "WGS72": same as "EPSG:4322" but has no dependence on EPSG data files.
    1674                 :  * <li> "NAD27": same as "EPSG:4267" but has no dependence on EPSG data files.
    1675                 :  * <li> "NAD83": same as "EPSG:4269" but has no dependence on EPSG data files.
    1676                 :  * <li> "EPSG:n": same as doing an ImportFromEPSG(n).
    1677                 :  * </ul>
    1678                 :  * 
    1679                 :  * @param pszName name of well known geographic coordinate system.
    1680                 :  * @return OGRERR_NONE on success, or OGRERR_FAILURE if the name isn't
    1681                 :  * recognised, the target object is already initialized, or an EPSG value
    1682                 :  * can't be successfully looked up.
    1683                 :  */ 
    1684                 : 
    1685            1802 : OGRErr OGRSpatialReference::SetWellKnownGeogCS( const char * pszName )
    1686                 : 
    1687                 : {
    1688            1802 :     OGRSpatialReference   oSRS2;
    1689                 :     OGRErr eErr;
    1690                 : 
    1691                 : /* -------------------------------------------------------------------- */
    1692                 : /*      Check for EPSG authority numbers.                               */
    1693                 : /* -------------------------------------------------------------------- */
    1694            1802 :     if( EQUALN(pszName, "EPSG:",5) )
    1695                 :     {
    1696               9 :         eErr = oSRS2.importFromEPSG( atoi(pszName+5) );
    1697               9 :         if( eErr != OGRERR_NONE )
    1698               0 :             return eErr;
    1699                 : 
    1700               9 :         if( !oSRS2.IsGeographic() )
    1701               0 :             return OGRERR_FAILURE;
    1702                 : 
    1703               9 :         return CopyGeogCSFrom( &oSRS2 );
    1704                 :     }
    1705                 : 
    1706                 : /* -------------------------------------------------------------------- */
    1707                 : /*      Check for EPSGA authority numbers.                               */
    1708                 : /* -------------------------------------------------------------------- */
    1709            1793 :     if( EQUALN(pszName, "EPSGA:",6) )
    1710                 :     {
    1711               0 :         eErr = oSRS2.importFromEPSGA( atoi(pszName+6) );
    1712               0 :         if( eErr != OGRERR_NONE )
    1713               0 :             return eErr;
    1714                 : 
    1715               0 :         if( !oSRS2.IsGeographic() )
    1716               0 :             return OGRERR_FAILURE;
    1717                 : 
    1718               0 :         return CopyGeogCSFrom( &oSRS2 );
    1719                 :     }
    1720                 : 
    1721                 : /* -------------------------------------------------------------------- */
    1722                 : /*      Check for simple names.                                         */
    1723                 : /* -------------------------------------------------------------------- */
    1724            1793 :     char        *pszWKT = NULL;
    1725                 : 
    1726            3461 :     if( EQUAL(pszName, "WGS84") || EQUAL(pszName,"CRS84") || EQUAL(pszName,"CRS:84") )
    1727            1668 :         pszWKT = (char* ) SRS_WKT_WGS84;
    1728                 : 
    1729             125 :     else if( EQUAL(pszName, "WGS72") )
    1730              36 :         pszWKT = (char* ) "GEOGCS[\"WGS 72\",DATUM[\"WGS_1972\",SPHEROID[\"WGS 72\",6378135,298.26,AUTHORITY[\"EPSG\",\"7043\"]],TOWGS84[0,0,4.5,0,0,0.554,0.2263],AUTHORITY[\"EPSG\",\"6322\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9108\"]],AUTHORITY[\"EPSG\",\"4322\"]]";
    1731                 : 
    1732             166 :     else if( EQUAL(pszName, "NAD27") || EQUAL(pszName, "CRS27") || EQUAL(pszName,"CRS:27") )
    1733              77 :         pszWKT = (char* ) "GEOGCS[\"NAD27\",DATUM[\"North_American_Datum_1927\",SPHEROID[\"Clarke 1866\",6378206.4,294.978698213898,AUTHORITY[\"EPSG\",\"7008\"]],AUTHORITY[\"EPSG\",\"6267\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9108\"]],AUTHORITY[\"EPSG\",\"4267\"]]";
    1734                 :         
    1735              23 :     else if( EQUAL(pszName, "NAD83") || EQUAL(pszName,"CRS83") || EQUAL(pszName,"CRS:83") )
    1736              11 :         pszWKT = (char* ) "GEOGCS[\"NAD83\",DATUM[\"North_American_Datum_1983\",SPHEROID[\"GRS 1980\",6378137,298.257222101,AUTHORITY[\"EPSG\",\"7019\"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY[\"EPSG\",\"6269\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9108\"]],AUTHORITY[\"EPSG\",\"4269\"]]";
    1737                 : 
    1738                 :     else
    1739               1 :         return OGRERR_FAILURE;
    1740                 : 
    1741                 : /* -------------------------------------------------------------------- */
    1742                 : /*      Import the WKT                                                  */
    1743                 : /* -------------------------------------------------------------------- */
    1744            1792 :     eErr = oSRS2.importFromWkt( &pszWKT );
    1745            1792 :     if( eErr != OGRERR_NONE )
    1746               0 :         return eErr;
    1747                 : 
    1748                 : /* -------------------------------------------------------------------- */
    1749                 : /*      Copy over.                                                      */
    1750                 : /* -------------------------------------------------------------------- */
    1751            1792 :     return CopyGeogCSFrom( &oSRS2 );
    1752                 : }
    1753                 : 
    1754                 : /************************************************************************/
    1755                 : /*                       OSRSetWellKnownGeogCS()                        */
    1756                 : /************************************************************************/
    1757                 : 
    1758                 : /**
    1759                 :  * \brief Set a GeogCS based on well known name.
    1760                 :  *
    1761                 :  * This function is the same as OGRSpatialReference::SetWellKnownGeogCS()
    1762                 :  */
    1763              41 : OGRErr OSRSetWellKnownGeogCS( OGRSpatialReferenceH hSRS, const char *pszName )
    1764                 : 
    1765                 : {
    1766              41 :     VALIDATE_POINTER1( hSRS, "OSRSetWellKnownGeogCS", CE_Failure );
    1767                 : 
    1768              41 :     return ((OGRSpatialReference *) hSRS)->SetWellKnownGeogCS( pszName );
    1769                 : }
    1770                 : 
    1771                 : /************************************************************************/
    1772                 : /*                           CopyGeogCSFrom()                           */
    1773                 : /************************************************************************/
    1774                 : 
    1775                 : /**
    1776                 :  * \brief Copy GEOGCS from another OGRSpatialReference.
    1777                 :  *
    1778                 :  * The GEOGCS information is copied into this OGRSpatialReference from another.
    1779                 :  * If this object has a PROJCS root already, the GEOGCS is installed within
    1780                 :  * it, otherwise it is installed as the root.
    1781                 :  * 
    1782                 :  * @param poSrcSRS the spatial reference to copy the GEOGCS information from.
    1783                 :  * 
    1784                 :  * @return OGRERR_NONE on success or an error code.
    1785                 :  */
    1786                 : 
    1787                 : 
    1788            2637 : OGRErr OGRSpatialReference::CopyGeogCSFrom( 
    1789                 :     const OGRSpatialReference * poSrcSRS )
    1790                 : 
    1791                 : {
    1792            2637 :     const OGR_SRSNode  *poGeogCS = NULL;
    1793                 : 
    1794            2637 :     bNormInfoSet = FALSE;
    1795                 : 
    1796                 : /* -------------------------------------------------------------------- */
    1797                 : /*      Handle geocentric coordinate systems specially.  We just        */
    1798                 : /*      want to copy the DATUM and PRIMEM nodes.                        */
    1799                 : /* -------------------------------------------------------------------- */
    1800            2637 :     if( IsGeocentric() )
    1801                 :     {
    1802               3 :         if( GetRoot()->FindChild( "DATUM" ) != -1 )
    1803               0 :             GetRoot()->DestroyChild( GetRoot()->FindChild( "DATUM" ) );
    1804               3 :         if( GetRoot()->FindChild( "PRIMEM" ) != -1 )
    1805               0 :             GetRoot()->DestroyChild( GetRoot()->FindChild( "PRIMEM" ) );
    1806                 : 
    1807               3 :         const OGR_SRSNode *poDatum = poSrcSRS->GetAttrNode( "DATUM" );
    1808               3 :         const OGR_SRSNode *poPrimeM = poSrcSRS->GetAttrNode( "PRIMEM" );
    1809                 : 
    1810               3 :         if( poDatum == NULL || poPrimeM == NULL )
    1811               0 :             return OGRERR_FAILURE;
    1812                 :         
    1813               3 :         poRoot->InsertChild( poDatum->Clone(), 1 );
    1814               3 :         poRoot->InsertChild( poPrimeM->Clone(), 2 );
    1815                 : 
    1816               3 :         return OGRERR_NONE;
    1817                 :         
    1818                 :     }
    1819                 : 
    1820                 : /* -------------------------------------------------------------------- */
    1821                 : /*      Do we already have a GEOGCS?  If so, blow it away so it can     */
    1822                 : /*      be properly replaced.                                           */
    1823                 : /* -------------------------------------------------------------------- */
    1824            2634 :     if( GetAttrNode( "GEOGCS" ) != NULL )
    1825                 :     {
    1826                 :         OGR_SRSNode *poPROJCS;
    1827                 : 
    1828             824 :         if( EQUAL(GetRoot()->GetValue(),"GEOGCS") )
    1829             819 :             Clear();
    1830               5 :         else if( (poPROJCS = GetAttrNode( "PROJCS" )) != NULL
    1831                 :                  && poPROJCS->FindChild( "GEOGCS" ) != -1 )
    1832               5 :             poPROJCS->DestroyChild( poPROJCS->FindChild( "GEOGCS" ) );
    1833                 :         else
    1834               0 :             return OGRERR_FAILURE;
    1835                 :     }
    1836                 : 
    1837                 : /* -------------------------------------------------------------------- */
    1838                 : /*      Find the GEOGCS node on the source.                             */
    1839                 : /* -------------------------------------------------------------------- */
    1840            2634 :     poGeogCS = poSrcSRS->GetAttrNode( "GEOGCS" );
    1841            2634 :     if( poGeogCS == NULL )
    1842               0 :         return OGRERR_FAILURE;
    1843                 : 
    1844                 : /* -------------------------------------------------------------------- */
    1845                 : /*      Attach below the PROJCS if there is one, or make this the root. */
    1846                 : /* -------------------------------------------------------------------- */
    1847            2634 :     if( GetRoot() != NULL && EQUAL(GetRoot()->GetValue(),"PROJCS") )
    1848             186 :         poRoot->InsertChild( poGeogCS->Clone(), 1 );
    1849                 :     else
    1850            2448 :         SetRoot( poGeogCS->Clone() );
    1851                 : 
    1852            2634 :     return OGRERR_NONE;
    1853                 : }
    1854                 : 
    1855                 : /************************************************************************/
    1856                 : /*                         OSRCopyGeogCSFrom()                          */
    1857                 : /************************************************************************/
    1858                 : 
    1859                 : /**
    1860                 :  * \brief Copy GEOGCS from another OGRSpatialReference.
    1861                 :  *
    1862                 :  * This function is the same as OGRSpatialReference::CopyGeogCSFrom()
    1863                 :  */
    1864               0 : OGRErr OSRCopyGeogCSFrom( OGRSpatialReferenceH hSRS, 
    1865                 :                           OGRSpatialReferenceH hSrcSRS )
    1866                 : 
    1867                 : {
    1868               0 :     VALIDATE_POINTER1( hSRS, "OSRCopyGeogCSFrom", CE_Failure );
    1869               0 :     VALIDATE_POINTER1( hSrcSRS, "OSRCopyGeogCSFrom", CE_Failure );
    1870                 : 
    1871                 :     return ((OGRSpatialReference *) hSRS)->CopyGeogCSFrom( 
    1872               0 :         (const OGRSpatialReference *) hSrcSRS );
    1873                 : }
    1874                 : 
    1875                 : /************************************************************************/
    1876                 : /*                          SetFromUserInput()                          */
    1877                 : /************************************************************************/
    1878                 : 
    1879                 : /**
    1880                 :  * \brief Set spatial reference from various text formats.
    1881                 :  *
    1882                 :  * This method will examine the provided input, and try to deduce the
    1883                 :  * format, and then use it to initialize the spatial reference system.  It
    1884                 :  * may take the following forms:
    1885                 :  *
    1886                 :  * <ol>
    1887                 :  * <li> Well Known Text definition - passed on to importFromWkt().
    1888                 :  * <li> "EPSG:n" - number passed on to importFromEPSG(). 
    1889                 :  * <li> "EPSGA:n" - number passed on to importFromEPSGA(). 
    1890                 :  * <li> "AUTO:proj_id,unit_id,lon0,lat0" - WMS auto projections.
    1891                 :  * <li> "urn:ogc:def:crs:EPSG::n" - ogc urns
    1892                 :  * <li> PROJ.4 definitions - passed on to importFromProj4().
    1893                 :  * <li> filename - file read for WKT, XML or PROJ.4 definition.
    1894                 :  * <li> well known name accepted by SetWellKnownGeogCS(), such as NAD27, NAD83,
    1895                 :  * WGS84 or WGS72. 
    1896                 :  * <li> WKT (directly or in a file) in ESRI format should be prefixed with
    1897                 :  * ESRI:: to trigger an automatic morphFromESRI().
    1898                 :  * <li> "IGNF:xxx" - "+init=IGNF:xxx" passed on to importFromProj4().
    1899                 :  * </ol>
    1900                 :  *
    1901                 :  * It is expected that this method will be extended in the future to support
    1902                 :  * XML and perhaps a simplified "minilanguage" for indicating common UTM and
    1903                 :  * State Plane definitions. 
    1904                 :  *
    1905                 :  * This method is intended to be flexible, but by it's nature it is 
    1906                 :  * imprecise as it must guess information about the format intended.  When
    1907                 :  * possible applications should call the specific method appropriate if the
    1908                 :  * input is known to be in a particular format. 
    1909                 :  *
    1910                 :  * This method does the same thing as the OSRSetFromUserInput() function.
    1911                 :  * 
    1912                 :  * @param pszDefinition text definition to try to deduce SRS from.
    1913                 :  *
    1914                 :  * @return OGRERR_NONE on success, or an error code if the name isn't
    1915                 :  * recognised, the definition is corrupt, or an EPSG value can't be 
    1916                 :  * successfully looked up.
    1917                 :  */ 
    1918                 : 
    1919           12781 : OGRErr OGRSpatialReference::SetFromUserInput( const char * pszDefinition )
    1920                 : 
    1921                 : {
    1922           12781 :     int     bESRI = FALSE;
    1923                 :     OGRErr  err;
    1924                 : 
    1925           12781 :     if( EQUALN(pszDefinition,"ESRI::",6) )
    1926                 :     {
    1927               1 :         bESRI = TRUE;
    1928               1 :         pszDefinition += 6;
    1929                 :     }
    1930                 : 
    1931                 : /* -------------------------------------------------------------------- */
    1932                 : /*      Is it a recognised syntax?                                      */
    1933                 : /* -------------------------------------------------------------------- */
    1934           12781 :     if( EQUALN(pszDefinition,"PROJCS",6)
    1935                 :         || EQUALN(pszDefinition,"GEOGCS",6)
    1936                 :         || EQUALN(pszDefinition,"COMPD_CS",8)
    1937                 :         || EQUALN(pszDefinition,"GEOCCS",6)
    1938                 :         || EQUALN(pszDefinition,"VERT_CS",7)
    1939                 :         || EQUALN(pszDefinition,"LOCAL_CS",8) )
    1940                 :     {
    1941           11951 :         err = importFromWkt( (char **) &pszDefinition );
    1942           11951 :         if( err == OGRERR_NONE && bESRI )
    1943               1 :             err = morphFromESRI();
    1944                 : 
    1945           11951 :         return err;
    1946                 :     }
    1947                 : 
    1948             830 :     if( EQUALN(pszDefinition,"EPSG:",5) 
    1949                 :         || EQUALN(pszDefinition,"EPSGA:",6) )
    1950                 :     {
    1951                 :         OGRErr eStatus; 
    1952                 : 
    1953             324 :         if( EQUALN(pszDefinition,"EPSG:",5) )
    1954             323 :             eStatus = importFromEPSG( atoi(pszDefinition+5) );
    1955                 :         
    1956                 :         else /* if( EQUALN(pszDefinition,"EPSGA:",6) ) */
    1957               1 :             eStatus = importFromEPSGA( atoi(pszDefinition+6) );
    1958                 :         
    1959                 :         // Do we want to turn this into a compound definition
    1960                 :         // with a vertical datum?
    1961             324 :         if( eStatus == OGRERR_NONE && strchr( pszDefinition, '+' ) != NULL )
    1962                 :         {
    1963               1 :             OGRSpatialReference oVertSRS;
    1964                 : 
    1965                 :             eStatus = oVertSRS.importFromEPSG( 
    1966               1 :                 atoi(strchr(pszDefinition,'+')+1) );
    1967               1 :             if( eStatus == OGRERR_NONE )
    1968                 :             {
    1969               1 :                 OGR_SRSNode *poHorizSRS = GetRoot()->Clone();
    1970                 : 
    1971               1 :                 Clear();
    1972                 : 
    1973               1 :                 CPLString osName = poHorizSRS->GetChild(0)->GetValue();
    1974               1 :                 osName += " + ";
    1975               1 :                 osName += oVertSRS.GetRoot()->GetValue();
    1976                 : 
    1977               1 :                 SetNode( "COMPD_CS", osName );
    1978               1 :                 GetRoot()->AddChild( poHorizSRS );
    1979               1 :                 GetRoot()->AddChild( oVertSRS.GetRoot()->Clone() );
    1980                 :             }
    1981                 :             
    1982               1 :             return eStatus;
    1983                 :         }
    1984                 :         else
    1985             323 :             return eStatus;
    1986                 :     }
    1987                 : 
    1988             506 :     if( EQUALN(pszDefinition,"urn:ogc:def:crs:",16)
    1989                 :         || EQUALN(pszDefinition,"urn:ogc:def:crs,crs:",20)
    1990                 :         || EQUALN(pszDefinition,"urn:x-ogc:def:crs:",18)
    1991                 :         || EQUALN(pszDefinition,"urn:opengis:crs:",16)
    1992                 :         || EQUALN(pszDefinition,"urn:opengis:def:crs:",20))
    1993             315 :         return importFromURN( pszDefinition );
    1994                 : 
    1995             191 :     if( EQUALN(pszDefinition,"http://opengis.net/def/crs",26)
    1996                 :         || EQUALN(pszDefinition,"http://www.opengis.net/def/crs",30)
    1997                 :         || EQUALN(pszDefinition,"www.opengis.net/def/crs",23))
    1998               2 :         return importFromCRSURL( pszDefinition );
    1999                 : 
    2000             189 :     if( EQUALN(pszDefinition,"AUTO:",5) )
    2001               0 :         return importFromWMSAUTO( pszDefinition );
    2002                 : 
    2003             189 :     if( EQUALN(pszDefinition,"OGC:",4) )  // WMS/WCS OGC codes like OGC:CRS84
    2004               0 :         return SetWellKnownGeogCS( pszDefinition+4 );
    2005                 : 
    2006             189 :     if( EQUALN(pszDefinition,"CRS:",4) )
    2007               1 :         return SetWellKnownGeogCS( pszDefinition );
    2008                 : 
    2009             188 :     if( EQUALN(pszDefinition,"DICT:",5) 
    2010                 :         && strstr(pszDefinition,",") )
    2011                 :     {
    2012               0 :         char *pszFile = CPLStrdup(pszDefinition+5);
    2013               0 :         char *pszCode = strstr(pszFile,",") + 1;
    2014                 :         
    2015               0 :         pszCode[-1] = '\0';
    2016                 : 
    2017               0 :         err = importFromDict( pszFile, pszCode );
    2018               0 :         CPLFree( pszFile );
    2019                 : 
    2020               0 :         if( err == OGRERR_NONE && bESRI )
    2021               0 :             err = morphFromESRI();
    2022                 : 
    2023               0 :         return err;
    2024                 :     }
    2025                 : 
    2026             188 :     if( EQUAL(pszDefinition,"NAD27") 
    2027                 :         || EQUAL(pszDefinition,"NAD83") 
    2028                 :         || EQUAL(pszDefinition,"WGS84") 
    2029                 :         || EQUAL(pszDefinition,"WGS72") )
    2030                 :     {
    2031             118 :         Clear();
    2032             118 :         return SetWellKnownGeogCS( pszDefinition );
    2033                 :     }
    2034                 : 
    2035              70 :     if( strstr(pszDefinition,"+proj") != NULL 
    2036                 :              || strstr(pszDefinition,"+init") != NULL )
    2037              61 :         return importFromProj4( pszDefinition );
    2038                 : 
    2039               9 :     if( EQUALN(pszDefinition,"IGNF:", 5) )
    2040                 :     {
    2041               0 :         char* pszProj4Str = (char*) CPLMalloc(6 + strlen(pszDefinition) + 1);
    2042               0 :         strcpy(pszProj4Str, "+init=");
    2043               0 :         strcat(pszProj4Str, pszDefinition);
    2044               0 :         err = importFromProj4( pszProj4Str );
    2045               0 :         CPLFree(pszProj4Str);
    2046                 : 
    2047               0 :         return err;
    2048                 :     }
    2049                 : 
    2050               9 :     if( EQUALN(pszDefinition,"http://",7) )
    2051                 :     {
    2052               0 :         return importFromUrl (pszDefinition);
    2053                 :     }
    2054                 : 
    2055               9 :     if( EQUAL(pszDefinition,"osgb:BNG") )
    2056                 :     {
    2057               3 :         return importFromEPSG(27700);
    2058                 :     }
    2059                 : 
    2060                 : /* -------------------------------------------------------------------- */
    2061                 : /*      Try to open it as a file.                                       */
    2062                 : /* -------------------------------------------------------------------- */
    2063                 :     FILE        *fp;
    2064               6 :     int         nBufMax = 100000;
    2065                 :     char        *pszBufPtr, *pszBuffer;
    2066                 :     int         nBytes;
    2067                 : 
    2068               6 :     fp = VSIFOpen( pszDefinition, "rt" );
    2069               6 :     if( fp == NULL )
    2070               3 :         return OGRERR_CORRUPT_DATA;
    2071                 : 
    2072               3 :     pszBuffer = (char *) CPLMalloc(nBufMax);
    2073               3 :     nBytes = VSIFRead( pszBuffer, 1, nBufMax-1, fp );
    2074               3 :     VSIFClose( fp );
    2075                 : 
    2076               3 :     if( nBytes == nBufMax-1 )
    2077                 :     {
    2078                 :         CPLDebug( "OGR", 
    2079                 :                   "OGRSpatialReference::SetFromUserInput(%s), opened file\n"
    2080                 :                   "but it is to large for our generous buffer.  Is it really\n"
    2081               0 :                   "just a WKT definition?", pszDefinition );
    2082               0 :         CPLFree( pszBuffer );
    2083               0 :         return OGRERR_FAILURE;
    2084                 :     }
    2085                 : 
    2086               3 :     pszBuffer[nBytes] = '\0';
    2087                 : 
    2088               3 :     pszBufPtr = pszBuffer;
    2089               6 :     while( pszBufPtr[0] == ' ' || pszBufPtr[0] == '\n' )
    2090               0 :         pszBufPtr++;
    2091                 : 
    2092               3 :     if( pszBufPtr[0] == '<' )
    2093               0 :         err = importFromXML( pszBufPtr );
    2094               3 :     else if( (strstr(pszBuffer,"+proj") != NULL  
    2095                 :               || strstr(pszBuffer,"+init") != NULL)
    2096                 :              && (strstr(pszBuffer,"EXTENSION") == NULL
    2097                 :                  && strstr(pszBuffer,"extension") == NULL) )
    2098               0 :         err = importFromProj4( pszBufPtr );
    2099                 :     else
    2100                 :     {
    2101               3 :         if( EQUALN(pszBufPtr,"ESRI::",6) )
    2102                 :         {
    2103               2 :             bESRI = TRUE;
    2104               2 :             pszBufPtr += 6;
    2105                 :         }
    2106                 : 
    2107               3 :         err = importFromWkt( &pszBufPtr );
    2108               3 :         if( err == OGRERR_NONE && bESRI )
    2109               2 :             err = morphFromESRI();
    2110                 :     }
    2111                 : 
    2112               3 :     CPLFree( pszBuffer );
    2113                 : 
    2114               3 :     return err;
    2115                 : }
    2116                 : 
    2117                 : /************************************************************************/
    2118                 : /*                        OSRSetFromUserInput()                         */
    2119                 : /************************************************************************/
    2120                 : 
    2121                 : /**
    2122                 :  * \brief Set spatial reference from various text formats.
    2123                 :  *
    2124                 :  * This function is the same as OGRSpatialReference::SetFromUserInput()
    2125                 :  */
    2126             284 : OGRErr CPL_STDCALL OSRSetFromUserInput( OGRSpatialReferenceH hSRS, 
    2127                 :                                         const char *pszDef )
    2128                 : 
    2129                 : {
    2130             284 :     VALIDATE_POINTER1( hSRS, "OSRSetFromUserInput", CE_Failure );
    2131                 : 
    2132             284 :     return ((OGRSpatialReference *) hSRS)->SetFromUserInput( pszDef );
    2133                 : }
    2134                 : 
    2135                 : 
    2136                 : /************************************************************************/
    2137                 : /*                          ImportFromUrl()                             */
    2138                 : /************************************************************************/
    2139                 : 
    2140                 : /**
    2141                 :  * \brief Set spatial reference from a URL.
    2142                 :  *
    2143                 :  * This method will download the spatial reference at a given URL and 
    2144                 :  * feed it into SetFromUserInput for you.  
    2145                 :  *
    2146                 :  * This method does the same thing as the OSRImportFromUrl() function.
    2147                 :  * 
    2148                 :  * @param pszUrl text definition to try to deduce SRS from.
    2149                 :  *
    2150                 :  * @return OGRERR_NONE on success, or an error code with the curl 
    2151                 :  * error message if it is unable to dowload data.
    2152                 :  */ 
    2153                 : 
    2154               2 : OGRErr OGRSpatialReference::importFromUrl( const char * pszUrl )
    2155                 : 
    2156                 : {
    2157                 : 
    2158                 : 
    2159               2 :     if( !EQUALN(pszUrl,"http://",7) )
    2160                 :     {
    2161                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2162                 :                   "The given string is not recognized as a URL"
    2163               0 :                   "starting with 'http://' -- %s", pszUrl );
    2164               0 :         return OGRERR_FAILURE;
    2165                 :     }
    2166                 : 
    2167                 : /* -------------------------------------------------------------------- */
    2168                 : /*      Fetch the result.                                               */
    2169                 : /* -------------------------------------------------------------------- */
    2170               2 :     CPLErrorReset();
    2171                 : 
    2172               2 :     const char* pszHeaders = "HEADERS=Accept: application/x-ogcwkt";
    2173               2 :     const char* pszTimeout = "TIMEOUT=10";
    2174                 :     char *apszOptions[] = { 
    2175                 :         (char *) pszHeaders,
    2176                 :         (char *) pszTimeout,
    2177                 :         NULL 
    2178               2 :     };
    2179                 :         
    2180               2 :     CPLHTTPResult *psResult = CPLHTTPFetch( pszUrl, apszOptions );
    2181                 : 
    2182                 : /* -------------------------------------------------------------------- */
    2183                 : /*      Try to handle errors.                                           */
    2184                 : /* -------------------------------------------------------------------- */
    2185                 : 
    2186               2 :     if ( psResult == NULL)
    2187               0 :         return OGRERR_FAILURE;
    2188               2 :     if( psResult->nDataLen == 0 
    2189                 :         || CPLGetLastErrorNo() != 0 || psResult->pabyData == NULL  )
    2190                 :     {
    2191               0 :         if (CPLGetLastErrorNo() == 0)
    2192                 :         {
    2193                 :             CPLError( CE_Failure, CPLE_AppDefined, 
    2194               0 :                     "No data was returned from the given URL" );
    2195                 :         }
    2196               0 :         CPLHTTPDestroyResult( psResult );
    2197               0 :         return OGRERR_FAILURE;
    2198                 :     }
    2199                 : 
    2200               2 :     if (psResult->nStatus != 0) 
    2201                 :     {
    2202                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2203               0 :                   "Curl reports error: %d: %s", psResult->nStatus, psResult->pszErrBuf );
    2204               0 :         CPLHTTPDestroyResult( psResult );
    2205               0 :         return OGRERR_FAILURE;        
    2206                 :     }
    2207                 : 
    2208               2 :     if( EQUALN( (const char*) psResult->pabyData,"http://",7) )
    2209                 :     {
    2210                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2211                 :                   "The data that was downloaded also starts with 'http://' "
    2212                 :                   "and cannot be passed into SetFromUserInput.  Is this "
    2213               0 :                   "really a spatial reference definition? ");
    2214               0 :         CPLHTTPDestroyResult( psResult );
    2215               0 :         return OGRERR_FAILURE;
    2216                 :     }
    2217               2 :     if( OGRERR_NONE != SetFromUserInput( (const char *) psResult->pabyData )) {
    2218               0 :         CPLHTTPDestroyResult( psResult );        
    2219               0 :         return OGRERR_FAILURE;
    2220                 :     }
    2221                 : 
    2222               2 :     CPLHTTPDestroyResult( psResult );
    2223               2 :     return OGRERR_NONE;
    2224                 : }
    2225                 : 
    2226                 : /************************************************************************/
    2227                 : /*                        OSRimportFromUrl()                            */
    2228                 : /************************************************************************/
    2229                 : 
    2230                 : /**
    2231                 :  * \brief Set spatial reference from a URL.
    2232                 :  *
    2233                 :  * This function is the same as OGRSpatialReference::importFromUrl()
    2234                 :  */
    2235               2 : OGRErr OSRImportFromUrl( OGRSpatialReferenceH hSRS, const char *pszUrl )
    2236                 : 
    2237                 : {
    2238               2 :     VALIDATE_POINTER1( hSRS, "OSRImportFromUrl", CE_Failure );
    2239                 : 
    2240               2 :     return ((OGRSpatialReference *) hSRS)->importFromUrl( pszUrl );
    2241                 : }
    2242                 : 
    2243                 : /************************************************************************/
    2244                 : /*                         importFromURNPart()                          */
    2245                 : /************************************************************************/
    2246             517 : OGRErr OGRSpatialReference::importFromURNPart(const char* pszAuthority,
    2247                 :                                               const char* pszCode,
    2248                 :                                               const char* pszURN)
    2249                 : {
    2250                 : 
    2251                 : /* -------------------------------------------------------------------- */
    2252                 : /*      Is this an EPSG code? Note that we import it with EPSG          */
    2253                 : /*      preferred axis ordering for geographic coordinate systems!      */
    2254                 : /* -------------------------------------------------------------------- */
    2255             517 :     if( EQUALN(pszAuthority,"EPSG",4) )
    2256             515 :         return importFromEPSGA( atoi(pszCode) );
    2257                 : 
    2258                 : /* -------------------------------------------------------------------- */
    2259                 : /*      Is this an IAU code?  Lets try for the IAU2000 dictionary.      */
    2260                 : /* -------------------------------------------------------------------- */
    2261               2 :     if( EQUALN(pszAuthority,"IAU",3) )
    2262               0 :         return importFromDict( "IAU2000.wkt", pszCode );
    2263                 : 
    2264                 : /* -------------------------------------------------------------------- */
    2265                 : /*      Is this an OGC code?                                            */
    2266                 : /* -------------------------------------------------------------------- */
    2267               2 :     if( !EQUALN(pszAuthority,"OGC",3) )
    2268                 :     {
    2269                 :         CPLError( CE_Failure, CPLE_AppDefined,
    2270                 :                   "URN %s has unrecognised authority.",
    2271               0 :                   pszURN );
    2272               0 :         return OGRERR_FAILURE;
    2273                 :     }
    2274                 : 
    2275               2 :     if( EQUALN(pszCode,"CRS84",5) )
    2276               1 :         return SetWellKnownGeogCS( pszCode );
    2277               1 :     else if( EQUALN(pszCode,"CRS83",5) )
    2278               0 :         return SetWellKnownGeogCS( pszCode );
    2279               1 :     else if( EQUALN(pszCode,"CRS27",5) )
    2280               0 :         return SetWellKnownGeogCS( pszCode );
    2281                 : 
    2282                 : /* -------------------------------------------------------------------- */
    2283                 : /*      Handle auto codes.  We need to convert from format              */
    2284                 : /*      AUTO42001:99:8888 to format AUTO:42001,99,8888.                 */
    2285                 : /* -------------------------------------------------------------------- */
    2286               1 :     else if( EQUALN(pszCode,"AUTO",4) )
    2287                 :     {
    2288                 :         char szWMSAuto[100];
    2289                 :         int i;
    2290                 : 
    2291               1 :         if( strlen(pszCode) > sizeof(szWMSAuto)-2 )
    2292               0 :             return OGRERR_FAILURE;
    2293                 : 
    2294               1 :         strcpy( szWMSAuto, "AUTO:" );
    2295               1 :         strcpy( szWMSAuto + 5, pszCode + 4 );
    2296              14 :         for( i = 5; szWMSAuto[i] != '\0'; i++ )
    2297                 :         {
    2298              13 :             if( szWMSAuto[i] == ':' )
    2299               2 :                 szWMSAuto[i] = ',';
    2300                 :         }
    2301                 : 
    2302               1 :         return importFromWMSAUTO( szWMSAuto );
    2303                 :     }
    2304                 : 
    2305                 : /* -------------------------------------------------------------------- */
    2306                 : /*      Not a recognise OGC item.                                       */
    2307                 : /* -------------------------------------------------------------------- */
    2308                 :     CPLError( CE_Failure, CPLE_AppDefined,
    2309                 :               "URN %s value not supported.",
    2310               0 :               pszURN );
    2311                 : 
    2312               0 :     return OGRERR_FAILURE;
    2313                 : }
    2314                 : 
    2315                 : /************************************************************************/
    2316                 : /*                           importFromURN()                            */
    2317                 : /*                                                                      */
    2318                 : /*      See OGC recommendation paper 06-023r1 or later for details.     */
    2319                 : /************************************************************************/
    2320                 : 
    2321                 : /**
    2322                 :  * \brief Initialize from OGC URN. 
    2323                 :  *
    2324                 :  * Initializes this spatial reference from a coordinate system defined
    2325                 :  * by an OGC URN prefixed with "urn:ogc:def:crs:" per recommendation 
    2326                 :  * paper 06-023r1.  Currently EPSG and OGC authority values are supported, 
    2327                 :  * including OGC auto codes, but not including CRS1 or CRS88 (NAVD88). 
    2328                 :  *
    2329                 :  * This method is also support through SetFromUserInput() which can
    2330                 :  * normally be used for URNs.
    2331                 :  * 
    2332                 :  * @param pszURN the urn string. 
    2333                 :  *
    2334                 :  * @return OGRERR_NONE on success or an error code.
    2335                 :  */
    2336                 : 
    2337             513 : OGRErr OGRSpatialReference::importFromURN( const char *pszURN )
    2338                 : 
    2339                 : {
    2340                 :     const char *pszCur;
    2341                 : 
    2342             513 :     if( EQUALN(pszURN,"urn:ogc:def:crs:",16) )
    2343             461 :         pszCur = pszURN + 16;
    2344              52 :     else if( EQUALN(pszURN,"urn:ogc:def:crs,crs:",20) )
    2345               1 :         pszCur = pszURN + 20;
    2346              51 :     else if( EQUALN(pszURN,"urn:x-ogc:def:crs:",18) )
    2347              51 :         pszCur = pszURN + 18;
    2348               0 :     else if( EQUALN(pszURN,"urn:opengis:crs:",16) )
    2349               0 :         pszCur = pszURN + 16;
    2350               0 :     else if( EQUALN(pszURN,"urn:opengis:def:crs:",20) )
    2351               0 :         pszCur = pszURN + 20;
    2352                 :     else
    2353                 :     {
    2354                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2355               0 :                   "URN %s not a supported format.", pszURN );
    2356               0 :         return OGRERR_FAILURE;
    2357                 :     }
    2358                 : 
    2359                 : /* -------------------------------------------------------------------- */
    2360                 : /*      Clear any existing definition.                                  */
    2361                 : /* -------------------------------------------------------------------- */
    2362             513 :     if( GetRoot() != NULL )
    2363                 :     {
    2364               0 :         delete poRoot;
    2365               0 :         poRoot = NULL;
    2366                 :     }
    2367                 : 
    2368                 : /* -------------------------------------------------------------------- */
    2369                 : /*      Find code (ignoring version) out of string like:                */
    2370                 : /*                                                                      */
    2371                 : /*      authority:[version]:code                                        */
    2372                 : /* -------------------------------------------------------------------- */
    2373             513 :     const char *pszAuthority = pszCur;
    2374                 : 
    2375                 :     // skip authority
    2376            3076 :     while( *pszCur != ':' && *pszCur )
    2377            2050 :         pszCur++;
    2378             513 :     if( *pszCur == ':' )
    2379             513 :         pszCur++;
    2380                 : 
    2381                 :     // skip version
    2382             513 :     const char* pszBeforeVersion = pszCur;
    2383            1256 :     while( *pszCur != ':' && *pszCur )
    2384             230 :         pszCur++;
    2385             513 :     if( *pszCur == ':' )
    2386             464 :         pszCur++;
    2387                 :     else
    2388                 :         /* We come here in the case, the content to parse is authority:code (instead of authority::code) */
    2389                 :         /* which is probably illegal according to http://www.opengeospatial.org/ogcUrnPolicy */
    2390                 :         /* but such content is found for example in what is returned by GeoServer */
    2391              49 :         pszCur = pszBeforeVersion;
    2392                 : 
    2393             513 :     const char *pszCode = pszCur;
    2394                 : 
    2395             513 :     const char* pszComma = strchr(pszCur, ',');
    2396             513 :     if (pszComma == NULL)
    2397             512 :         return importFromURNPart(pszAuthority, pszCode, pszURN);
    2398                 : 
    2399                 : 
    2400                 :     /* There's a second part with the vertical SRS */
    2401               1 :     pszCur = pszComma + 1;
    2402               1 :     if (strncmp(pszCur, "crs:", 4) != 0)
    2403                 :     {
    2404                 :         CPLError( CE_Failure, CPLE_AppDefined,
    2405               0 :                   "URN %s not a supported format.", pszURN );
    2406               0 :         return OGRERR_FAILURE;
    2407                 :     }
    2408                 : 
    2409               1 :     pszCur += 4;
    2410                 : 
    2411               1 :     char* pszFirstCode = CPLStrdup(pszCode);
    2412               1 :     pszFirstCode[pszComma - pszCode] = '\0';
    2413               1 :     OGRErr eStatus = importFromURNPart(pszAuthority, pszFirstCode, pszURN);
    2414               1 :     CPLFree(pszFirstCode);
    2415                 : 
    2416                 :     // Do we want to turn this into a compound definition
    2417                 :     // with a vertical datum?
    2418               1 :     if( eStatus == OGRERR_NONE )
    2419                 :     {
    2420               1 :         OGRSpatialReference oVertSRS;
    2421                 : 
    2422                 :     /* -------------------------------------------------------------------- */
    2423                 :     /*      Find code (ignoring version) out of string like:                */
    2424                 :     /*                                                                      */
    2425                 :     /*      authority:[version]:code                                        */
    2426                 :     /* -------------------------------------------------------------------- */
    2427               1 :         pszAuthority = pszCur;
    2428                 : 
    2429                 :         // skip authority
    2430               6 :         while( *pszCur != ':' && *pszCur )
    2431               4 :             pszCur++;
    2432               1 :         if( *pszCur == ':' )
    2433               1 :             pszCur++;
    2434                 : 
    2435                 :         // skip version
    2436               1 :         pszBeforeVersion = pszCur;
    2437               2 :         while( *pszCur != ':' && *pszCur )
    2438               0 :             pszCur++;
    2439               1 :         if( *pszCur == ':' )
    2440               1 :             pszCur++;
    2441                 :         else
    2442               0 :             pszCur = pszBeforeVersion;
    2443                 : 
    2444               1 :         pszCode = pszCur;
    2445                 : 
    2446               1 :         eStatus = oVertSRS.importFromURNPart(pszAuthority, pszCode, pszURN);
    2447               1 :         if( eStatus == OGRERR_NONE )
    2448                 :         {
    2449               1 :             OGR_SRSNode *poHorizSRS = GetRoot()->Clone();
    2450                 : 
    2451               1 :             Clear();
    2452                 : 
    2453               1 :             CPLString osName = poHorizSRS->GetChild(0)->GetValue();
    2454               1 :             osName += " + ";
    2455               1 :             osName += oVertSRS.GetRoot()->GetValue();
    2456                 : 
    2457               1 :             SetNode( "COMPD_CS", osName );
    2458               1 :             GetRoot()->AddChild( poHorizSRS );
    2459               1 :             GetRoot()->AddChild( oVertSRS.GetRoot()->Clone() );
    2460                 :         }
    2461                 : 
    2462               1 :         return eStatus;
    2463                 :     }
    2464                 :     else
    2465               0 :         return eStatus;
    2466                 : }
    2467                 : 
    2468                 : /************************************************************************/
    2469                 : /*                           importFromCRSURL()                         */
    2470                 : /*                                                                      */
    2471                 : /*      See OGC Best Practice document 11-135 for details.              */
    2472                 : /************************************************************************/
    2473                 : 
    2474                 : /**
    2475                 :  * \brief Initialize from OGC URL. 
    2476                 :  *
    2477                 :  * Initializes this spatial reference from a coordinate system defined
    2478                 :  * by an OGC URL prefixed with "http://opengis.net/def/crs" per best practice 
    2479                 :  * paper 11-135.  Currently EPSG and OGC authority values are supported, 
    2480                 :  * including OGC auto codes, but not including CRS1 or CRS88 (NAVD88). 
    2481                 :  *
    2482                 :  * This method is also supported through SetFromUserInput() which can
    2483                 :  * normally be used for URLs.
    2484                 :  * 
    2485                 :  * @param pszURL the URL string. 
    2486                 :  *
    2487                 :  * @return OGRERR_NONE on success or an error code.
    2488                 :  */
    2489                 : 
    2490               4 : OGRErr OGRSpatialReference::importFromCRSURL( const char *pszURL )
    2491                 : 
    2492                 : {
    2493                 :     const char *pszCur;
    2494                 :     
    2495               4 :     if( EQUALN(pszURL,"http://opengis.net/def/crs",26) )
    2496               0 :         pszCur = pszURL + 26;
    2497               4 :     else if( EQUALN(pszURL,"http://www.opengis.net/def/crs",30) )
    2498               4 :         pszCur = pszURL + 30;
    2499               0 :     else if( EQUALN(pszURL,"www.opengis.net/def/crs",23) )
    2500               0 :         pszCur = pszURL + 23;
    2501                 :     else
    2502                 :     {
    2503                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2504               0 :                   "URL %s not a supported format.", pszURL );
    2505               0 :         return OGRERR_FAILURE;
    2506                 :     }
    2507                 : 
    2508                 : /* -------------------------------------------------------------------- */
    2509                 : /*      Clear any existing definition.                                  */
    2510                 : /* -------------------------------------------------------------------- */
    2511               4 :     if( GetRoot() != NULL )
    2512                 :     {
    2513               0 :         delete poRoot;
    2514               0 :         poRoot = NULL;
    2515                 :     }
    2516                 : 
    2517               4 :     if( EQUALN(pszCur, "-compound?1=", 12) )
    2518                 :     {
    2519                 : /* -------------------------------------------------------------------- */
    2520                 : /*      It's a compound CRS, of the form:                               */
    2521                 : /*                                                                      */
    2522                 : /*      http://opengis.net/def/crs-compound?1=URL1&2=URL2&3=URL3&..     */
    2523                 : /* -------------------------------------------------------------------- */
    2524               1 :         pszCur += 12;
    2525                 :         
    2526                 :         // extract each component CRS URL
    2527               1 :         int iComponentUrl = 2;
    2528                 : 
    2529               1 :         CPLString osName = "";
    2530               1 :         Clear();
    2531                 :         
    2532               1 :         while (iComponentUrl != -1)
    2533                 :         {
    2534                 :             char searchStr[5];
    2535               2 :             sprintf(searchStr, "&%d=", iComponentUrl);
    2536                 :             
    2537               2 :             const char* pszUrlEnd = strstr(pszCur, searchStr);
    2538                 :             
    2539                 :             // figure out the next component URL
    2540                 :             char* pszComponentUrl;
    2541                 :             
    2542               2 :             if( pszUrlEnd )
    2543                 :             {
    2544               1 :                 size_t nLen = pszUrlEnd - pszCur;
    2545               1 :                 pszComponentUrl = (char*) CPLMalloc(nLen + 1);
    2546               1 :                 strncpy(pszComponentUrl, pszCur, nLen);
    2547               1 :                 pszComponentUrl[nLen] = '\0';
    2548                 :                 
    2549               1 :                 ++iComponentUrl;
    2550               1 :                 pszCur += nLen + strlen(searchStr);
    2551                 :             }
    2552                 :             else
    2553                 :             {
    2554               1 :                 if( iComponentUrl == 2 )
    2555                 :                 {
    2556                 :                     CPLError( CE_Failure, CPLE_AppDefined, 
    2557               0 :                               "Compound CRS URLs must have at least two component CRSs." );
    2558               0 :                     return OGRERR_FAILURE;
    2559                 :                 }
    2560                 :                 else
    2561                 :                 {
    2562               1 :                     pszComponentUrl = CPLStrdup(pszCur);
    2563                 :                     // no more components
    2564               1 :                     iComponentUrl = -1;
    2565                 :                 }
    2566                 :             }
    2567                 :             
    2568               2 :             OGRSpatialReference oComponentSRS;
    2569               2 :             OGRErr eStatus = oComponentSRS.importFromCRSURL( pszComponentUrl );
    2570                 : 
    2571               2 :             CPLFree(pszComponentUrl);
    2572               2 :             pszComponentUrl = NULL;
    2573                 :             
    2574               2 :             if( eStatus == OGRERR_NONE )
    2575                 :             {
    2576               2 :                 if( osName.length() != 0 )
    2577                 :                 {
    2578               1 :                   osName += " + ";
    2579                 :                 }
    2580               2 :                 osName += oComponentSRS.GetRoot()->GetValue();
    2581               2 :                 SetNode( "COMPD_CS", osName );
    2582               2 :                 GetRoot()->AddChild( oComponentSRS.GetRoot()->Clone() );
    2583                 :             }
    2584                 :             else
    2585               0 :                 return eStatus;
    2586                 :         }
    2587                 :         
    2588                 :         
    2589               1 :         return OGRERR_NONE;
    2590                 :     }
    2591                 :     else
    2592                 :     {
    2593                 : /* -------------------------------------------------------------------- */
    2594                 : /*      It's a normal CRS URL, of the form:                             */
    2595                 : /*                                                                      */
    2596                 : /*      http://opengis.net/def/crs/AUTHORITY/VERSION/CODE               */
    2597                 : /* -------------------------------------------------------------------- */
    2598               3 :         ++pszCur;
    2599               3 :         const char *pszAuthority = pszCur;
    2600                 : 
    2601                 :         // skip authority
    2602              18 :         while( *pszCur != '/' && *pszCur )
    2603              12 :             pszCur++;
    2604               3 :         if( *pszCur == '/' )
    2605               3 :             pszCur++;
    2606                 :         
    2607                 : 
    2608                 :         // skip version
    2609               9 :         while( *pszCur != '/' && *pszCur )
    2610               3 :             pszCur++;
    2611               3 :         if( *pszCur == '/' )
    2612               3 :             pszCur++;
    2613                 :         
    2614               3 :         const char *pszCode = pszCur;
    2615                 :         
    2616               3 :         return importFromURNPart( pszAuthority, pszCode, pszURL );
    2617                 :     }
    2618                 : }
    2619                 : 
    2620                 : /************************************************************************/
    2621                 : /*                         importFromWMSAUTO()                          */
    2622                 : /************************************************************************/
    2623                 : 
    2624                 : /**
    2625                 :  * \brief Initialize from WMSAUTO string.
    2626                 :  *
    2627                 :  * Note that the WMS 1.3 specification does not include the
    2628                 :  * units code, while apparently earlier specs do.  We try to
    2629                 :  * guess around this.
    2630                 :  *
    2631                 :  * @param pszDefinition the WMSAUTO string
    2632                 :  *
    2633                 :  * @return OGRERR_NONE on success or an error code.
    2634                 :  */
    2635               1 : OGRErr OGRSpatialReference::importFromWMSAUTO( const char * pszDefinition )
    2636                 : 
    2637                 : {
    2638                 :     char **papszTokens;
    2639                 :     int nProjId, nUnitsId;
    2640               1 :     double dfRefLong, dfRefLat = 0.0;
    2641                 :     
    2642                 : /* -------------------------------------------------------------------- */
    2643                 : /*      Tokenize                                                        */
    2644                 : /* -------------------------------------------------------------------- */
    2645               1 :     if( EQUALN(pszDefinition,"AUTO:",5) )
    2646               1 :         pszDefinition += 5;
    2647                 : 
    2648               1 :     papszTokens = CSLTokenizeStringComplex( pszDefinition, ",", FALSE, TRUE );
    2649                 : 
    2650               1 :     if( CSLCount(papszTokens) == 4 )
    2651                 :     {
    2652               0 :         nProjId = atoi(papszTokens[0]);
    2653               0 :         nUnitsId = atoi(papszTokens[1]);
    2654               0 :         dfRefLong = CPLAtof(papszTokens[2]);
    2655               0 :         dfRefLat = CPLAtof(papszTokens[3]);
    2656                 :     }
    2657               1 :     else if( CSLCount(papszTokens) == 3 && atoi(papszTokens[0]) == 42005 )
    2658                 :     {
    2659               0 :         nProjId = atoi(papszTokens[0]);
    2660               0 :         nUnitsId = atoi(papszTokens[1]);
    2661               0 :         dfRefLong = CPLAtof(papszTokens[2]);
    2662               0 :         dfRefLat = 0.0;
    2663                 :     }
    2664               1 :     else if( CSLCount(papszTokens) == 3 )
    2665                 :     {
    2666               1 :         nProjId = atoi(papszTokens[0]);
    2667               1 :         nUnitsId = 9001;
    2668               1 :         dfRefLong = CPLAtof(papszTokens[1]);
    2669               1 :         dfRefLat = CPLAtof(papszTokens[2]);
    2670                 : 
    2671                 :     }
    2672               0 :     else if( CSLCount(papszTokens) == 2 && atoi(papszTokens[0]) == 42005 ) 
    2673                 :     {
    2674               0 :         nProjId = atoi(papszTokens[0]);
    2675               0 :         nUnitsId = 9001;
    2676               0 :         dfRefLong = CPLAtof(papszTokens[1]);
    2677                 :     }
    2678                 :     else
    2679                 :     {
    2680               0 :         CSLDestroy( papszTokens );
    2681                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2682                 :                   "AUTO projection has wrong number of arguments, expected\n"
    2683                 :                   "AUTO:proj_id,units_id,ref_long,ref_lat or"
    2684               0 :                   "AUTO:proj_id,ref_long,ref_lat" );
    2685               0 :         return OGRERR_FAILURE;
    2686                 :     }
    2687                 : 
    2688               1 :     CSLDestroy( papszTokens );
    2689                 : 
    2690                 : /* -------------------------------------------------------------------- */
    2691                 : /*      Build coordsys.                                                 */
    2692                 : /* -------------------------------------------------------------------- */
    2693               1 :     Clear();
    2694                 : 
    2695               1 :     switch( nProjId )
    2696                 :     {
    2697                 :       case 42001: // Auto UTM
    2698                 :         SetUTM( (int) floor( (dfRefLong + 180.0) / 6.0 ) + 1, 
    2699               1 :                 dfRefLat >= 0.0 );
    2700               1 :         break;
    2701                 : 
    2702                 :       case 42002: // Auto TM (strangely very UTM-like).
    2703                 :         SetTM( 0, dfRefLong, 0.9996, 
    2704               0 :                500000.0, (dfRefLat >= 0.0) ? 0.0 : 10000000.0 );
    2705               0 :         break;
    2706                 : 
    2707                 :       case 42003: // Auto Orthographic.
    2708               0 :         SetOrthographic( dfRefLat, dfRefLong, 0.0, 0.0 );
    2709               0 :         break;
    2710                 : 
    2711                 :       case 42004: // Auto Equirectangular
    2712               0 :         SetEquirectangular( dfRefLat, dfRefLong, 0.0, 0.0 );
    2713               0 :         break;
    2714                 : 
    2715                 :       case 42005:
    2716               0 :         SetMollweide( dfRefLong, 0.0, 0.0 );
    2717               0 :         break;
    2718                 : 
    2719                 :       default:
    2720                 :         CPLError( CE_Failure, CPLE_AppDefined,
    2721                 :                   "Unsupported projection id in importFromWMSAUTO(): %d", 
    2722               0 :                   nProjId );
    2723               0 :         return OGRERR_FAILURE;
    2724                 :     }
    2725                 : 
    2726                 : /* -------------------------------------------------------------------- */
    2727                 : /*      Set units.                                                      */
    2728                 : /* -------------------------------------------------------------------- */
    2729                 : 
    2730               1 :     switch( nUnitsId )
    2731                 :     {
    2732                 :       case 9001:
    2733               1 :         SetLinearUnits( SRS_UL_METER, 1.0 );
    2734               1 :         break;
    2735                 : 
    2736                 :       case 9002:
    2737               0 :         SetLinearUnits( "Foot", 0.3048 );
    2738               0 :         break;
    2739                 : 
    2740                 :       case 9003:
    2741               0 :         SetLinearUnits( "US survey foot", CPLAtof(SRS_UL_US_FOOT_CONV) );
    2742               0 :         break;
    2743                 : 
    2744                 :       default:
    2745                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2746                 :                   "Unsupported units code (%d).", 
    2747               0 :                   nUnitsId );
    2748               0 :         return OGRERR_FAILURE;
    2749                 :         break;
    2750                 :     }
    2751                 :     
    2752               1 :     SetAuthority( "PROJCS|UNIT", "EPSG", nUnitsId );
    2753                 : 
    2754                 : /* -------------------------------------------------------------------- */
    2755                 : /*      Set WGS84.                                                      */
    2756                 : /* -------------------------------------------------------------------- */
    2757               1 :     SetWellKnownGeogCS( "WGS84" );
    2758                 : 
    2759               1 :     return OGRERR_NONE;
    2760                 : }
    2761                 : 
    2762                 : /************************************************************************/
    2763                 : /*                            GetSemiMajor()                            */
    2764                 : /************************************************************************/
    2765                 : 
    2766                 : /**
    2767                 :  * \brief Get spheroid semi major axis.
    2768                 :  *
    2769                 :  * This method does the same thing as the C function OSRGetSemiMajor().
    2770                 :  *
    2771                 :  * @param pnErr if non-NULL set to OGRERR_FAILURE if semi major axis
    2772                 :  * can be found. 
    2773                 :  *
    2774                 :  * @return semi-major axis, or SRS_WGS84_SEMIMAJOR if it can't be found.
    2775                 :  */
    2776                 : 
    2777            9853 : double OGRSpatialReference::GetSemiMajor( OGRErr * pnErr ) const
    2778                 : 
    2779                 : {
    2780            9853 :     const OGR_SRSNode *poSpheroid = GetAttrNode( "SPHEROID" );
    2781                 :     
    2782            9853 :     if( pnErr != NULL )
    2783             962 :         *pnErr = OGRERR_NONE;
    2784                 : 
    2785            9853 :     if( poSpheroid != NULL && poSpheroid->GetChildCount() >= 3 )
    2786                 :     {
    2787            9850 :         return CPLAtof( poSpheroid->GetChild(1)->GetValue() );
    2788                 :     }
    2789                 :     else
    2790                 :     {
    2791               3 :         if( pnErr != NULL )
    2792               3 :             *pnErr = OGRERR_FAILURE;
    2793                 : 
    2794               3 :         return SRS_WGS84_SEMIMAJOR;
    2795                 :     }
    2796                 : }
    2797                 : 
    2798                 : /************************************************************************/
    2799                 : /*                          OSRGetSemiMajor()                           */
    2800                 : /************************************************************************/
    2801                 : 
    2802                 : /**
    2803                 :  * \brief Get spheroid semi major axis.
    2804                 :  *
    2805                 :  * This function is the same as OGRSpatialReference::GetSemiMajor()
    2806                 :  */
    2807               4 : double OSRGetSemiMajor( OGRSpatialReferenceH hSRS, OGRErr *pnErr )
    2808                 : 
    2809                 : {
    2810               4 :     VALIDATE_POINTER1( hSRS, "OSRGetSemiMajor", 0 );
    2811                 : 
    2812               4 :     return ((OGRSpatialReference *) hSRS)->GetSemiMajor( pnErr );
    2813                 : }
    2814                 : 
    2815                 : /************************************************************************/
    2816                 : /*                          GetInvFlattening()                          */
    2817                 : /************************************************************************/
    2818                 : 
    2819                 : /**
    2820                 :  * \brief Get spheroid inverse flattening.
    2821                 :  *
    2822                 :  * This method does the same thing as the C function OSRGetInvFlattening().
    2823                 :  *
    2824                 :  * @param pnErr if non-NULL set to OGRERR_FAILURE if no inverse flattening 
    2825                 :  * can be found. 
    2826                 :  *
    2827                 :  * @return inverse flattening, or SRS_WGS84_INVFLATTENING if it can't be found.
    2828                 :  */
    2829                 : 
    2830            9703 : double OGRSpatialReference::GetInvFlattening( OGRErr * pnErr ) const
    2831                 : 
    2832                 : {
    2833            9703 :     const OGR_SRSNode *poSpheroid = GetAttrNode( "SPHEROID" );
    2834                 :     
    2835            9703 :     if( pnErr != NULL )
    2836             962 :         *pnErr = OGRERR_NONE;
    2837                 : 
    2838            9703 :     if( poSpheroid != NULL && poSpheroid->GetChildCount() >= 3 )
    2839                 :     {
    2840            9700 :         return CPLAtof( poSpheroid->GetChild(2)->GetValue() );
    2841                 :     }
    2842                 :     else
    2843                 :     {
    2844               3 :         if( pnErr != NULL )
    2845               3 :             *pnErr = OGRERR_FAILURE;
    2846                 : 
    2847               3 :         return SRS_WGS84_INVFLATTENING;
    2848                 :     }
    2849                 : }
    2850                 : 
    2851                 : /************************************************************************/
    2852                 : /*                        OSRGetInvFlattening()                         */
    2853                 : /************************************************************************/
    2854                 : 
    2855                 : /**
    2856                 :  * \brief Get spheroid inverse flattening.
    2857                 :  *
    2858                 :  * This function is the same as OGRSpatialReference::GetInvFlattening()
    2859                 :  */
    2860               4 : double OSRGetInvFlattening( OGRSpatialReferenceH hSRS, OGRErr *pnErr )
    2861                 : 
    2862                 : {
    2863               4 :     VALIDATE_POINTER1( hSRS, "OSRGetInvFlattening", 0 );
    2864                 : 
    2865               4 :     return ((OGRSpatialReference *) hSRS)->GetInvFlattening( pnErr );
    2866                 : }
    2867                 : 
    2868                 : /************************************************************************/
    2869                 : /*                            GetSemiMinor()                            */
    2870                 : /************************************************************************/
    2871                 : 
    2872                 : /**
    2873                 :  * \brief Get spheroid semi minor axis.
    2874                 :  *
    2875                 :  * This method does the same thing as the C function OSRGetSemiMinor().
    2876                 :  *
    2877                 :  * @param pnErr if non-NULL set to OGRERR_FAILURE if semi minor axis
    2878                 :  * can be found. 
    2879                 :  *
    2880                 :  * @return semi-minor axis, or WGS84 semi minor if it can't be found.
    2881                 :  */
    2882                 : 
    2883             184 : double OGRSpatialReference::GetSemiMinor( OGRErr * pnErr ) const
    2884                 : 
    2885                 : {
    2886                 :     double      dfInvFlattening, dfSemiMajor;
    2887                 : 
    2888             184 :     dfSemiMajor = GetSemiMajor( pnErr );
    2889             184 :     dfInvFlattening = GetInvFlattening( pnErr );
    2890                 : 
    2891             184 :     if( ABS(dfInvFlattening) < 0.000000000001 )
    2892              24 :         return dfSemiMajor;
    2893                 :     else
    2894             160 :         return dfSemiMajor * (1.0 - 1.0/dfInvFlattening);
    2895                 : }
    2896                 : 
    2897                 : /************************************************************************/
    2898                 : /*                          OSRGetSemiMinor()                           */
    2899                 : /************************************************************************/
    2900                 : 
    2901                 : /**
    2902                 :  * \brief Get spheroid semi minor axis.
    2903                 :  *
    2904                 :  * This function is the same as OGRSpatialReference::GetSemiMinor()
    2905                 :  */
    2906               3 : double OSRGetSemiMinor( OGRSpatialReferenceH hSRS, OGRErr *pnErr )
    2907                 : 
    2908                 : {
    2909               3 :     VALIDATE_POINTER1( hSRS, "OSRGetSemiMinor", 0 );
    2910                 : 
    2911               3 :     return ((OGRSpatialReference *) hSRS)->GetSemiMinor( pnErr );
    2912                 : }
    2913                 : 
    2914                 : /************************************************************************/
    2915                 : /*                             SetLocalCS()                             */
    2916                 : /************************************************************************/
    2917                 : 
    2918                 : /**
    2919                 :  * \brief Set the user visible LOCAL_CS name.
    2920                 :  *
    2921                 :  * This method is the same as the C function OSRSetLocalCS(). 
    2922                 :  *
    2923                 :  * This method will ensure a LOCAL_CS node is created as the root,
    2924                 :  * and set the provided name on it.  It must be used before SetLinearUnits().
    2925                 :  *
    2926                 :  * @param pszName the user visible name to assign.  Not used as a key.
    2927                 :  * 
    2928                 :  * @return OGRERR_NONE on success.
    2929                 :  */
    2930                 : 
    2931              43 : OGRErr OGRSpatialReference::SetLocalCS( const char * pszName )
    2932                 : 
    2933                 : {
    2934              43 :     OGR_SRSNode *poCS = GetAttrNode( "LOCAL_CS" );
    2935                 : 
    2936              43 :     if( poCS == NULL && GetRoot() != NULL )
    2937                 :     {
    2938                 :         CPLDebug( "OGR", 
    2939                 :                   "OGRSpatialReference::SetLocalCS(%s) failed.\n"
    2940                 :                "It appears an incompatible root node (%s) already exists.\n",
    2941               0 :                   pszName, GetRoot()->GetValue() );
    2942               0 :         return OGRERR_FAILURE;
    2943                 :     }
    2944                 :     else
    2945                 :     {
    2946              43 :         SetNode( "LOCAL_CS", pszName );
    2947              43 :         return OGRERR_NONE;
    2948                 :     }
    2949                 : }
    2950                 : 
    2951                 : /************************************************************************/
    2952                 : /*                           OSRSetLocalCS()                            */
    2953                 : /************************************************************************/
    2954                 : 
    2955                 : /**
    2956                 :  * \brief Set the user visible LOCAL_CS name.
    2957                 :  *
    2958                 :  * This function is the same as OGRSpatialReference::SetLocalCS()
    2959                 :  */
    2960               0 : OGRErr OSRSetLocalCS( OGRSpatialReferenceH hSRS, const char * pszName )
    2961                 : 
    2962                 : {
    2963               0 :     VALIDATE_POINTER1( hSRS, "OSRSetLocalCS", CE_Failure );
    2964                 : 
    2965               0 :     return ((OGRSpatialReference *) hSRS)->SetLocalCS( pszName );
    2966                 : }
    2967                 : 
    2968                 : /************************************************************************/
    2969                 : /*                             SetGeocCS()                              */
    2970                 : /************************************************************************/
    2971                 : 
    2972                 : /**
    2973                 :  * \brief Set the user visible GEOCCS name.
    2974                 :  *
    2975                 :  * This method is the same as the C function OSRSetGeocCS(). 
    2976                 : 
    2977                 :  * This method will ensure a GEOCCS node is created as the root,
    2978                 :  * and set the provided name on it.  If used on a GEOGCS coordinate system, 
    2979                 :  * the DATUM and PRIMEM nodes from the GEOGCS will be tarnsferred over to 
    2980                 :  * the GEOGCS. 
    2981                 :  *
    2982                 :  * @param pszName the user visible name to assign.  Not used as a key.
    2983                 :  * 
    2984                 :  * @return OGRERR_NONE on success.
    2985                 :  *
    2986                 :  * @since OGR 1.9.0
    2987                 :  */
    2988                 : 
    2989               9 : OGRErr OGRSpatialReference::SetGeocCS( const char * pszName )
    2990                 : 
    2991                 : {
    2992               9 :     OGR_SRSNode *poGeogCS = NULL;
    2993               9 :     OGR_SRSNode *poGeocCS = GetAttrNode( "GEOCCS" );
    2994                 : 
    2995               9 :     if( poRoot != NULL && EQUAL(poRoot->GetValue(),"GEOGCS") )
    2996                 :     {
    2997               2 :         poGeogCS = poRoot;
    2998               2 :         poRoot = NULL;
    2999                 :     }
    3000                 : 
    3001               9 :     if( poGeocCS == NULL && GetRoot() != NULL )
    3002                 :     {
    3003                 :         CPLDebug( "OGR", 
    3004                 :                   "OGRSpatialReference::SetGeocCS(%s) failed.\n"
    3005                 :                "It appears an incompatible root node (%s) already exists.\n",
    3006               1 :                   pszName, GetRoot()->GetValue() );
    3007               1 :         return OGRERR_FAILURE;
    3008                 :     }
    3009                 : 
    3010               8 :     SetNode( "GEOCCS", pszName );
    3011                 : 
    3012               8 :     if( poGeogCS != NULL )
    3013                 :     {
    3014               2 :         OGR_SRSNode *poDatum = poGeogCS->GetNode( "DATUM" );
    3015               2 :         OGR_SRSNode *poPRIMEM = poGeogCS->GetNode( "PRIMEM" );
    3016               2 :         if ( poDatum != NULL && poPRIMEM != NULL )
    3017                 :         {
    3018               1 :             poRoot->InsertChild( poDatum->Clone(), 1 );
    3019               1 :             poRoot->InsertChild( poPRIMEM->Clone(), 2 );
    3020                 :         }
    3021               2 :         delete poGeogCS;
    3022                 :     }
    3023                 : 
    3024               8 :     return OGRERR_NONE;
    3025                 : }
    3026                 : 
    3027                 : /************************************************************************/
    3028                 : /*                            OSRSetGeocCS()                            */
    3029                 : /************************************************************************/
    3030                 : 
    3031                 : /**
    3032                 :  * \brief Set the user visible PROJCS name.
    3033                 :  *
    3034                 :  * This function is the same as OGRSpatialReference::SetGeocCS()
    3035                 :  *
    3036                 :  * @since OGR 1.9.0
    3037                 :  */
    3038               5 : OGRErr OSRSetGeocCS( OGRSpatialReferenceH hSRS, const char * pszName )
    3039                 : 
    3040                 : {
    3041               5 :     VALIDATE_POINTER1( hSRS, "OSRSetGeocCS", CE_Failure );
    3042                 : 
    3043               5 :     return ((OGRSpatialReference *) hSRS)->SetGeocCS( pszName );
    3044                 : }
    3045                 : 
    3046                 : /************************************************************************/
    3047                 : /*                             SetVertCS()                              */
    3048                 : /************************************************************************/
    3049                 : 
    3050                 : /**
    3051                 :  * \brief Set the user visible VERT_CS name.
    3052                 :  *
    3053                 :  * This method is the same as the C function OSRSetVertCS(). 
    3054                 : 
    3055                 :  * This method will ensure a VERT_CS node is created if needed.  If the
    3056                 :  * existing coordinate system is GEOGCS or PROJCS rooted, then it will be
    3057                 :  * turned into a COMPD_CS.
    3058                 :  *
    3059                 :  * @param pszVertCSName the user visible name of the vertical coordinate
    3060                 :  * system. Not used as a key.
    3061                 :  *  
    3062                 :  * @param pszVertDatumName the user visible name of the vertical datum.  It
    3063                 :  * is helpful if this matches the EPSG name.
    3064                 :  * 
    3065                 :  * @param nVertDatumType the OGC vertical datum type, usually 2005. 
    3066                 :  * 
    3067                 :  * @return OGRERR_NONE on success.
    3068                 :  *
    3069                 :  * @since OGR 1.9.0
    3070                 :  */
    3071                 : 
    3072               8 : OGRErr OGRSpatialReference::SetVertCS( const char * pszVertCSName,
    3073                 :                                        const char * pszVertDatumName,
    3074                 :                                        int nVertDatumType )
    3075                 : 
    3076                 : {
    3077                 : /* -------------------------------------------------------------------- */
    3078                 : /*      Handle the case where we want to make a compound coordinate     */
    3079                 : /*      system.                                                         */
    3080                 : /* -------------------------------------------------------------------- */
    3081               8 :     if( IsProjected() || IsGeographic() )
    3082                 :     {
    3083               0 :         OGR_SRSNode *poNewRoot = new OGR_SRSNode( "COMPD_CS" );
    3084               0 :         poNewRoot->AddChild( poRoot );
    3085               0 :         poRoot = poNewRoot;
    3086                 :     }
    3087                 : 
    3088               8 :     else if( GetAttrNode( "VERT_CS" ) == NULL )
    3089               8 :         Clear();
    3090                 : 
    3091                 : /* -------------------------------------------------------------------- */
    3092                 : /*      If we already have a VERT_CS, wipe and recreate the root        */
    3093                 : /*      otherwise create the VERT_CS now.                               */
    3094                 : /* -------------------------------------------------------------------- */
    3095               8 :     OGR_SRSNode *poVertCS = GetAttrNode( "VERT_CS" );
    3096                 :     
    3097               8 :     if( poVertCS != NULL )
    3098                 :     {
    3099               0 :         poVertCS->ClearChildren();
    3100                 :     }
    3101                 :     else
    3102                 :     {
    3103               8 :         poVertCS = new OGR_SRSNode( "VERT_CS" );
    3104               8 :         if( poRoot != NULL && EQUAL(poRoot->GetValue(),"COMPD_CS") )
    3105                 :         {
    3106               0 :             poRoot->AddChild( poVertCS );
    3107                 :         }
    3108                 :         else
    3109               8 :             SetRoot( poVertCS );
    3110                 :     }
    3111                 : 
    3112                 : /* -------------------------------------------------------------------- */
    3113                 : /*      Set the name, datumname, and type.                              */
    3114                 : /* -------------------------------------------------------------------- */
    3115                 :     OGR_SRSNode *poVertDatum;
    3116                 : 
    3117               8 :     poVertCS->AddChild( new OGR_SRSNode( pszVertCSName ) );
    3118                 :     
    3119              16 :     poVertDatum = new OGR_SRSNode( "VERT_DATUM" );
    3120               8 :     poVertCS->AddChild( poVertDatum );
    3121                 :         
    3122              16 :     poVertDatum->AddChild( new OGR_SRSNode( pszVertDatumName ) );
    3123                 : 
    3124               8 :     CPLString osVertDatumType;
    3125               8 :     osVertDatumType.Printf( "%d", nVertDatumType );
    3126               8 :     poVertDatum->AddChild( new OGR_SRSNode( osVertDatumType ) );
    3127                 : 
    3128                 :     // add default axis node.
    3129               8 :     OGR_SRSNode *poAxis = new OGR_SRSNode( "AXIS" );
    3130                 : 
    3131              16 :     poAxis->AddChild( new OGR_SRSNode( "Up" ) );
    3132               8 :     poAxis->AddChild( new OGR_SRSNode( "UP" ) );
    3133                 : 
    3134               8 :     poVertCS->AddChild( poAxis );
    3135                 : 
    3136               8 :     return OGRERR_NONE;
    3137                 : }
    3138                 : 
    3139                 : /************************************************************************/
    3140                 : /*                            OSRSetVertCS()                            */
    3141                 : /************************************************************************/
    3142                 : 
    3143                 : /**
    3144                 :  * \brief Setup the vertical coordinate system.
    3145                 :  *
    3146                 :  * This function is the same as OGRSpatialReference::SetVertCS()
    3147                 :  *
    3148                 :  * @since OGR 1.9.0
    3149                 :  */
    3150               0 : OGRErr OSRSetVertCS( OGRSpatialReferenceH hSRS,
    3151                 :                      const char * pszVertCSName,
    3152                 :                      const char * pszVertDatumName,
    3153                 :                      int nVertDatumType )
    3154                 : 
    3155                 : {
    3156               0 :     VALIDATE_POINTER1( hSRS, "OSRSetVertCS", CE_Failure );
    3157                 : 
    3158                 :     return ((OGRSpatialReference *) hSRS)->SetVertCS( pszVertCSName,
    3159                 :                                                       pszVertDatumName,
    3160               0 :                                                       nVertDatumType );
    3161                 : }
    3162                 : 
    3163                 : /************************************************************************/
    3164                 : /*                           SetCompoundCS()                            */
    3165                 : /************************************************************************/
    3166                 : 
    3167                 : /**
    3168                 :  * \brief Setup a compound coordinate system.
    3169                 :  *
    3170                 :  * This method is the same as the C function OSRSetCompoundCS(). 
    3171                 : 
    3172                 :  * This method is replace the current SRS with a COMPD_CS coordinate system
    3173                 :  * consisting of the passed in horizontal and vertical coordinate systems.
    3174                 :  *
    3175                 :  * @param pszName the name of the compound coordinate system. 
    3176                 :  * 
    3177                 :  * @param poHorizSRS the horizontal SRS (PROJCS or GEOGCS).
    3178                 :  *  
    3179                 :  * @param poVertSRS the vertical SRS (VERT_CS).
    3180                 :  * 
    3181                 :  * @return OGRERR_NONE on success.
    3182                 :  */
    3183                 : 
    3184                 : OGRErr 
    3185               1 : OGRSpatialReference::SetCompoundCS( const char *pszName,
    3186                 :                                     const OGRSpatialReference *poHorizSRS,
    3187                 :                                     const OGRSpatialReference *poVertSRS )
    3188                 : 
    3189                 : {
    3190                 : /* -------------------------------------------------------------------- */
    3191                 : /*      Verify these are legal horizontal and vertical coordinate       */
    3192                 : /*      systems.                                                        */
    3193                 : /* -------------------------------------------------------------------- */
    3194               1 :     if( !poVertSRS->IsVertical() ) 
    3195                 :     {
    3196                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    3197               0 :                   "SetCompoundCS() fails, vertical component is not VERT_CS." );
    3198               0 :         return OGRERR_FAILURE;
    3199                 :     }
    3200               1 :     if( !poHorizSRS->IsProjected() 
    3201                 :         && !poHorizSRS->IsGeographic() )
    3202                 :     {
    3203                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    3204               0 :                   "SetCompoundCS() fails, horizontal component is not PROJCS or GEOGCS." );
    3205               0 :         return OGRERR_FAILURE;
    3206                 :     }
    3207                 : 
    3208                 : /* -------------------------------------------------------------------- */
    3209                 : /*      Replace with compound srs.                                      */
    3210                 : /* -------------------------------------------------------------------- */
    3211               1 :     Clear();
    3212                 : 
    3213               1 :     poRoot = new OGR_SRSNode( "COMPD_CS" );
    3214               2 :     poRoot->AddChild( new OGR_SRSNode( pszName ) );
    3215               1 :     poRoot->AddChild( poHorizSRS->GetRoot()->Clone() );
    3216               1 :     poRoot->AddChild( poVertSRS->GetRoot()->Clone() );
    3217                 :     
    3218               1 :     return OGRERR_NONE;
    3219                 : }
    3220                 : 
    3221                 : /************************************************************************/
    3222                 : /*                          OSRSetCompoundCS()                          */
    3223                 : /************************************************************************/
    3224                 : 
    3225                 : /**
    3226                 :  * \brief Setup a compound coordinate system.
    3227                 :  *
    3228                 :  * This function is the same as OGRSpatialReference::SetCompoundCS()
    3229                 :  */
    3230               1 : OGRErr OSRSetCompoundCS( OGRSpatialReferenceH hSRS,
    3231                 :                          const char *pszName,
    3232                 :                          OGRSpatialReferenceH hHorizSRS,
    3233                 :                          OGRSpatialReferenceH hVertSRS )
    3234                 : 
    3235                 : {
    3236               1 :     VALIDATE_POINTER1( hSRS, "OSRSetCompoundCS", CE_Failure );
    3237               1 :     VALIDATE_POINTER1( hHorizSRS, "OSRSetCompoundCS", CE_Failure );
    3238               1 :     VALIDATE_POINTER1( hVertSRS, "OSRSetCompoundCS", CE_Failure );
    3239                 : 
    3240                 :     return ((OGRSpatialReference *) hSRS)->
    3241                 :         SetCompoundCS( pszName,
    3242                 :                        (OGRSpatialReference *) hHorizSRS,
    3243               1 :                        (OGRSpatialReference *) hVertSRS );
    3244                 : }
    3245                 : 
    3246                 : /************************************************************************/
    3247                 : /*                             SetProjCS()                              */
    3248                 : /************************************************************************/
    3249                 : 
    3250                 : /**
    3251                 :  * \brief Set the user visible PROJCS name.
    3252                 :  *
    3253                 :  * This method is the same as the C function OSRSetProjCS(). 
    3254                 :  *
    3255                 :  * This method will ensure a PROJCS node is created as the root,
    3256                 :  * and set the provided name on it.  If used on a GEOGCS coordinate system, 
    3257                 :  * the GEOGCS node will be demoted to be a child of the new PROJCS root.
    3258                 :  *
    3259                 :  * @param pszName the user visible name to assign.  Not used as a key.
    3260                 :  * 
    3261                 :  * @return OGRERR_NONE on success.
    3262                 :  */
    3263                 : 
    3264              98 : OGRErr OGRSpatialReference::SetProjCS( const char * pszName )
    3265                 : 
    3266                 : {
    3267              98 :     OGR_SRSNode *poGeogCS = NULL;
    3268              98 :     OGR_SRSNode *poProjCS = GetAttrNode( "PROJCS" );
    3269                 : 
    3270              98 :     if( poRoot != NULL && EQUAL(poRoot->GetValue(),"GEOGCS") )
    3271                 :     {
    3272               6 :         poGeogCS = poRoot;
    3273               6 :         poRoot = NULL;
    3274                 :     }
    3275                 : 
    3276              98 :     if( poProjCS == NULL && GetRoot() != NULL )
    3277                 :     {
    3278                 :         CPLDebug( "OGR", 
    3279                 :                   "OGRSpatialReference::SetProjCS(%s) failed.\n"
    3280                 :                "It appears an incompatible root node (%s) already exists.\n",
    3281               0 :                   pszName, GetRoot()->GetValue() );
    3282               0 :         return OGRERR_FAILURE;
    3283                 :     }
    3284                 : 
    3285              98 :     SetNode( "PROJCS", pszName );
    3286                 : 
    3287              98 :     if( poGeogCS != NULL )
    3288               6 :         poRoot->InsertChild( poGeogCS, 1 );
    3289                 : 
    3290              98 :     return OGRERR_NONE;
    3291                 : }
    3292                 : 
    3293                 : /************************************************************************/
    3294                 : /*                            OSRSetProjCS()                            */
    3295                 : /************************************************************************/
    3296                 : 
    3297                 : /**
    3298                 :  * \brief Set the user visible PROJCS name.
    3299                 :  *
    3300                 :  * This function is the same as OGRSpatialReference::SetProjCS()
    3301                 :  */
    3302               2 : OGRErr OSRSetProjCS( OGRSpatialReferenceH hSRS, const char * pszName )
    3303                 : 
    3304                 : {
    3305               2 :     VALIDATE_POINTER1( hSRS, "OSRSetProjCS", CE_Failure );
    3306                 : 
    3307               2 :     return ((OGRSpatialReference *) hSRS)->SetProjCS( pszName );
    3308                 : }
    3309                 : 
    3310                 : /************************************************************************/
    3311                 : /*                           SetProjection()                            */
    3312                 : /************************************************************************/
    3313                 : 
    3314                 : /**
    3315                 :  * \brief Set a projection name.
    3316                 :  *
    3317                 :  * This method is the same as the C function OSRSetProjection().
    3318                 :  *
    3319                 :  * @param pszProjection the projection name, which should be selected from
    3320                 :  * the macros in ogr_srs_api.h, such as SRS_PT_TRANSVERSE_MERCATOR. 
    3321                 :  *
    3322                 :  * @return OGRERR_NONE on success.
    3323                 :  */
    3324                 : 
    3325           16966 : OGRErr OGRSpatialReference::SetProjection( const char * pszProjection )
    3326                 : 
    3327                 : {
    3328           16966 :     OGR_SRSNode *poGeogCS = NULL;
    3329                 :     OGRErr eErr;
    3330                 : 
    3331           16966 :     if( poRoot != NULL && EQUAL(poRoot->GetValue(),"GEOGCS") )
    3332                 :     {
    3333             124 :         poGeogCS = poRoot;
    3334             124 :         poRoot = NULL;
    3335                 :     }
    3336                 : 
    3337           16966 :     if( !GetAttrNode( "PROJCS" ) )
    3338                 :     {
    3339             416 :         SetNode( "PROJCS", "unnamed" );
    3340                 :     }
    3341                 : 
    3342           16966 :     eErr = SetNode( "PROJCS|PROJECTION", pszProjection );
    3343           16966 :     if( eErr != OGRERR_NONE )
    3344               0 :         return eErr;
    3345                 : 
    3346           16966 :     if( poGeogCS != NULL )
    3347             124 :         poRoot->InsertChild( poGeogCS, 1 );
    3348                 : 
    3349           16966 :     return OGRERR_NONE;
    3350                 : }
    3351                 : 
    3352                 : /************************************************************************/
    3353                 : /*                            OSRSetProjection()                        */
    3354                 : /************************************************************************/
    3355                 : 
    3356                 : /**
    3357                 :  * \brief Set a projection name.
    3358                 :  *
    3359                 :  * This function is the same as OGRSpatialReference::SetProjection()
    3360                 :  */
    3361               0 : OGRErr OSRSetProjection( OGRSpatialReferenceH hSRS,
    3362                 :                          const char * pszProjection )
    3363                 : 
    3364                 : {
    3365               0 :     VALIDATE_POINTER1( hSRS, "OSRSetProjection", CE_Failure );
    3366                 : 
    3367               0 :     return ((OGRSpatialReference *) hSRS)->SetProjection( pszProjection );
    3368                 : }
    3369                 : 
    3370                 : /************************************************************************/
    3371                 : /*                            SetProjParm()                             */
    3372                 : /************************************************************************/
    3373                 : 
    3374                 : /**
    3375                 :  * \brief Set a projection parameter value.
    3376                 :  *
    3377                 :  * Adds a new PARAMETER under the PROJCS with the indicated name and value.
    3378                 :  *
    3379                 :  * This method is the same as the C function OSRSetProjParm().
    3380                 :  *
    3381                 :  * Please check http://www.remotesensing.org/geotiff/proj_list pages for
    3382                 :  * legal parameter names for specific projections.
    3383                 :  *
    3384                 :  * 
    3385                 :  * @param pszParmName the parameter name, which should be selected from
    3386                 :  * the macros in ogr_srs_api.h, such as SRS_PP_CENTRAL_MERIDIAN. 
    3387                 :  *
    3388                 :  * @param dfValue value to assign. 
    3389                 :  * 
    3390                 :  * @return OGRERR_NONE on success.
    3391                 :  */
    3392                 : 
    3393           87854 : OGRErr OGRSpatialReference::SetProjParm( const char * pszParmName,
    3394                 :                                          double dfValue )
    3395                 : 
    3396                 : {
    3397           87854 :     OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
    3398                 :     OGR_SRSNode *poParm;
    3399                 :     char        szValue[64];
    3400                 : 
    3401           87854 :     if( poPROJCS == NULL )
    3402               2 :         return OGRERR_FAILURE;
    3403                 : 
    3404           87852 :     OGRPrintDouble( szValue, dfValue );
    3405                 : 
    3406                 : /* -------------------------------------------------------------------- */
    3407                 : /*      Try to find existing parameter with this name.                  */
    3408                 : /* -------------------------------------------------------------------- */
    3409          620878 :     for( int iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
    3410                 :     {
    3411          533079 :         poParm = poPROJCS->GetChild( iChild );
    3412                 : 
    3413          533079 :         if( EQUAL(poParm->GetValue(),"PARAMETER")
    3414                 :             && poParm->GetChildCount() == 2 
    3415                 :             && EQUAL(poParm->GetChild(0)->GetValue(),pszParmName) )
    3416                 :         {
    3417              53 :             poParm->GetChild(1)->SetValue( szValue );
    3418              53 :             return OGRERR_NONE;
    3419                 :         }
    3420                 :     }
    3421                 :     
    3422                 : /* -------------------------------------------------------------------- */
    3423                 : /*      Otherwise create a new parameter and append.                    */
    3424                 : /* -------------------------------------------------------------------- */
    3425           87799 :     poParm = new OGR_SRSNode( "PARAMETER" );
    3426          175598 :     poParm->AddChild( new OGR_SRSNode( pszParmName ) );
    3427          175598 :     poParm->AddChild( new OGR_SRSNode( szValue ) );
    3428                 : 
    3429           87799 :     poPROJCS->AddChild( poParm );
    3430                 : 
    3431           87799 :     return OGRERR_NONE;
    3432                 : }
    3433                 : 
    3434                 : /************************************************************************/
    3435                 : /*                           OSRSetProjParm()                           */
    3436                 : /************************************************************************/
    3437                 : 
    3438                 : /**
    3439                 :  * \brief Set a projection parameter value.
    3440                 :  *
    3441                 :  * This function is the same as OGRSpatialReference::SetProjParm()
    3442                 :  */
    3443             142 : OGRErr OSRSetProjParm( OGRSpatialReferenceH hSRS, 
    3444                 :                        const char * pszParmName, double dfValue )
    3445                 : 
    3446                 : {
    3447             142 :     VALIDATE_POINTER1( hSRS, "OSRSetProjParm", CE_Failure );
    3448                 : 
    3449             142 :     return ((OGRSpatialReference *) hSRS)->SetProjParm( pszParmName, dfValue );
    3450                 : }
    3451                 : 
    3452                 : /************************************************************************/
    3453                 : /*                            FindProjParm()                            */
    3454                 : /************************************************************************/
    3455                 : 
    3456                 : /**
    3457                 :   * \brief Return the child index of the named projection parameter on
    3458                 :   * its parent PROJCS node.
    3459                 :   *
    3460                 :   * @param pszParameter projection parameter to look for
    3461                 :   * @param poPROJCS projection CS node to look in. If NULL is passed,
    3462                 :   *        the PROJCS node of the SpatialReference object will be searched.
    3463                 :   *
    3464                 :   * @return the child index of the named projection parameter. -1 on failure
    3465                 :   */
    3466          174024 : int OGRSpatialReference::FindProjParm( const char *pszParameter,
    3467                 :                                        const OGR_SRSNode *poPROJCS ) const
    3468                 : 
    3469                 : {
    3470          174024 :     const OGR_SRSNode *poParameter = NULL;
    3471                 : 
    3472          174024 :     if( poPROJCS == NULL )
    3473             970 :         poPROJCS = GetAttrNode( "PROJCS" );
    3474                 : 
    3475          174024 :     if( poPROJCS == NULL )
    3476             937 :         return -1;
    3477                 : 
    3478                 : /* -------------------------------------------------------------------- */
    3479                 : /*      Search for requested parameter.                                 */
    3480                 : /* -------------------------------------------------------------------- */
    3481                 :     int iChild;
    3482                 : 
    3483         1111522 :     for( iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
    3484                 :     {
    3485         1103030 :         poParameter = poPROJCS->GetChild(iChild);
    3486                 :         
    3487         1103030 :         if( EQUAL(poParameter->GetValue(),"PARAMETER")
    3488                 :             && poParameter->GetChildCount() == 2 
    3489                 :             && EQUAL(poPROJCS->GetChild(iChild)->GetChild(0)->GetValue(),
    3490                 :                      pszParameter) )
    3491                 :         {
    3492          164595 :             return iChild;
    3493                 :         }
    3494                 :     }
    3495                 : 
    3496                 : /* -------------------------------------------------------------------- */
    3497                 : /*      Try similar names, for selected parameters.                     */
    3498                 : /* -------------------------------------------------------------------- */
    3499            8492 :     iChild = -1;
    3500                 : 
    3501            8492 :     if( EQUAL(pszParameter,SRS_PP_LATITUDE_OF_ORIGIN) )
    3502                 :     {
    3503             103 :         iChild = FindProjParm( SRS_PP_LATITUDE_OF_CENTER, poPROJCS );
    3504                 :     }
    3505            8389 :     else if( EQUAL(pszParameter,SRS_PP_CENTRAL_MERIDIAN) )
    3506                 :     {
    3507              41 :         iChild = FindProjParm(SRS_PP_LONGITUDE_OF_CENTER, poPROJCS );
    3508              41 :         if( iChild == -1 )
    3509               3 :             iChild = FindProjParm(SRS_PP_LONGITUDE_OF_ORIGIN, poPROJCS );
    3510                 :     }
    3511                 : 
    3512            8492 :     return iChild;
    3513                 : }
    3514                 : 
    3515                 : /************************************************************************/
    3516                 : /*                            GetProjParm()                             */
    3517                 : /************************************************************************/
    3518                 : 
    3519                 : /**
    3520                 :  * \brief Fetch a projection parameter value.
    3521                 :  *
    3522                 :  * NOTE: This code should be modified to translate non degree angles into
    3523                 :  * degrees based on the GEOGCS unit.  This has not yet been done.
    3524                 :  *
    3525                 :  * This method is the same as the C function OSRGetProjParm().
    3526                 :  *
    3527                 :  * @param pszName the name of the parameter to fetch, from the set of 
    3528                 :  * SRS_PP codes in ogr_srs_api.h.
    3529                 :  *
    3530                 :  * @param dfDefaultValue the value to return if this parameter doesn't exist.
    3531                 :  *
    3532                 :  * @param pnErr place to put error code on failure.  Ignored if NULL.
    3533                 :  *
    3534                 :  * @return value of parameter.
    3535                 :  */
    3536                 : 
    3537          170547 : double OGRSpatialReference::GetProjParm( const char * pszName,
    3538                 :                                          double dfDefaultValue,
    3539                 :                                          OGRErr *pnErr ) const
    3540                 : 
    3541                 : {
    3542          170547 :     const OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
    3543                 : 
    3544          170547 :     if( pnErr != NULL )
    3545           21666 :         *pnErr = OGRERR_NONE;
    3546                 :     
    3547                 : /* -------------------------------------------------------------------- */
    3548                 : /*      Find the desired parameter.                                     */
    3549                 : /* -------------------------------------------------------------------- */
    3550          170547 :     int iChild = FindProjParm( pszName, poPROJCS );
    3551                 : 
    3552          170547 :     if( iChild != -1 )
    3553                 :     {
    3554          161727 :         const OGR_SRSNode *poParameter = NULL;
    3555          161727 :         poParameter = poPROJCS->GetChild(iChild);
    3556          161727 :         return CPLAtof(poParameter->GetChild(1)->GetValue());
    3557                 :     }
    3558                 : 
    3559                 : /* -------------------------------------------------------------------- */
    3560                 : /*      Return default value on failure.                                */
    3561                 : /* -------------------------------------------------------------------- */
    3562            8820 :     if( pnErr != NULL )
    3563              39 :         *pnErr = OGRERR_FAILURE;
    3564                 : 
    3565            8820 :     return dfDefaultValue;
    3566                 : }
    3567                 : 
    3568                 : /************************************************************************/
    3569                 : /*                           OSRGetProjParm()                           */
    3570                 : /************************************************************************/
    3571                 : 
    3572                 : /**
    3573                 :  * \brief Fetch a projection parameter value.
    3574                 :  *
    3575                 :  * This function is the same as OGRSpatialReference::GetProjParm()
    3576                 :  */
    3577            8816 : double OSRGetProjParm( OGRSpatialReferenceH hSRS, const char *pszName,
    3578                 :                        double dfDefaultValue, OGRErr *pnErr )
    3579                 : 
    3580                 : {
    3581            8816 :     VALIDATE_POINTER1( hSRS, "OSRGetProjParm", 0 );
    3582                 : 
    3583                 :     return ((OGRSpatialReference *) hSRS)->
    3584            8816 :         GetProjParm(pszName, dfDefaultValue, pnErr);
    3585                 : }
    3586                 : 
    3587                 : /************************************************************************/
    3588                 : /*                          GetNormProjParm()                           */
    3589                 : /************************************************************************/
    3590                 : 
    3591                 : /**
    3592                 :  * \brief Fetch a normalized projection parameter value.
    3593                 :  *
    3594                 :  * This method is the same as GetProjParm() except that the value of
    3595                 :  * the parameter is "normalized" into degrees or meters depending on 
    3596                 :  * whether it is linear or angular.
    3597                 :  *
    3598                 :  * This method is the same as the C function OSRGetNormProjParm().
    3599                 :  *
    3600                 :  * @param pszName the name of the parameter to fetch, from the set of 
    3601                 :  * SRS_PP codes in ogr_srs_api.h.
    3602                 :  *
    3603                 :  * @param dfDefaultValue the value to return if this parameter doesn't exist.
    3604                 :  *
    3605                 :  * @param pnErr place to put error code on failure.  Ignored if NULL.
    3606                 :  *
    3607                 :  * @return value of parameter.
    3608                 :  */
    3609                 : 
    3610           21666 : double OGRSpatialReference::GetNormProjParm( const char * pszName,
    3611                 :                                              double dfDefaultValue,
    3612                 :                                              OGRErr *pnErr ) const
    3613                 : 
    3614                 : {
    3615                 :     double dfRawResult;
    3616                 :     OGRErr nError;
    3617                 : 
    3618           21666 :     if( pnErr == NULL )
    3619           21666 :         pnErr = &nError;
    3620                 : 
    3621           21666 :     GetNormInfo();
    3622                 : 
    3623           21666 :     dfRawResult = GetProjParm( pszName, dfDefaultValue, pnErr );
    3624                 : 
    3625                 :     // If we got the default just return it unadjusted.
    3626           21666 :     if( *pnErr != OGRERR_NONE )
    3627              39 :         return dfRawResult;
    3628                 : 
    3629           21627 :     if( dfToDegrees != 1.0 && IsAngularParameter(pszName) )
    3630               6 :         dfRawResult *= dfToDegrees;
    3631                 : 
    3632           21627 :     if( dfToMeter != 1.0 && IsLinearParameter( pszName ) )
    3633             152 :         return dfRawResult * dfToMeter;
    3634                 : #ifdef WKT_LONGITUDE_RELATIVE_TO_PM
    3635                 :     else if( dfFromGreenwich != 0.0 && IsLongitudeParameter( pszName ) )
    3636                 :         return dfRawResult + dfFromGreenwich;
    3637                 : #endif
    3638                 :     else
    3639           21475 :         return dfRawResult;
    3640                 : }
    3641                 : 
    3642                 : /************************************************************************/
    3643                 : /*                         OSRGetNormProjParm()                         */
    3644                 : /************************************************************************/
    3645                 : 
    3646                 : /**
    3647                 :  * \brief This function is the same as OGRSpatialReference::
    3648                 :  *
    3649                 :  * This function is the same as OGRSpatialReference::GetNormProjParm()
    3650                 :  */
    3651               0 : double OSRGetNormProjParm( OGRSpatialReferenceH hSRS, const char *pszName,
    3652                 :                            double dfDefaultValue, OGRErr *pnErr )
    3653                 : 
    3654                 : {
    3655               0 :     VALIDATE_POINTER1( hSRS, "OSRGetNormProjParm", 0 );
    3656                 : 
    3657                 :     return ((OGRSpatialReference *) hSRS)->
    3658               0 :         GetNormProjParm(pszName, dfDefaultValue, pnErr);
    3659                 : }
    3660                 : 
    3661                 : /************************************************************************/
    3662                 : /*                          SetNormProjParm()                           */
    3663                 : /************************************************************************/
    3664                 : 
    3665                 : /**
    3666                 :  * \brief Set a projection parameter with a normalized value.
    3667                 :  *
    3668                 :  * This method is the same as SetProjParm() except that the value of
    3669                 :  * the parameter passed in is assumed to be in "normalized" form (decimal
    3670                 :  * degrees for angular values, meters for linear values.  The values are 
    3671                 :  * converted in a form suitable for the GEOGCS and linear units in effect.
    3672                 :  *
    3673                 :  * This method is the same as the C function OSRSetNormProjParm().
    3674                 :  *
    3675                 :  * @param pszName the parameter name, which should be selected from
    3676                 :  * the macros in ogr_srs_api.h, such as SRS_PP_CENTRAL_MERIDIAN. 
    3677                 :  *
    3678                 :  * @param dfValue value to assign. 
    3679                 :  * 
    3680                 :  * @return OGRERR_NONE on success.
    3681                 :  */
    3682                 : 
    3683           87669 : OGRErr OGRSpatialReference::SetNormProjParm( const char * pszName,
    3684                 :                                              double dfValue )
    3685                 : 
    3686                 : {
    3687           87669 :     GetNormInfo();
    3688                 : 
    3689           87669 :     if( (dfToDegrees != 1.0 || dfFromGreenwich != 0.0) 
    3690                 :         && IsAngularParameter(pszName) )
    3691                 :     {
    3692                 : #ifdef WKT_LONGITUDE_RELATIVE_TO_PM
    3693                 :         if( dfFromGreenwich != 0.0 && IsLongitudeParameter( pszName ) )
    3694                 :             dfValue -= dfFromGreenwich;
    3695                 : #endif
    3696                 : 
    3697             884 :         dfValue /= dfToDegrees;
    3698                 :     }
    3699           86785 :     else if( dfToMeter != 1.0 && IsLinearParameter( pszName ) )
    3700            4468 :         dfValue /= dfToMeter;
    3701                 : 
    3702           87669 :     return SetProjParm( pszName, dfValue );
    3703                 : }
    3704                 : 
    3705                 : /************************************************************************/
    3706                 : /*                         OSRSetNormProjParm()                         */
    3707                 : /************************************************************************/
    3708                 : 
    3709                 : /**
    3710                 :  * \brief Set a projection parameter with a normalized value.
    3711                 :  *
    3712                 :  * This function is the same as OGRSpatialReference::SetNormProjParm()
    3713                 :  */
    3714               0 : OGRErr OSRSetNormProjParm( OGRSpatialReferenceH hSRS, 
    3715                 :                            const char * pszParmName, double dfValue )
    3716                 : 
    3717                 : {
    3718               0 :     VALIDATE_POINTER1( hSRS, "OSRSetNormProjParm", CE_Failure );
    3719                 : 
    3720                 :     return ((OGRSpatialReference *) hSRS)->
    3721               0 :         SetNormProjParm( pszParmName, dfValue );
    3722                 : }
    3723                 : 
    3724                 : /************************************************************************/
    3725                 : /*                               SetTM()                                */
    3726                 : /************************************************************************/
    3727                 : 
    3728           12439 : OGRErr OGRSpatialReference::SetTM( double dfCenterLat, double dfCenterLong,
    3729                 :                                    double dfScale,
    3730                 :                                    double dfFalseEasting,
    3731                 :                                    double dfFalseNorthing )
    3732                 : 
    3733                 : {
    3734           12439 :     SetProjection( SRS_PT_TRANSVERSE_MERCATOR );
    3735           12439 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    3736           12439 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    3737           12439 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    3738           12439 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3739           12439 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3740                 : 
    3741           12439 :     return OGRERR_NONE;
    3742                 : }
    3743                 : 
    3744                 : /************************************************************************/
    3745                 : /*                              OSRSetTM()                              */
    3746                 : /************************************************************************/
    3747                 : 
    3748               0 : OGRErr OSRSetTM( OGRSpatialReferenceH hSRS, 
    3749                 :                  double dfCenterLat, double dfCenterLong,
    3750                 :                  double dfScale,
    3751                 :                  double dfFalseEasting,
    3752                 :                  double dfFalseNorthing )
    3753                 : 
    3754                 : {
    3755               0 :     VALIDATE_POINTER1( hSRS, "OSRSetTM", CE_Failure );
    3756                 : 
    3757                 :     return ((OGRSpatialReference *) hSRS)->SetTM( 
    3758                 :         dfCenterLat, dfCenterLong, 
    3759                 :         dfScale, 
    3760               0 :         dfFalseEasting, dfFalseNorthing );
    3761                 : }
    3762                 : 
    3763                 : /************************************************************************/
    3764                 : /*                            SetTMVariant()                            */
    3765                 : /************************************************************************/
    3766                 : 
    3767               0 : OGRErr OGRSpatialReference::SetTMVariant( 
    3768                 :     const char *pszVariantName,
    3769                 :     double dfCenterLat, double dfCenterLong,
    3770                 :     double dfScale,
    3771                 :     double dfFalseEasting,
    3772                 :     double dfFalseNorthing )
    3773                 : 
    3774                 : {
    3775               0 :     SetProjection( pszVariantName );
    3776               0 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    3777               0 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    3778               0 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    3779               0 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3780               0 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3781                 : 
    3782               0 :     return OGRERR_NONE;
    3783                 : }
    3784                 : 
    3785                 : /************************************************************************/
    3786                 : /*                          OSRSetTMVariant()                           */
    3787                 : /************************************************************************/
    3788                 : 
    3789               0 : OGRErr OSRSetTMVariant( OGRSpatialReferenceH hSRS, 
    3790                 :                         const char *pszVariantName,
    3791                 :                         double dfCenterLat, double dfCenterLong,
    3792                 :                         double dfScale,
    3793                 :                         double dfFalseEasting,
    3794                 :                         double dfFalseNorthing )
    3795                 : 
    3796                 : {
    3797               0 :     VALIDATE_POINTER1( hSRS, "OSRSetTMVariant", CE_Failure );
    3798                 : 
    3799                 :     return ((OGRSpatialReference *) hSRS)->SetTMVariant( 
    3800                 :         pszVariantName,
    3801                 :         dfCenterLat, dfCenterLong, 
    3802                 :         dfScale, 
    3803               0 :         dfFalseEasting, dfFalseNorthing );
    3804                 : }
    3805                 : 
    3806                 : /************************************************************************/
    3807                 : /*                              SetTMSO()                               */
    3808                 : /************************************************************************/
    3809                 : 
    3810             118 : OGRErr OGRSpatialReference::SetTMSO( double dfCenterLat, double dfCenterLong,
    3811                 :                                      double dfScale,
    3812                 :                                      double dfFalseEasting,
    3813                 :                                      double dfFalseNorthing )
    3814                 : 
    3815                 : {
    3816             118 :     SetProjection( SRS_PT_TRANSVERSE_MERCATOR_SOUTH_ORIENTED );
    3817             118 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    3818             118 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    3819             118 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    3820             118 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3821             118 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3822                 : 
    3823             118 :     return OGRERR_NONE;
    3824                 : }
    3825                 : 
    3826                 : /************************************************************************/
    3827                 : /*                              SetTPED()                               */
    3828                 : /************************************************************************/
    3829                 : 
    3830               2 : OGRErr OGRSpatialReference::SetTPED( double dfLat1, double dfLong1, 
    3831                 :                                      double dfLat2, double dfLong2,
    3832                 :                                      double dfFalseEasting,
    3833                 :                                      double dfFalseNorthing )
    3834                 : 
    3835                 : {
    3836               2 :     SetProjection( SRS_PT_TWO_POINT_EQUIDISTANT );
    3837               2 :     SetNormProjParm( SRS_PP_LATITUDE_OF_1ST_POINT, dfLat1 );
    3838               2 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_1ST_POINT, dfLong1 );
    3839               2 :     SetNormProjParm( SRS_PP_LATITUDE_OF_2ND_POINT, dfLat2 );
    3840               2 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_2ND_POINT, dfLong2 );
    3841               2 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3842               2 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3843                 : 
    3844               2 :     return OGRERR_NONE;
    3845                 : }
    3846                 : 
    3847                 : /************************************************************************/
    3848                 : /*                             OSRSetTPED()                             */
    3849                 : /************************************************************************/
    3850                 : 
    3851               0 : OGRErr OSRSetTPED( OGRSpatialReferenceH hSRS,
    3852                 :                    double dfLat1, double dfLong1,
    3853                 :                    double dfLat2, double dfLong2,
    3854                 :                    double dfFalseEasting, double dfFalseNorthing )
    3855                 : 
    3856                 : {
    3857               0 :     VALIDATE_POINTER1( hSRS, "OSRSetTPED", CE_Failure );
    3858                 : 
    3859                 :     return ((OGRSpatialReference *) hSRS)->SetTPED( 
    3860                 :         dfLat1, dfLong1, dfLat2, dfLong2,
    3861               0 :         dfFalseEasting, dfFalseNorthing );
    3862                 : }
    3863                 : 
    3864                 : /************************************************************************/
    3865                 : /*                             OSRSetTMSO()                             */
    3866                 : /************************************************************************/
    3867                 : 
    3868               0 : OGRErr OSRSetTMSO( OGRSpatialReferenceH hSRS, 
    3869                 :                  double dfCenterLat, double dfCenterLong,
    3870                 :                  double dfScale,
    3871                 :                  double dfFalseEasting,
    3872                 :                  double dfFalseNorthing )
    3873                 : 
    3874                 : {
    3875               0 :     VALIDATE_POINTER1( hSRS, "OSRSetTMSO", CE_Failure );
    3876                 : 
    3877                 :     return ((OGRSpatialReference *) hSRS)->SetTMSO( 
    3878                 :         dfCenterLat, dfCenterLong, 
    3879                 :         dfScale, 
    3880               0 :         dfFalseEasting, dfFalseNorthing );
    3881                 : }
    3882                 : 
    3883                 : /************************************************************************/
    3884                 : /*                               SetTMG()                               */
    3885                 : /************************************************************************/
    3886                 : 
    3887                 : OGRErr 
    3888               4 : OGRSpatialReference::SetTMG( double dfCenterLat, double dfCenterLong,
    3889                 :                              double dfFalseEasting, double dfFalseNorthing )
    3890                 :     
    3891                 : {
    3892               4 :     SetProjection( SRS_PT_TUNISIA_MINING_GRID );
    3893               4 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    3894               4 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    3895               4 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3896               4 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3897                 : 
    3898               4 :     return OGRERR_NONE;
    3899                 : }
    3900                 : 
    3901                 : /************************************************************************/
    3902                 : /*                             OSRSetTMG()                              */
    3903                 : /************************************************************************/
    3904                 : 
    3905               0 : OGRErr OSRSetTMG( OGRSpatialReferenceH hSRS, 
    3906                 :                  double dfCenterLat, double dfCenterLong,
    3907                 :                  double dfFalseEasting,
    3908                 :                  double dfFalseNorthing )
    3909                 : 
    3910                 : {
    3911               0 :     VALIDATE_POINTER1( hSRS, "OSRSetTMG", CE_Failure );
    3912                 : 
    3913                 :     return ((OGRSpatialReference *) hSRS)->SetTMG( 
    3914                 :         dfCenterLat, dfCenterLong, 
    3915               0 :         dfFalseEasting, dfFalseNorthing );
    3916                 : }
    3917                 : 
    3918                 : /************************************************************************/
    3919                 : /*                              SetACEA()                               */
    3920                 : /************************************************************************/
    3921                 : 
    3922             129 : OGRErr OGRSpatialReference::SetACEA( double dfStdP1, double dfStdP2,
    3923                 :                                      double dfCenterLat, double dfCenterLong,
    3924                 :                                      double dfFalseEasting,
    3925                 :                                      double dfFalseNorthing )
    3926                 : 
    3927                 : {
    3928             129 :     SetProjection( SRS_PT_ALBERS_CONIC_EQUAL_AREA );
    3929             129 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
    3930             129 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
    3931             129 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    3932             129 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    3933             129 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3934             129 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3935                 : 
    3936             129 :     return OGRERR_NONE;
    3937                 : }
    3938                 : 
    3939                 : /************************************************************************/
    3940                 : /*                             OSRSetACEA()                             */
    3941                 : /************************************************************************/
    3942                 : 
    3943               0 : OGRErr OSRSetACEA( OGRSpatialReferenceH hSRS, 
    3944                 :                    double dfStdP1, double dfStdP2,
    3945                 :                    double dfCenterLat, double dfCenterLong,
    3946                 :                    double dfFalseEasting,
    3947                 :                    double dfFalseNorthing )
    3948                 : 
    3949                 : {
    3950               0 :     VALIDATE_POINTER1( hSRS, "OSRSetACEA", CE_Failure );
    3951                 : 
    3952                 :     return ((OGRSpatialReference *) hSRS)->SetACEA( 
    3953                 :         dfStdP1, dfStdP2, 
    3954                 :         dfCenterLat, dfCenterLong, 
    3955               0 :         dfFalseEasting, dfFalseNorthing );
    3956                 : }
    3957                 : 
    3958                 : /************************************************************************/
    3959                 : /*                               SetAE()                                */
    3960                 : /************************************************************************/
    3961                 : 
    3962              22 : OGRErr OGRSpatialReference::SetAE( double dfCenterLat, double dfCenterLong,
    3963                 :                                    double dfFalseEasting,
    3964                 :                                    double dfFalseNorthing )
    3965                 : 
    3966                 : {
    3967              22 :     SetProjection( SRS_PT_AZIMUTHAL_EQUIDISTANT );
    3968              22 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    3969              22 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    3970              22 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3971              22 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3972                 : 
    3973              22 :     return OGRERR_NONE;
    3974                 : }
    3975                 : 
    3976                 : /************************************************************************/
    3977                 : /*                              OSRSetAE()                              */
    3978                 : /************************************************************************/
    3979                 : 
    3980               0 : OGRErr OSRSetAE( OGRSpatialReferenceH hSRS, 
    3981                 :                  double dfCenterLat, double dfCenterLong,
    3982                 :                  double dfFalseEasting,
    3983                 :                  double dfFalseNorthing )
    3984                 : 
    3985                 : {
    3986               0 :     VALIDATE_POINTER1( hSRS, "OSRSetACEA", CE_Failure );
    3987                 : 
    3988                 :     return ((OGRSpatialReference *) hSRS)->SetAE( 
    3989                 :         dfCenterLat, dfCenterLong, 
    3990               0 :         dfFalseEasting, dfFalseNorthing );
    3991                 : }
    3992                 : 
    3993                 : /************************************************************************/
    3994                 : /*                              SetBonne()                              */
    3995                 : /************************************************************************/
    3996                 : 
    3997               1 : OGRErr OGRSpatialReference::SetBonne( 
    3998                 :     double dfStdP1, double dfCentralMeridian,
    3999                 :     double dfFalseEasting, double dfFalseNorthing )
    4000                 : 
    4001                 : {
    4002               1 :     SetProjection( SRS_PT_BONNE );
    4003               1 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
    4004               1 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    4005               1 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4006               1 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4007                 : 
    4008               1 :     return OGRERR_NONE;
    4009                 : }
    4010                 : 
    4011                 : /************************************************************************/
    4012                 : /*                            OSRSetBonne()                             */
    4013                 : /************************************************************************/
    4014                 : 
    4015               0 : OGRErr OSRSetBonne( OGRSpatialReferenceH hSRS, 
    4016                 :                     double dfStdP1, double dfCentralMeridian,
    4017                 :                     double dfFalseEasting, double dfFalseNorthing )
    4018                 :     
    4019                 : {
    4020               0 :     VALIDATE_POINTER1( hSRS, "OSRSetBonne", CE_Failure );
    4021                 : 
    4022                 :     return ((OGRSpatialReference *) hSRS)->SetBonne( 
    4023                 :         dfStdP1, dfCentralMeridian,
    4024               0 :         dfFalseEasting, dfFalseNorthing );
    4025                 : }
    4026                 : 
    4027                 : /************************************************************************/
    4028                 : /*                               SetCEA()                               */
    4029                 : /************************************************************************/
    4030                 : 
    4031              24 : OGRErr OGRSpatialReference::SetCEA( double dfStdP1, double dfCentralMeridian,
    4032                 :                                     double dfFalseEasting,
    4033                 :                                     double dfFalseNorthing )
    4034                 : 
    4035                 : {
    4036              24 :     SetProjection( SRS_PT_CYLINDRICAL_EQUAL_AREA );
    4037              24 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
    4038              24 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    4039              24 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4040              24 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4041                 : 
    4042              24 :     return OGRERR_NONE;
    4043                 : }
    4044                 : 
    4045                 : /************************************************************************/
    4046                 : /*                             OSRSetCEA()                              */
    4047                 : /************************************************************************/
    4048                 : 
    4049               0 : OGRErr OSRSetCEA( OGRSpatialReferenceH hSRS, 
    4050                 :                   double dfStdP1, double dfCentralMeridian,
    4051                 :                   double dfFalseEasting, double dfFalseNorthing )
    4052                 : 
    4053                 : {
    4054               0 :     VALIDATE_POINTER1( hSRS, "OSRSetCEA", CE_Failure );
    4055                 : 
    4056                 :     return ((OGRSpatialReference *) hSRS)->SetCEA( 
    4057                 :         dfStdP1, dfCentralMeridian,
    4058               0 :         dfFalseEasting, dfFalseNorthing );
    4059                 : }
    4060                 : 
    4061                 : /************************************************************************/
    4062                 : /*                               SetCS()                                */
    4063                 : /************************************************************************/
    4064                 : 
    4065              87 : OGRErr OGRSpatialReference::SetCS( double dfCenterLat, double dfCenterLong,
    4066                 :                                    double dfFalseEasting,
    4067                 :                                    double dfFalseNorthing )
    4068                 : 
    4069                 : {
    4070              87 :     SetProjection( SRS_PT_CASSINI_SOLDNER );
    4071              87 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4072              87 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4073              87 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4074              87 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4075                 : 
    4076              87 :     return OGRERR_NONE;
    4077                 : }
    4078                 : 
    4079                 : /************************************************************************/
    4080                 : /*                              OSRSetCS()                              */
    4081                 : /************************************************************************/
    4082                 : 
    4083               0 : OGRErr OSRSetCS( OGRSpatialReferenceH hSRS, 
    4084                 :                  double dfCenterLat, double dfCenterLong,
    4085                 :                  double dfFalseEasting,
    4086                 :                  double dfFalseNorthing )
    4087                 : 
    4088                 : {
    4089               0 :     VALIDATE_POINTER1( hSRS, "OSRSetCS", CE_Failure );
    4090                 : 
    4091                 :     return ((OGRSpatialReference *) hSRS)->SetCS( 
    4092                 :         dfCenterLat, dfCenterLong, 
    4093               0 :         dfFalseEasting, dfFalseNorthing );
    4094                 : }
    4095                 : 
    4096                 : /************************************************************************/
    4097                 : /*                               SetEC()                                */
    4098                 : /************************************************************************/
    4099                 : 
    4100               3 : OGRErr OGRSpatialReference::SetEC( double dfStdP1, double dfStdP2,
    4101                 :                                    double dfCenterLat, double dfCenterLong,
    4102                 :                                    double dfFalseEasting,
    4103                 :                                    double dfFalseNorthing )
    4104                 : 
    4105                 : {
    4106               3 :     SetProjection( SRS_PT_EQUIDISTANT_CONIC );
    4107               3 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
    4108               3 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
    4109               3 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    4110               3 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    4111               3 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4112               3 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4113                 : 
    4114               3 :     return OGRERR_NONE;
    4115                 : }
    4116                 : 
    4117                 : /************************************************************************/
    4118                 : /*                              OSRSetEC()                              */
    4119                 : /************************************************************************/
    4120                 : 
    4121               0 : OGRErr OSRSetEC( OGRSpatialReferenceH hSRS, 
    4122                 :                  double dfStdP1, double dfStdP2,
    4123                 :                  double dfCenterLat, double dfCenterLong,
    4124                 :                  double dfFalseEasting,
    4125                 :                  double dfFalseNorthing )
    4126                 : 
    4127                 : {
    4128               0 :     VALIDATE_POINTER1( hSRS, "OSRSetEC", CE_Failure );
    4129                 : 
    4130                 :     return ((OGRSpatialReference *) hSRS)->SetEC( 
    4131                 :         dfStdP1, dfStdP2, 
    4132                 :         dfCenterLat, dfCenterLong, 
    4133               0 :         dfFalseEasting, dfFalseNorthing );
    4134                 : }
    4135                 : 
    4136                 : /************************************************************************/
    4137                 : /*                             SetEckert()                              */
    4138                 : /************************************************************************/
    4139                 : 
    4140               7 : OGRErr OGRSpatialReference::SetEckert( int nVariation /* 1-6 */,
    4141                 :                                        double dfCentralMeridian,
    4142                 :                                        double dfFalseEasting,
    4143                 :                                        double dfFalseNorthing )
    4144                 : 
    4145                 : {
    4146               7 :     if( nVariation == 1 )
    4147               1 :         SetProjection( SRS_PT_ECKERT_I );
    4148               6 :     else if( nVariation == 2 )
    4149               1 :         SetProjection( SRS_PT_ECKERT_II );
    4150               5 :     else if( nVariation == 3 )
    4151               1 :         SetProjection( SRS_PT_ECKERT_III );
    4152               4 :     else if( nVariation == 4 )
    4153               2 :         SetProjection( SRS_PT_ECKERT_IV );
    4154               2 :     else if( nVariation == 5 )
    4155               1 :         SetProjection( SRS_PT_ECKERT_V );
    4156               1 :     else if( nVariation == 6 )
    4157               1 :         SetProjection( SRS_PT_ECKERT_VI );
    4158                 :     else
    4159                 :     {
    4160                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    4161                 :                   "Unsupported Eckert variation (%d).", 
    4162               0 :                   nVariation );
    4163               0 :         return OGRERR_UNSUPPORTED_SRS;
    4164                 :     }
    4165                 : 
    4166               7 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    4167               7 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4168               7 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4169                 : 
    4170               7 :     return OGRERR_NONE;
    4171                 : }
    4172                 : 
    4173                 : /************************************************************************/
    4174                 : /*                            OSRSetEckert()                            */
    4175                 : /************************************************************************/
    4176                 : 
    4177               0 : OGRErr OSRSetEckert( OGRSpatialReferenceH hSRS, 
    4178                 :                      int nVariation,
    4179                 :                      double dfCentralMeridian,
    4180                 :                      double dfFalseEasting,
    4181                 :                      double dfFalseNorthing )
    4182                 : 
    4183                 : {
    4184               0 :     VALIDATE_POINTER1( hSRS, "OSRSetEckert", CE_Failure );
    4185                 : 
    4186                 :     return ((OGRSpatialReference *) hSRS)->SetEckert( 
    4187                 :         nVariation, dfCentralMeridian,
    4188               0 :         dfFalseEasting, dfFalseNorthing );
    4189                 : }
    4190                 : 
    4191                 : /************************************************************************/
    4192                 : /*                            SetEckertIV()                             */
    4193                 : /*                                                                      */
    4194                 : /*      Deprecated                                                      */
    4195                 : /************************************************************************/
    4196                 : 
    4197               0 : OGRErr OGRSpatialReference::SetEckertIV( double dfCentralMeridian,
    4198                 :                                          double dfFalseEasting,
    4199                 :                                          double dfFalseNorthing )
    4200                 : 
    4201                 : {
    4202               0 :     SetProjection( SRS_PT_ECKERT_IV );
    4203               0 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    4204               0 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4205               0 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4206                 : 
    4207               0 :     return OGRERR_NONE;
    4208                 : }
    4209                 : 
    4210                 : /************************************************************************/
    4211                 : /*                           OSRSetEckertIV()                           */
    4212                 : /************************************************************************/
    4213                 : 
    4214               0 : OGRErr OSRSetEckertIV( OGRSpatialReferenceH hSRS, 
    4215                 :                        double dfCentralMeridian,
    4216                 :                        double dfFalseEasting,
    4217                 :                        double dfFalseNorthing )
    4218                 : 
    4219                 : {
    4220               0 :     VALIDATE_POINTER1( hSRS, "OSRSetEckertIV", CE_Failure );
    4221                 : 
    4222                 :     return ((OGRSpatialReference *) hSRS)->SetEckertIV( 
    4223                 :         dfCentralMeridian,
    4224               0 :         dfFalseEasting, dfFalseNorthing );
    4225                 : }
    4226                 : 
    4227                 : /************************************************************************/
    4228                 : /*                            SetEckertVI()                             */
    4229                 : /*                                                                      */
    4230                 : /*      Deprecated                                                      */
    4231                 : /************************************************************************/
    4232                 : 
    4233               0 : OGRErr OGRSpatialReference::SetEckertVI( double dfCentralMeridian,
    4234                 :                                          double dfFalseEasting,
    4235                 :                                          double dfFalseNorthing )
    4236                 : 
    4237                 : {
    4238               0 :     SetProjection( SRS_PT_ECKERT_VI );
    4239               0 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    4240               0 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4241               0 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4242                 : 
    4243               0 :     return OGRERR_NONE;
    4244                 : }
    4245                 : 
    4246                 : /************************************************************************/
    4247                 : /*                           OSRSetEckertVI()                           */
    4248                 : /************************************************************************/
    4249                 : 
    4250               0 : OGRErr OSRSetEckertVI( OGRSpatialReferenceH hSRS, 
    4251                 :                        double dfCentralMeridian,
    4252                 :                        double dfFalseEasting,
    4253                 :                        double dfFalseNorthing )
    4254                 : 
    4255                 : {
    4256               0 :     VALIDATE_POINTER1( hSRS, "OSRSetEckertVI", CE_Failure );
    4257                 : 
    4258                 :     return ((OGRSpatialReference *) hSRS)->SetEckertVI( 
    4259                 :         dfCentralMeridian,
    4260               0 :         dfFalseEasting, dfFalseNorthing );
    4261                 : }
    4262                 : 
    4263                 : /************************************************************************/
    4264                 : /*                         SetEquirectangular()                         */
    4265                 : /************************************************************************/
    4266                 : 
    4267              21 : OGRErr OGRSpatialReference::SetEquirectangular(
    4268                 :                                    double dfCenterLat, double dfCenterLong,
    4269                 :                                    double dfFalseEasting,
    4270                 :                                    double dfFalseNorthing )
    4271                 : 
    4272                 : {
    4273              21 :     SetProjection( SRS_PT_EQUIRECTANGULAR );
    4274              21 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4275              21 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4276              21 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4277              21 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4278                 : 
    4279              21 :     return OGRERR_NONE;
    4280                 : }
    4281                 : 
    4282                 : /************************************************************************/
    4283                 : /*                       OSRSetEquirectangular()                        */
    4284                 : /************************************************************************/
    4285                 : 
    4286               0 : OGRErr OSRSetEquirectangular( OGRSpatialReferenceH hSRS, 
    4287                 :                               double dfCenterLat, double dfCenterLong,
    4288                 :                               double dfFalseEasting,
    4289                 :                               double dfFalseNorthing )
    4290                 :     
    4291                 : {
    4292               0 :     VALIDATE_POINTER1( hSRS, "OSRSetEquirectangular", CE_Failure );
    4293                 : 
    4294                 :     return ((OGRSpatialReference *) hSRS)->SetEquirectangular( 
    4295                 :         dfCenterLat, dfCenterLong, 
    4296               0 :         dfFalseEasting, dfFalseNorthing );
    4297                 : }
    4298                 : 
    4299                 : /************************************************************************/
    4300                 : /*                         SetEquirectangular2()                        */
    4301                 : /* Generalized form                                                     */
    4302                 : /************************************************************************/
    4303                 : 
    4304              14 : OGRErr OGRSpatialReference::SetEquirectangular2(
    4305                 :                                    double dfCenterLat, double dfCenterLong,
    4306                 :                                    double dfStdParallel1,
    4307                 :                                    double dfFalseEasting,
    4308                 :                                    double dfFalseNorthing )
    4309                 : 
    4310                 : {
    4311              14 :     SetProjection( SRS_PT_EQUIRECTANGULAR );
    4312              14 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4313              14 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4314              14 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdParallel1 );
    4315              14 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4316              14 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4317                 : 
    4318              14 :     return OGRERR_NONE;
    4319                 : }
    4320                 : 
    4321                 : /************************************************************************/
    4322                 : /*                       OSRSetEquirectangular2()                       */
    4323                 : /************************************************************************/
    4324                 : 
    4325               0 : OGRErr OSRSetEquirectangular2( OGRSpatialReferenceH hSRS, 
    4326                 :                                double dfCenterLat, double dfCenterLong,
    4327                 :                                double dfStdParallel1,
    4328                 :                                double dfFalseEasting,
    4329                 :                                double dfFalseNorthing )
    4330                 :     
    4331                 : {
    4332               0 :     VALIDATE_POINTER1( hSRS, "OSRSetEquirectangular2", CE_Failure );
    4333                 : 
    4334                 :     return ((OGRSpatialReference *) hSRS)->SetEquirectangular2( 
    4335                 :         dfCenterLat, dfCenterLong, 
    4336                 :         dfStdParallel1,
    4337               0 :         dfFalseEasting, dfFalseNorthing );
    4338                 : }
    4339                 : 
    4340                 : /************************************************************************/
    4341                 : /*                               SetGS()                                */
    4342                 : /************************************************************************/
    4343                 : 
    4344               3 : OGRErr OGRSpatialReference::SetGS( double dfCentralMeridian,
    4345                 :                                    double dfFalseEasting,
    4346                 :                                    double dfFalseNorthing )
    4347                 : 
    4348                 : {
    4349               3 :     SetProjection( SRS_PT_GALL_STEREOGRAPHIC );
    4350               3 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    4351               3 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4352               3 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4353                 : 
    4354               3 :     return OGRERR_NONE;
    4355                 : }
    4356                 : 
    4357                 : /************************************************************************/
    4358                 : /*                              OSRSetGS()                              */
    4359                 : /************************************************************************/
    4360                 : 
    4361               1 : OGRErr OSRSetGS( OGRSpatialReferenceH hSRS, 
    4362                 :                  double dfCentralMeridian,
    4363                 :                  double dfFalseEasting,
    4364                 :                  double dfFalseNorthing )
    4365                 : 
    4366                 : {
    4367               1 :     VALIDATE_POINTER1( hSRS, "OSRSetGS", CE_Failure );
    4368                 : 
    4369                 :     return ((OGRSpatialReference *) hSRS)->SetGS( 
    4370                 :         dfCentralMeridian,
    4371               1 :         dfFalseEasting, dfFalseNorthing );
    4372                 : }
    4373                 : 
    4374                 : /************************************************************************/
    4375                 : /*                               SetGH()                                */
    4376                 : /************************************************************************/
    4377                 : 
    4378               3 : OGRErr OGRSpatialReference::SetGH( double dfCentralMeridian,
    4379                 :                                    double dfFalseEasting,
    4380                 :                                    double dfFalseNorthing )
    4381                 : 
    4382                 : {
    4383               3 :     SetProjection( SRS_PT_GOODE_HOMOLOSINE );
    4384               3 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    4385               3 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4386               3 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4387                 : 
    4388               3 :     return OGRERR_NONE;
    4389                 : }
    4390                 : 
    4391                 : /************************************************************************/
    4392                 : /*                              OSRSetGH()                              */
    4393                 : /************************************************************************/
    4394                 : 
    4395               0 : OGRErr OSRSetGH( OGRSpatialReferenceH hSRS, 
    4396                 :                  double dfCentralMeridian,
    4397                 :                  double dfFalseEasting,
    4398                 :                  double dfFalseNorthing )
    4399                 : 
    4400                 : {
    4401               0 :     VALIDATE_POINTER1( hSRS, "OSRSetGH", CE_Failure );
    4402                 : 
    4403                 :     return ((OGRSpatialReference *) hSRS)->SetGH( 
    4404                 :         dfCentralMeridian,
    4405               0 :         dfFalseEasting, dfFalseNorthing );
    4406                 : }
    4407                 : 
    4408                 : /************************************************************************/
    4409                 : /*                              SetIGH()                                */
    4410                 : /************************************************************************/
    4411                 : 
    4412               1 : OGRErr OGRSpatialReference::SetIGH()
    4413                 : 
    4414                 : {
    4415               1 :     SetProjection( SRS_PT_IGH );
    4416                 : 
    4417               1 :     return OGRERR_NONE;
    4418                 : }
    4419                 : 
    4420                 : /************************************************************************/
    4421                 : /*                              OSRSetIGH()                             */
    4422                 : /************************************************************************/
    4423                 : 
    4424               0 : OGRErr OSRSetIGH( OGRSpatialReferenceH hSRS )
    4425                 : 
    4426                 : {
    4427               0 :     VALIDATE_POINTER1( hSRS, "OSRSetIGH", CE_Failure );
    4428                 : 
    4429               0 :     return ((OGRSpatialReference *) hSRS)->SetIGH();
    4430                 : }
    4431                 : 
    4432                 : /************************************************************************/
    4433                 : /*                              SetGEOS()                               */
    4434                 : /************************************************************************/
    4435                 : 
    4436               1 : OGRErr OGRSpatialReference::SetGEOS( double dfCentralMeridian,
    4437                 :                                      double dfSatelliteHeight,
    4438                 :                                      double dfFalseEasting,
    4439                 :                                      double dfFalseNorthing )
    4440                 : 
    4441                 : {
    4442               1 :     SetProjection( SRS_PT_GEOSTATIONARY_SATELLITE );
    4443               1 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    4444               1 :     SetNormProjParm( SRS_PP_SATELLITE_HEIGHT, dfSatelliteHeight );
    4445               1 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4446               1 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4447                 : 
    4448               1 :     return OGRERR_NONE;
    4449                 : }
    4450                 : 
    4451                 : /************************************************************************/
    4452                 : /*                              OSRSetGEOS()                             */
    4453                 : /************************************************************************/
    4454                 : 
    4455               0 : OGRErr OSRSetGEOS( OGRSpatialReferenceH hSRS, 
    4456                 :                    double dfCentralMeridian,
    4457                 :                    double dfSatelliteHeight,
    4458                 :                    double dfFalseEasting,
    4459                 :                    double dfFalseNorthing )
    4460                 : 
    4461                 : {
    4462               0 :     VALIDATE_POINTER1( hSRS, "OSRSetGEOS", CE_Failure );
    4463                 : 
    4464                 :     return ((OGRSpatialReference *) hSRS)->SetGEOS( 
    4465                 :         dfCentralMeridian, dfSatelliteHeight,
    4466               0 :         dfFalseEasting, dfFalseNorthing );
    4467                 : }
    4468                 : 
    4469                 : /************************************************************************/
    4470                 : /*                       SetGaussSchreiberTMercator()                   */
    4471                 : /************************************************************************/
    4472                 : 
    4473               1 : OGRErr OGRSpatialReference::SetGaussSchreiberTMercator(
    4474                 :                                    double dfCenterLat, double dfCenterLong,
    4475                 :                                    double dfScale,
    4476                 :                                    double dfFalseEasting,
    4477                 :                                    double dfFalseNorthing )
    4478                 : 
    4479                 : {
    4480               1 :     SetProjection( SRS_PT_GAUSSSCHREIBERTMERCATOR );
    4481               1 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4482               1 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4483               1 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    4484               1 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4485               1 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4486                 : 
    4487               1 :     return OGRERR_NONE;
    4488                 : }
    4489                 : 
    4490                 : /************************************************************************/
    4491                 : /*                     OSRSetGaussSchreiberTMercator()                  */
    4492                 : /************************************************************************/
    4493                 : 
    4494               0 : OGRErr OSRSetGaussSchreiberTMercator( OGRSpatialReferenceH hSRS,
    4495                 :                                       double dfCenterLat, double dfCenterLong,
    4496                 :                                       double dfScale,
    4497                 :                                       double dfFalseEasting,
    4498                 :                                       double dfFalseNorthing )
    4499                 : 
    4500                 : {
    4501               0 :     VALIDATE_POINTER1( hSRS, "OSRSetGaussSchreiberTMercator", CE_Failure );
    4502                 : 
    4503                 :     return ((OGRSpatialReference *) hSRS)->SetGaussSchreiberTMercator(
    4504                 :         dfCenterLat, dfCenterLong, dfScale,
    4505               0 :         dfFalseEasting, dfFalseNorthing );
    4506                 : }
    4507                 : 
    4508                 : /************************************************************************/
    4509                 : /*                            SetGnomonic()                             */
    4510                 : /************************************************************************/
    4511                 : 
    4512               1 : OGRErr OGRSpatialReference::SetGnomonic(
    4513                 :                                    double dfCenterLat, double dfCenterLong,
    4514                 :                                    double dfFalseEasting,
    4515                 :                                    double dfFalseNorthing )
    4516                 : 
    4517                 : {
    4518               1 :     SetProjection( SRS_PT_GNOMONIC );
    4519               1 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4520               1 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4521               1 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4522               1 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4523                 : 
    4524               1 :     return OGRERR_NONE;
    4525                 : }
    4526                 : 
    4527                 : /************************************************************************/
    4528                 : /*                           OSRSetGnomonic()                           */
    4529                 : /************************************************************************/
    4530                 : 
    4531               0 : OGRErr OSRSetGnomonic( OGRSpatialReferenceH hSRS, 
    4532                 :                        double dfCenterLat, double dfCenterLong,
    4533                 :                        double dfFalseEasting,
    4534                 :                        double dfFalseNorthing )
    4535                 :     
    4536                 : {
    4537               0 :     VALIDATE_POINTER1( hSRS, "OSRSetGnomonic", CE_Failure );
    4538                 : 
    4539                 :     return ((OGRSpatialReference *) hSRS)->SetGnomonic( 
    4540                 :         dfCenterLat, dfCenterLong, 
    4541               0 :         dfFalseEasting, dfFalseNorthing );
    4542                 : }
    4543                 : 
    4544                 : /************************************************************************/
    4545                 : /*                              SetHOMAC()                              */
    4546                 : /************************************************************************/
    4547                 : 
    4548                 : /**
    4549                 :  * \brief Set an Hotine Oblique Mercator Azimuth Center projection using 
    4550                 :  * azimuth angle.
    4551                 :  *
    4552                 :  * This projection corresponds to EPSG projection method 9815, also 
    4553                 :  * sometimes known as hotine oblique mercator (variant B).
    4554                 :  *
    4555                 :  * This method does the same thing as the C function OSRSetHOMAC().
    4556                 :  *
    4557                 :  * @param dfCenterLat Latitude of the projection origin.
    4558                 :  * @param dfCenterLong Longitude of the projection origin.
    4559                 :  * @param dfAzimuth Azimuth, measured clockwise from North, of the projection
    4560                 :  * centerline.
    4561                 :  * @param dfRectToSkew ?.
    4562                 :  * @param dfScale Scale factor applies to the projection origin.
    4563                 :  * @param dfFalseEasting False easting.
    4564                 :  * @param dfFalseNorthing False northing.
    4565                 :  *
    4566                 :  * @return OGRERR_NONE on success.
    4567                 :  */ 
    4568                 : 
    4569              60 : OGRErr OGRSpatialReference::SetHOMAC( double dfCenterLat, double dfCenterLong,
    4570                 :                                       double dfAzimuth, double dfRectToSkew,
    4571                 :                                       double dfScale,
    4572                 :                                       double dfFalseEasting,
    4573                 :                                       double dfFalseNorthing )
    4574                 : 
    4575                 : {
    4576              60 :     SetProjection( SRS_PT_HOTINE_OBLIQUE_MERCATOR_AZIMUTH_CENTER );
    4577              60 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    4578              60 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    4579              60 :     SetNormProjParm( SRS_PP_AZIMUTH, dfAzimuth );
    4580              60 :     SetNormProjParm( SRS_PP_RECTIFIED_GRID_ANGLE, dfRectToSkew );
    4581              60 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    4582              60 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4583              60 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4584                 : 
    4585              60 :     return OGRERR_NONE;
    4586                 : }
    4587                 : 
    4588                 : /************************************************************************/
    4589                 : /*                            OSRSetHOMAC()                             */
    4590                 : /************************************************************************/
    4591                 : 
    4592                 : /**
    4593                 :  * \brief Set an Oblique Mercator projection using azimuth angle.
    4594                 :  *
    4595                 :  * This is the same as the C++ method OGRSpatialReference::SetHOMAC()
    4596                 :  */
    4597               0 : OGRErr OSRSetHOMAC( OGRSpatialReferenceH hSRS, 
    4598                 :                     double dfCenterLat, double dfCenterLong,
    4599                 :                     double dfAzimuth, double dfRectToSkew, 
    4600                 :                     double dfScale,
    4601                 :                     double dfFalseEasting,
    4602                 :                     double dfFalseNorthing )
    4603                 :     
    4604                 : {
    4605               0 :     VALIDATE_POINTER1( hSRS, "OSRSetHOMAC", CE_Failure );
    4606                 : 
    4607                 :     return ((OGRSpatialReference *) hSRS)->SetHOMAC( 
    4608                 :         dfCenterLat, dfCenterLong, 
    4609                 :         dfAzimuth, dfRectToSkew, 
    4610                 :         dfScale,
    4611               0 :         dfFalseEasting, dfFalseNorthing );
    4612                 : }
    4613                 : 
    4614                 : /************************************************************************/
    4615                 : /*                               SetHOM()                               */
    4616                 : /************************************************************************/
    4617                 : 
    4618                 : /**
    4619                 :  * \brief Set a Hotine Oblique Mercator projection using azimuth angle.
    4620                 :  *
    4621                 :  * This projection corresponds to EPSG projection method 9812, also 
    4622                 :  * sometimes known as hotine oblique mercator (variant A)..
    4623                 :  *
    4624                 :  * This method does the same thing as the C function OSRSetHOM().
    4625                 :  *
    4626                 :  * @param dfCenterLat Latitude of the projection origin.
    4627                 :  * @param dfCenterLong Longitude of the projection origin.
    4628                 :  * @param dfAzimuth Azimuth, measured clockwise from North, of the projection
    4629                 :  * centerline.
    4630                 :  * @param dfRectToSkew ?.
    4631                 :  * @param dfScale Scale factor applies to the projection origin.
    4632                 :  * @param dfFalseEasting False easting.
    4633                 :  * @param dfFalseNorthing False northing.
    4634                 :  *
    4635                 :  * @return OGRERR_NONE on success.
    4636                 :  */ 
    4637                 : 
    4638              52 : OGRErr OGRSpatialReference::SetHOM( double dfCenterLat, double dfCenterLong,
    4639                 :                                     double dfAzimuth, double dfRectToSkew,
    4640                 :                                     double dfScale,
    4641                 :                                     double dfFalseEasting,
    4642                 :                                     double dfFalseNorthing )
    4643                 : 
    4644                 : {
    4645              52 :     SetProjection( SRS_PT_HOTINE_OBLIQUE_MERCATOR );
    4646              52 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    4647              52 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    4648              52 :     SetNormProjParm( SRS_PP_AZIMUTH, dfAzimuth );
    4649              52 :     SetNormProjParm( SRS_PP_RECTIFIED_GRID_ANGLE, dfRectToSkew );
    4650              52 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    4651              52 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4652              52 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4653                 : 
    4654              52 :     return OGRERR_NONE;
    4655                 : }
    4656                 : 
    4657                 : /************************************************************************/
    4658                 : /*                             OSRSetHOM()                              */
    4659                 : /************************************************************************/
    4660                 : /**
    4661                 :  * \brief Set a Hotine Oblique Mercator projection using azimuth angle.
    4662                 :  *
    4663                 :  * This is the same as the C++ method OGRSpatialReference::SetHOM()
    4664                 :  */
    4665               0 : OGRErr OSRSetHOM( OGRSpatialReferenceH hSRS, 
    4666                 :                   double dfCenterLat, double dfCenterLong,
    4667                 :                   double dfAzimuth, double dfRectToSkew, 
    4668                 :                   double dfScale,
    4669                 :                   double dfFalseEasting,
    4670                 :                   double dfFalseNorthing )
    4671                 :     
    4672                 : {
    4673               0 :     VALIDATE_POINTER1( hSRS, "OSRSetHOM", CE_Failure );
    4674                 : 
    4675                 :     return ((OGRSpatialReference *) hSRS)->SetHOM( 
    4676                 :         dfCenterLat, dfCenterLong, 
    4677                 :         dfAzimuth, dfRectToSkew, 
    4678                 :         dfScale,
    4679               0 :         dfFalseEasting, dfFalseNorthing );
    4680                 : }
    4681                 : 
    4682                 : /************************************************************************/
    4683                 : /*                             SetHOM2PNO()                             */
    4684                 : /************************************************************************/
    4685                 : 
    4686                 : /**
    4687                 :  * \brief Set a Hotine Oblique Mercator projection using two points on projection
    4688                 :  * centerline.
    4689                 :  *
    4690                 :  * This method does the same thing as the C function OSRSetHOM2PNO().
    4691                 :  *
    4692                 :  * @param dfCenterLat Latitude of the projection origin.
    4693                 :  * @param dfLat1 Latitude of the first point on center line.
    4694                 :  * @param dfLong1 Longitude of the first point on center line.
    4695                 :  * @param dfLat2 Latitude of the second point on center line.
    4696                 :  * @param dfLong2 Longitude of the second point on center line.
    4697                 :  * @param dfScale Scale factor applies to the projection origin.
    4698                 :  * @param dfFalseEasting False easting.
    4699                 :  * @param dfFalseNorthing False northing.
    4700                 :  *
    4701                 :  * @return OGRERR_NONE on success.
    4702                 :  */ 
    4703                 : 
    4704               0 : OGRErr OGRSpatialReference::SetHOM2PNO( double dfCenterLat,
    4705                 :                                         double dfLat1, double dfLong1,
    4706                 :                                         double dfLat2, double dfLong2,
    4707                 :                                         double dfScale,
    4708                 :                                         double dfFalseEasting,
    4709                 :                                         double dfFalseNorthing )
    4710                 : 
    4711                 : {
    4712               0 :     SetProjection( SRS_PT_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN );
    4713               0 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    4714               0 :     SetNormProjParm( SRS_PP_LATITUDE_OF_POINT_1, dfLat1 );
    4715               0 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_POINT_1, dfLong1 );
    4716               0 :     SetNormProjParm( SRS_PP_LATITUDE_OF_POINT_2, dfLat2 );
    4717               0 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_POINT_2, dfLong2 );
    4718               0 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    4719               0 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4720               0 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4721                 : 
    4722               0 :     return OGRERR_NONE;
    4723                 : }
    4724                 : 
    4725                 : /************************************************************************/
    4726                 : /*                           OSRSetHOM2PNO()                            */
    4727                 : /************************************************************************/
    4728                 : /**
    4729                 :  * \brief  Set a Hotine Oblique Mercator projection using two points on projection
    4730                 :  *  centerline.
    4731                 :  *
    4732                 :  * This is the same as the C++ method OGRSpatialReference::SetHOM2PNO()
    4733                 :  */
    4734               0 : OGRErr OSRSetHOM2PNO( OGRSpatialReferenceH hSRS, 
    4735                 :                       double dfCenterLat,
    4736                 :                       double dfLat1, double dfLong1,
    4737                 :                       double dfLat2, double dfLong2,
    4738                 :                       double dfScale,
    4739                 :                       double dfFalseEasting, double dfFalseNorthing )
    4740                 :     
    4741                 : {
    4742               0 :     VALIDATE_POINTER1( hSRS, "OSRSetHOM2PNO", CE_Failure );
    4743                 : 
    4744                 :     return ((OGRSpatialReference *) hSRS)->SetHOM2PNO( 
    4745                 :         dfCenterLat,
    4746                 :         dfLat1, dfLong1,
    4747                 :         dfLat2, dfLong2,
    4748                 :         dfScale,
    4749               0 :         dfFalseEasting, dfFalseNorthing );
    4750                 : }
    4751                 : 
    4752                 : /************************************************************************/
    4753                 : /*                            SetIWMPolyconic()                         */
    4754                 : /************************************************************************/
    4755                 : 
    4756               1 : OGRErr OGRSpatialReference::SetIWMPolyconic(
    4757                 :                                 double dfLat1, double dfLat2,
    4758                 :                                 double dfCenterLong,
    4759                 :                                 double dfFalseEasting, double dfFalseNorthing )
    4760                 : 
    4761                 : {
    4762               1 :     SetProjection( SRS_PT_IMW_POLYCONIC );
    4763               1 :     SetNormProjParm( SRS_PP_LATITUDE_OF_1ST_POINT, dfLat1 );
    4764               1 :     SetNormProjParm( SRS_PP_LATITUDE_OF_2ND_POINT, dfLat2 );
    4765               1 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4766               1 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4767               1 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4768                 : 
    4769               1 :     return OGRERR_NONE;
    4770                 : }
    4771                 : 
    4772                 : /************************************************************************/
    4773                 : /*                          OSRSetIWMPolyconic()                        */
    4774                 : /************************************************************************/
    4775                 : 
    4776               0 : OGRErr OSRSetIWMPolyconic( OGRSpatialReferenceH hSRS, 
    4777                 :                            double dfLat1, double dfLat2,
    4778                 :                            double dfCenterLong,
    4779                 :                            double dfFalseEasting, double dfFalseNorthing )
    4780                 :     
    4781                 : {
    4782               0 :     VALIDATE_POINTER1( hSRS, "OSRSetIWMPolyconic", CE_Failure );
    4783                 : 
    4784                 :     return ((OGRSpatialReference *) hSRS)->SetIWMPolyconic( 
    4785                 :         dfLat1, dfLat2, dfCenterLong, 
    4786               0 :         dfFalseEasting, dfFalseNorthing );
    4787                 : }
    4788                 : 
    4789                 : /************************************************************************/
    4790                 : /*                             SetKrovak()                              */
    4791                 : /************************************************************************/
    4792                 : 
    4793             143 : OGRErr OGRSpatialReference::SetKrovak( double dfCenterLat, double dfCenterLong,
    4794                 :                                        double dfAzimuth, 
    4795                 :                                        double dfPseudoStdParallel1,
    4796                 :                                        double dfScale,
    4797                 :                                        double dfFalseEasting,
    4798                 :                                        double dfFalseNorthing )
    4799                 : 
    4800                 : {
    4801             143 :     SetProjection( SRS_PT_KROVAK );
    4802             143 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    4803             143 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    4804             143 :     SetNormProjParm( SRS_PP_AZIMUTH, dfAzimuth );
    4805             143 :     SetNormProjParm( SRS_PP_PSEUDO_STD_PARALLEL_1, dfPseudoStdParallel1 );
    4806             143 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    4807             143 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4808             143 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4809                 : 
    4810             143 :     return OGRERR_NONE;
    4811                 : }
    4812                 : 
    4813                 : /************************************************************************/
    4814                 : /*                            OSRSetKrovak()                            */
    4815                 : /************************************************************************/
    4816                 : 
    4817               0 : OGRErr OSRSetKrovak( OGRSpatialReferenceH hSRS, 
    4818                 :                      double dfCenterLat, double dfCenterLong,
    4819                 :                      double dfAzimuth, double dfPseudoStdParallel1,
    4820                 :                      double dfScale,
    4821                 :                      double dfFalseEasting,
    4822                 :                      double dfFalseNorthing )
    4823                 :     
    4824                 : {
    4825               0 :     VALIDATE_POINTER1( hSRS, "OSRSetKrovak", CE_Failure );
    4826                 : 
    4827                 :     return ((OGRSpatialReference *) hSRS)->SetKrovak( 
    4828                 :         dfCenterLat, dfCenterLong, 
    4829                 :         dfAzimuth, dfPseudoStdParallel1,
    4830                 :         dfScale,
    4831               0 :         dfFalseEasting, dfFalseNorthing );
    4832                 : }
    4833                 : 
    4834                 : /************************************************************************/
    4835                 : /*                              SetLAEA()                               */
    4836                 : /************************************************************************/
    4837                 : 
    4838              82 : OGRErr OGRSpatialReference::SetLAEA( double dfCenterLat, double dfCenterLong,
    4839                 :                                    double dfFalseEasting,
    4840                 :                                    double dfFalseNorthing )
    4841                 : 
    4842                 : {
    4843              82 :     SetProjection( SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA );
    4844              82 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    4845              82 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    4846              82 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4847              82 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4848                 : 
    4849              82 :     return OGRERR_NONE;
    4850                 : }
    4851                 : 
    4852                 : /************************************************************************/
    4853                 : /*                             OSRSetLAEA()                             */
    4854                 : /************************************************************************/
    4855                 : 
    4856               0 : OGRErr OSRSetLAEA( OGRSpatialReferenceH hSRS, 
    4857                 :                    double dfCenterLat, double dfCenterLong,
    4858                 :                    double dfFalseEasting, double dfFalseNorthing )
    4859                 :     
    4860                 : {
    4861               0 :     VALIDATE_POINTER1( hSRS, "OSRSetLAEA", CE_Failure );
    4862                 : 
    4863                 :     return ((OGRSpatialReference *) hSRS)->SetLAEA( 
    4864                 :         dfCenterLat, dfCenterLong, 
    4865               0 :         dfFalseEasting, dfFalseNorthing );
    4866                 : }
    4867                 : 
    4868                 : /************************************************************************/
    4869                 : /*                               SetLCC()                               */
    4870                 : /************************************************************************/
    4871                 : 
    4872            2724 : OGRErr OGRSpatialReference::SetLCC( double dfStdP1, double dfStdP2,
    4873                 :                                     double dfCenterLat, double dfCenterLong,
    4874                 :                                     double dfFalseEasting,
    4875                 :                                     double dfFalseNorthing )
    4876                 : 
    4877                 : {
    4878            2724 :     SetProjection( SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP );
    4879            2724 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
    4880            2724 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
    4881            2724 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4882            2724 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4883            2724 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4884            2724 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4885                 : 
    4886            2724 :     return OGRERR_NONE;
    4887                 : }
    4888                 : 
    4889                 : /************************************************************************/
    4890                 : /*                             OSRSetLCC()                              */
    4891                 : /************************************************************************/
    4892                 : 
    4893               2 : OGRErr OSRSetLCC( OGRSpatialReferenceH hSRS, 
    4894                 :                   double dfStdP1, double dfStdP2, 
    4895                 :                   double dfCenterLat, double dfCenterLong,
    4896                 :                   double dfFalseEasting, double dfFalseNorthing )
    4897                 :     
    4898                 : {
    4899               2 :     VALIDATE_POINTER1( hSRS, "OSRSetLCC", CE_Failure );
    4900                 : 
    4901                 :     return ((OGRSpatialReference *) hSRS)->SetLCC( 
    4902                 :         dfStdP1, dfStdP2, 
    4903                 :         dfCenterLat, dfCenterLong, 
    4904               2 :         dfFalseEasting, dfFalseNorthing );
    4905                 : }
    4906                 : 
    4907                 : /************************************************************************/
    4908                 : /*                             SetLCC1SP()                              */
    4909                 : /************************************************************************/
    4910                 : 
    4911             320 : OGRErr OGRSpatialReference::SetLCC1SP( double dfCenterLat, double dfCenterLong,
    4912                 :                                        double dfScale,
    4913                 :                                        double dfFalseEasting,
    4914                 :                                        double dfFalseNorthing )
    4915                 : 
    4916                 : {
    4917             320 :     SetProjection( SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP );
    4918             320 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4919             320 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4920             320 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    4921             320 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4922             320 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4923                 : 
    4924             320 :     return OGRERR_NONE;
    4925                 : }
    4926                 : 
    4927                 : /************************************************************************/
    4928                 : /*                            OSRSetLCC1SP()                            */
    4929                 : /************************************************************************/
    4930                 : 
    4931               0 : OGRErr OSRSetLCC1SP( OGRSpatialReferenceH hSRS, 
    4932                 :                      double dfCenterLat, double dfCenterLong,
    4933                 :                      double dfScale,
    4934                 :                      double dfFalseEasting, double dfFalseNorthing )
    4935                 :     
    4936                 : {
    4937               0 :     VALIDATE_POINTER1( hSRS, "OSRSetLCC1SP", CE_Failure );
    4938                 : 
    4939                 :     return ((OGRSpatialReference *) hSRS)->SetLCC1SP( 
    4940                 :         dfCenterLat, dfCenterLong, 
    4941                 :         dfScale,
    4942               0 :         dfFalseEasting, dfFalseNorthing );
    4943                 : }
    4944                 : 
    4945                 : /************************************************************************/
    4946                 : /*                              SetLCCB()                               */
    4947                 : /************************************************************************/
    4948                 : 
    4949               4 : OGRErr OGRSpatialReference::SetLCCB( double dfStdP1, double dfStdP2,
    4950                 :                                      double dfCenterLat, double dfCenterLong,
    4951                 :                                      double dfFalseEasting,
    4952                 :                                      double dfFalseNorthing )
    4953                 : 
    4954                 : {
    4955               4 :     SetProjection( SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM );
    4956               4 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
    4957               4 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
    4958               4 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4959               4 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4960               4 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4961               4 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4962                 : 
    4963               4 :     return OGRERR_NONE;
    4964                 : }
    4965                 : 
    4966                 : /************************************************************************/
    4967                 : /*                             OSRSetLCCB()                             */
    4968                 : /************************************************************************/
    4969                 : 
    4970               0 : OGRErr OSRSetLCCB( OGRSpatialReferenceH hSRS, 
    4971                 :                    double dfStdP1, double dfStdP2, 
    4972                 :                    double dfCenterLat, double dfCenterLong,
    4973                 :                    double dfFalseEasting, double dfFalseNorthing )
    4974                 :     
    4975                 : {
    4976               0 :     VALIDATE_POINTER1( hSRS, "OSRSetLCCB", CE_Failure );
    4977                 : 
    4978                 :     return ((OGRSpatialReference *) hSRS)->SetLCCB( 
    4979                 :         dfStdP1, dfStdP2, 
    4980                 :         dfCenterLat, dfCenterLong, 
    4981               0 :         dfFalseEasting, dfFalseNorthing );
    4982                 : }
    4983                 : 
    4984                 : /************************************************************************/
    4985                 : /*                               SetMC()                                */
    4986                 : /************************************************************************/
    4987                 : 
    4988               2 : OGRErr OGRSpatialReference::SetMC( double dfCenterLat, double dfCenterLong,
    4989                 :                                    double dfFalseEasting,
    4990                 :                                    double dfFalseNorthing )
    4991                 : 
    4992                 : {
    4993               2 :     SetProjection( SRS_PT_MILLER_CYLINDRICAL );
    4994               2 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    4995               2 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    4996               2 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4997               2 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4998                 : 
    4999               2 :     return OGRERR_NONE;
    5000                 : }
    5001                 : 
    5002                 : /************************************************************************/
    5003                 : /*                              OSRSetMC()                              */
    5004                 : /************************************************************************/
    5005                 : 
    5006               0 : OGRErr OSRSetMC( OGRSpatialReferenceH hSRS, 
    5007                 :                  double dfCenterLat, double dfCenterLong,
    5008                 :                  double dfFalseEasting, double dfFalseNorthing )
    5009                 :     
    5010                 : {
    5011               0 :     VALIDATE_POINTER1( hSRS, "OSRSetMC", CE_Failure );
    5012                 : 
    5013                 :     return ((OGRSpatialReference *) hSRS)->SetMC( 
    5014                 :         dfCenterLat, dfCenterLong, 
    5015               0 :         dfFalseEasting, dfFalseNorthing );
    5016                 : }
    5017                 : 
    5018                 : /************************************************************************/
    5019                 : /*                            SetMercator()                             */
    5020                 : /************************************************************************/
    5021                 : 
    5022             152 : OGRErr OGRSpatialReference::SetMercator( double dfCenterLat, double dfCenterLong,
    5023                 :                                          double dfScale,
    5024                 :                                          double dfFalseEasting,
    5025                 :                                          double dfFalseNorthing )
    5026                 : 
    5027                 : {
    5028             152 :     SetProjection( SRS_PT_MERCATOR_1SP );
    5029                 : 
    5030             152 :     if( dfCenterLat != 0.0 )
    5031               6 :         SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    5032                 : 
    5033             152 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    5034             152 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    5035             152 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5036             152 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5037                 : 
    5038             152 :     return OGRERR_NONE;
    5039                 : }
    5040                 : 
    5041                 : /************************************************************************/
    5042                 : /*                           OSRSetMercator()                           */
    5043                 : /************************************************************************/
    5044                 : 
    5045               0 : OGRErr OSRSetMercator( OGRSpatialReferenceH hSRS, 
    5046                 :                        double dfCenterLat, double dfCenterLong,
    5047                 :                        double dfScale,
    5048                 :                        double dfFalseEasting, double dfFalseNorthing )
    5049                 :     
    5050                 : {
    5051               0 :     VALIDATE_POINTER1( hSRS, "OSRSetMercator", CE_Failure );
    5052                 : 
    5053                 :     return ((OGRSpatialReference *) hSRS)->SetMercator( 
    5054                 :         dfCenterLat, dfCenterLong, 
    5055                 :         dfScale,
    5056               0 :         dfFalseEasting, dfFalseNorthing );
    5057                 : }
    5058                 : 
    5059                 : /************************************************************************/
    5060                 : /*                           SetMercator2SP()                           */
    5061                 : /************************************************************************/
    5062                 : 
    5063              21 : OGRErr OGRSpatialReference::SetMercator2SP( 
    5064                 :     double dfStdP1, 
    5065                 :     double dfCenterLat, double dfCenterLong,
    5066                 :     double dfFalseEasting,
    5067                 :     double dfFalseNorthing )
    5068                 : 
    5069                 : {
    5070              21 :     SetProjection( SRS_PT_MERCATOR_2SP );
    5071                 : 
    5072              21 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
    5073              21 :     if( dfCenterLat != 0.0 )
    5074               0 :         SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    5075                 : 
    5076              21 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    5077              21 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5078              21 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5079                 : 
    5080              21 :     return OGRERR_NONE;
    5081                 : }
    5082                 : 
    5083                 : /************************************************************************/
    5084                 : /*                         OSRSetMercator2SP()                          */
    5085                 : /************************************************************************/
    5086                 : 
    5087               0 : OGRErr OSRSetMercator2SP( OGRSpatialReferenceH hSRS, 
    5088                 :                           double dfStdP1,
    5089                 :                           double dfCenterLat, double dfCenterLong,
    5090                 :                           double dfFalseEasting, double dfFalseNorthing )
    5091                 :     
    5092                 : {
    5093               0 :     VALIDATE_POINTER1( hSRS, "OSRSetMercator2SP", CE_Failure );
    5094                 : 
    5095                 :     return ((OGRSpatialReference *) hSRS)->SetMercator2SP( 
    5096                 :         dfStdP1, 
    5097                 :         dfCenterLat, dfCenterLong, 
    5098               0 :         dfFalseEasting, dfFalseNorthing );
    5099                 : }
    5100                 : 
    5101                 : /************************************************************************/
    5102                 : /*                            SetMollweide()                            */
    5103                 : /************************************************************************/
    5104                 : 
    5105               1 : OGRErr OGRSpatialReference::SetMollweide( double dfCentralMeridian,
    5106                 :                                           double dfFalseEasting,
    5107                 :                                           double dfFalseNorthing )
    5108                 : 
    5109                 : {
    5110               1 :     SetProjection( SRS_PT_MOLLWEIDE );
    5111               1 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    5112               1 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5113               1 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5114                 : 
    5115               1 :     return OGRERR_NONE;
    5116                 : }
    5117                 : 
    5118                 : /************************************************************************/
    5119                 : /*                          OSRSetMollweide()                           */
    5120                 : /************************************************************************/
    5121                 : 
    5122               0 : OGRErr OSRSetMollweide( OGRSpatialReferenceH hSRS, 
    5123                 :                         double dfCentralMeridian,
    5124                 :                         double dfFalseEasting, double dfFalseNorthing )
    5125                 :     
    5126                 : {
    5127               0 :     VALIDATE_POINTER1( hSRS, "OSRSetMollweide", CE_Failure );
    5128                 : 
    5129                 :     return ((OGRSpatialReference *) hSRS)->SetMollweide( 
    5130                 :         dfCentralMeridian,
    5131               0 :         dfFalseEasting, dfFalseNorthing );
    5132                 : }
    5133                 : 
    5134                 : /************************************************************************/
    5135                 : /*                              SetNZMG()                               */
    5136                 : /************************************************************************/
    5137                 : 
    5138              11 : OGRErr OGRSpatialReference::SetNZMG( double dfCenterLat, double dfCenterLong,
    5139                 :                                      double dfFalseEasting,
    5140                 :                                      double dfFalseNorthing )
    5141                 : 
    5142                 : {
    5143              11 :     SetProjection( SRS_PT_NEW_ZEALAND_MAP_GRID );
    5144              11 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    5145              11 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    5146              11 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5147              11 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5148                 : 
    5149              11 :     return OGRERR_NONE;
    5150                 : }
    5151                 : 
    5152                 : /************************************************************************/
    5153                 : /*                             OSRSetNZMG()                             */
    5154                 : /************************************************************************/
    5155                 : 
    5156               0 : OGRErr OSRSetNZMG( OGRSpatialReferenceH hSRS, 
    5157                 :                    double dfCenterLat, double dfCenterLong,
    5158                 :                    double dfFalseEasting, double dfFalseNorthing )
    5159                 :     
    5160                 : {
    5161               0 :     VALIDATE_POINTER1( hSRS, "OSRSetNZMG", CE_Failure );
    5162                 : 
    5163                 :     return ((OGRSpatialReference *) hSRS)->SetNZMG( 
    5164                 :         dfCenterLat, dfCenterLong, 
    5165               0 :         dfFalseEasting, dfFalseNorthing );
    5166                 : }
    5167                 : 
    5168                 : /************************************************************************/
    5169                 : /*                               SetOS()                                */
    5170                 : /************************************************************************/
    5171                 : 
    5172             101 : OGRErr OGRSpatialReference::SetOS( double dfOriginLat, double dfCMeridian,
    5173                 :                                    double dfScale,
    5174                 :                                    double dfFalseEasting,
    5175                 :                                    double dfFalseNorthing )
    5176                 : 
    5177                 : {
    5178             101 :     SetProjection( SRS_PT_OBLIQUE_STEREOGRAPHIC );
    5179             101 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfOriginLat );
    5180             101 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCMeridian );
    5181             101 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    5182             101 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5183             101 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5184                 : 
    5185             101 :     return OGRERR_NONE;
    5186                 : }
    5187                 : 
    5188                 : /************************************************************************/
    5189                 : /*                              OSRSetOS()                              */
    5190                 : /************************************************************************/
    5191                 : 
    5192               0 : OGRErr OSRSetOS( OGRSpatialReferenceH hSRS, 
    5193                 :                  double dfOriginLat, double dfCMeridian,
    5194                 :                  double dfScale,
    5195                 :                  double dfFalseEasting, double dfFalseNorthing )
    5196                 :     
    5197                 : {
    5198               0 :     VALIDATE_POINTER1( hSRS, "OSRSetOS", CE_Failure );
    5199                 : 
    5200                 :     return ((OGRSpatialReference *) hSRS)->SetOS( 
    5201                 :         dfOriginLat, dfCMeridian,
    5202                 :         dfScale,
    5203               0 :         dfFalseEasting, dfFalseNorthing );
    5204                 : }
    5205                 : 
    5206                 : /************************************************************************/
    5207                 : /*                          SetOrthographic()                           */
    5208                 : /************************************************************************/
    5209                 : 
    5210              12 : OGRErr OGRSpatialReference::SetOrthographic(
    5211                 :                                 double dfCenterLat, double dfCenterLong,
    5212                 :                                 double dfFalseEasting, double dfFalseNorthing )
    5213                 : 
    5214                 : {
    5215              12 :     SetProjection( SRS_PT_ORTHOGRAPHIC );
    5216              12 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    5217              12 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    5218              12 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5219              12 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5220                 : 
    5221              12 :     return OGRERR_NONE;
    5222                 : }
    5223                 : 
    5224                 : /************************************************************************/
    5225                 : /*                         OSRSetOrthographic()                         */
    5226                 : /************************************************************************/
    5227                 : 
    5228               0 : OGRErr OSRSetOrthographic( OGRSpatialReferenceH hSRS, 
    5229                 :                            double dfCenterLat, double dfCenterLong,
    5230                 :                            double dfFalseEasting, double dfFalseNorthing )
    5231                 :     
    5232                 : {
    5233               0 :     VALIDATE_POINTER1( hSRS, "OSRSetOrthographic", CE_Failure );
    5234                 : 
    5235                 :     return ((OGRSpatialReference *) hSRS)->SetOrthographic( 
    5236                 :         dfCenterLat, dfCenterLong, 
    5237               0 :         dfFalseEasting, dfFalseNorthing );
    5238                 : }
    5239                 : 
    5240                 : /************************************************************************/
    5241                 : /*                            SetPolyconic()                            */
    5242                 : /************************************************************************/
    5243                 : 
    5244              22 : OGRErr OGRSpatialReference::SetPolyconic(
    5245                 :                                 double dfCenterLat, double dfCenterLong,
    5246                 :                                 double dfFalseEasting, double dfFalseNorthing )
    5247                 : 
    5248                 : {
    5249                 :     // note: it seems that by some definitions this should include a
    5250                 :     //       scale_factor parameter.
    5251                 :     
    5252              22 :     SetProjection( SRS_PT_POLYCONIC );
    5253              22 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    5254              22 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    5255              22 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5256              22 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5257                 : 
    5258              22 :     return OGRERR_NONE;
    5259                 : }
    5260                 : 
    5261                 : /************************************************************************/
    5262                 : /*                          OSRSetPolyconic()                           */
    5263                 : /************************************************************************/
    5264                 : 
    5265               0 : OGRErr OSRSetPolyconic( OGRSpatialReferenceH hSRS, 
    5266                 :                         double dfCenterLat, double dfCenterLong,
    5267                 :                         double dfFalseEasting, double dfFalseNorthing )
    5268                 :     
    5269                 : {
    5270               0 :     VALIDATE_POINTER1( hSRS, "OSRSetPolyconic", CE_Failure );
    5271                 : 
    5272                 :     return ((OGRSpatialReference *) hSRS)->SetPolyconic( 
    5273                 :         dfCenterLat, dfCenterLong, 
    5274               0 :         dfFalseEasting, dfFalseNorthing );
    5275                 : }
    5276                 : 
    5277                 : /************************************************************************/
    5278                 : /*                               SetPS()                                */
    5279                 : /************************************************************************/
    5280                 : 
    5281             155 : OGRErr OGRSpatialReference::SetPS(
    5282                 :                                 double dfCenterLat, double dfCenterLong,
    5283                 :                                 double dfScale,
    5284                 :                                 double dfFalseEasting, double dfFalseNorthing )
    5285                 : 
    5286                 : {
    5287             155 :     SetProjection( SRS_PT_POLAR_STEREOGRAPHIC );
    5288             155 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    5289             155 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    5290             155 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    5291             155 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5292             155 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5293                 : 
    5294             155 :     return OGRERR_NONE;
    5295                 : }
    5296                 : 
    5297                 : /************************************************************************/
    5298                 : /*                              OSRSetPS()                              */
    5299                 : /************************************************************************/
    5300                 : 
    5301               0 : OGRErr OSRSetPS( OGRSpatialReferenceH hSRS, 
    5302                 :                  double dfCenterLat, double dfCenterLong,
    5303                 :                  double dfScale,
    5304                 :                  double dfFalseEasting, double dfFalseNorthing )
    5305                 :     
    5306                 : {
    5307               0 :     VALIDATE_POINTER1( hSRS, "OSRSetPS", CE_Failure );
    5308                 : 
    5309                 :     return ((OGRSpatialReference *) hSRS)->SetPS( 
    5310                 :         dfCenterLat, dfCenterLong, 
    5311                 :         dfScale,
    5312               0 :         dfFalseEasting, dfFalseNorthing );
    5313                 : }
    5314                 : 
    5315                 : /************************************************************************/
    5316                 : /*                            SetRobinson()                             */
    5317                 : /************************************************************************/
    5318                 : 
    5319               1 : OGRErr OGRSpatialReference::SetRobinson( double dfCenterLong,
    5320                 :                                          double dfFalseEasting,
    5321                 :                                          double dfFalseNorthing )
    5322                 : 
    5323                 : {
    5324               1 :     SetProjection( SRS_PT_ROBINSON );
    5325               1 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    5326               1 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5327               1 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5328                 : 
    5329               1 :     return OGRERR_NONE;
    5330                 : }
    5331                 : 
    5332                 : /************************************************************************/
    5333                 : /*                           OSRSetRobinson()                           */
    5334                 : /************************************************************************/
    5335                 : 
    5336               0 : OGRErr OSRSetRobinson( OGRSpatialReferenceH hSRS, 
    5337                 :                         double dfCenterLong,
    5338                 :                         double dfFalseEasting, double dfFalseNorthing )
    5339                 :     
    5340                 : {
    5341               0 :     VALIDATE_POINTER1( hSRS, "OSRSetRobinson", CE_Failure );
    5342                 : 
    5343                 :     return ((OGRSpatialReference *) hSRS)->SetRobinson( 
    5344                 :         dfCenterLong, 
    5345               0 :         dfFalseEasting, dfFalseNorthing );
    5346                 : }
    5347                 : 
    5348                 : /************************************************************************/
    5349                 : /*                           SetSinusoidal()                            */
    5350                 : /************************************************************************/
    5351                 : 
    5352              12 : OGRErr OGRSpatialReference::SetSinusoidal( double dfCenterLong,
    5353                 :                                            double dfFalseEasting,
    5354                 :                                            double dfFalseNorthing )
    5355                 : 
    5356                 : {
    5357              12 :     SetProjection( SRS_PT_SINUSOIDAL );
    5358              12 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    5359              12 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5360              12 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5361                 : 
    5362              12 :     return OGRERR_NONE;
    5363                 : }
    5364                 : 
    5365                 : /************************************************************************/
    5366                 : /*                          OSRSetSinusoidal()                          */
    5367                 : /************************************************************************/
    5368                 : 
    5369               0 : OGRErr OSRSetSinusoidal( OGRSpatialReferenceH hSRS, 
    5370                 :                          double dfCenterLong,
    5371                 :                          double dfFalseEasting, double dfFalseNorthing )
    5372                 :     
    5373                 : {
    5374               0 :     VALIDATE_POINTER1( hSRS, "OSRSetSinusoidal", CE_Failure );
    5375                 : 
    5376                 :     return ((OGRSpatialReference *) hSRS)->SetSinusoidal( 
    5377                 :         dfCenterLong, 
    5378               0 :         dfFalseEasting, dfFalseNorthing );
    5379                 : }
    5380                 : 
    5381                 : /************************************************************************/
    5382                 : /*                          SetStereographic()                          */
    5383                 : /************************************************************************/
    5384                 : 
    5385              11 : OGRErr OGRSpatialReference::SetStereographic(
    5386                 :                             double dfOriginLat, double dfCMeridian,
    5387                 :                             double dfScale,
    5388                 :                             double dfFalseEasting,
    5389                 :                             double dfFalseNorthing )
    5390                 : 
    5391                 : {
    5392              11 :     SetProjection( SRS_PT_STEREOGRAPHIC );
    5393              11 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfOriginLat );
    5394              11 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCMeridian );
    5395              11 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    5396              11 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5397              11 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5398                 : 
    5399              11 :     return OGRERR_NONE;
    5400                 : }
    5401                 : 
    5402                 : /************************************************************************/
    5403                 : /*                        OSRSetStereographic()                         */
    5404                 : /************************************************************************/
    5405                 : 
    5406               0 : OGRErr OSRSetStereographic( OGRSpatialReferenceH hSRS, 
    5407                 :                             double dfOriginLat, double dfCMeridian,
    5408                 :                             double dfScale,
    5409                 :                             double dfFalseEasting, double dfFalseNorthing )
    5410                 :     
    5411                 : {
    5412               0 :     VALIDATE_POINTER1( hSRS, "OSRSetStereographic", CE_Failure );
    5413                 : 
    5414                 :     return ((OGRSpatialReference *) hSRS)->SetStereographic( 
    5415                 :         dfOriginLat, dfCMeridian,
    5416                 :         dfScale,
    5417               0 :         dfFalseEasting, dfFalseNorthing );
    5418                 : }
    5419                 : 
    5420                 : /************************************************************************/
    5421                 : /*                               SetSOC()                               */
    5422                 : /*                                                                      */
    5423                 : /*      NOTE: This definition isn't really used in practice any more    */
    5424                 : /*      and should be considered deprecated.  It seems that swiss       */
    5425                 : /*      oblique mercator is now define as Hotine_Oblique_Mercator       */
    5426                 : /*      with an azimuth of 90 and a rectified_grid_angle of 90.  See    */
    5427                 : /*      EPSG:2056 and Bug 423.                                          */
    5428                 : /************************************************************************/
    5429                 : 
    5430               0 : OGRErr OGRSpatialReference::SetSOC( double dfLatitudeOfOrigin, 
    5431                 :                                     double dfCentralMeridian,
    5432                 :                                     double dfFalseEasting,
    5433                 :                                     double dfFalseNorthing )
    5434                 : 
    5435                 : {
    5436               0 :     SetProjection( SRS_PT_SWISS_OBLIQUE_CYLINDRICAL );
    5437               0 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfLatitudeOfOrigin );
    5438               0 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    5439               0 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5440               0 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5441                 : 
    5442               0 :     return OGRERR_NONE;
    5443                 : }
    5444                 : 
    5445                 : /************************************************************************/
    5446                 : /*                             OSRSetSOC()                              */
    5447                 : /************************************************************************/
    5448                 : 
    5449               0 : OGRErr OSRSetSOC( OGRSpatialReferenceH hSRS, 
    5450                 :                   double dfLatitudeOfOrigin, double dfCentralMeridian,
    5451                 :                   double dfFalseEasting, double dfFalseNorthing )
    5452                 :     
    5453                 : {
    5454               0 :     VALIDATE_POINTER1( hSRS, "OSRSetSOC", CE_Failure );
    5455                 : 
    5456                 :     return ((OGRSpatialReference *) hSRS)->SetSOC( 
    5457                 :         dfLatitudeOfOrigin, dfCentralMeridian,
    5458               0 :         dfFalseEasting, dfFalseNorthing );
    5459                 : }
    5460                 : 
    5461                 : /************************************************************************/
    5462                 : /*                               SetVDG()                               */
    5463                 : /************************************************************************/
    5464                 : 
    5465               6 : OGRErr OGRSpatialReference::SetVDG( double dfCMeridian,
    5466                 :                                     double dfFalseEasting,
    5467                 :                                     double dfFalseNorthing )
    5468                 : 
    5469                 : {
    5470               6 :     SetProjection( SRS_PT_VANDERGRINTEN );
    5471               6 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCMeridian );
    5472               6 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5473               6 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5474                 : 
    5475               6 :     return OGRERR_NONE;
    5476                 : }
    5477                 : 
    5478                 : /************************************************************************/
    5479                 : /*                             OSRSetVDG()                              */
    5480                 : /************************************************************************/
    5481                 : 
    5482               0 : OGRErr OSRSetVDG( OGRSpatialReferenceH hSRS, 
    5483                 :                   double dfCentralMeridian,
    5484                 :                   double dfFalseEasting, double dfFalseNorthing )
    5485                 :     
    5486                 : {
    5487               0 :     VALIDATE_POINTER1( hSRS, "OSRSetVDG", CE_Failure );
    5488                 : 
    5489                 :     return ((OGRSpatialReference *) hSRS)->SetVDG( 
    5490                 :         dfCentralMeridian,
    5491               0 :         dfFalseEasting, dfFalseNorthing );
    5492                 : }
    5493                 : 
    5494                 : /************************************************************************/
    5495                 : /*                               SetUTM()                               */
    5496                 : /************************************************************************/
    5497                 : 
    5498                 : /**
    5499                 :  * \brief Set UTM projection definition.
    5500                 :  *
    5501                 :  * This will generate a projection definition with the full set of 
    5502                 :  * transverse mercator projection parameters for the given UTM zone.
    5503                 :  * If no PROJCS[] description is set yet, one will be set to look
    5504                 :  * like "UTM Zone %d, {Northern, Southern} Hemisphere". 
    5505                 :  *
    5506                 :  * This method is the same as the C function OSRSetUTM().
    5507                 :  *
    5508                 :  * @param nZone UTM zone.
    5509                 :  *
    5510                 :  * @param bNorth TRUE for northern hemisphere, or FALSE for southern 
    5511                 :  * hemisphere. 
    5512                 :  * 
    5513                 :  * @return OGRERR_NONE on success. 
    5514                 :  */
    5515                 : 
    5516             185 : OGRErr OGRSpatialReference::SetUTM( int nZone, int bNorth )
    5517                 : 
    5518                 : {
    5519             185 :     SetProjection( SRS_PT_TRANSVERSE_MERCATOR );
    5520             185 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0 );
    5521             185 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, nZone * 6 - 183 );
    5522             185 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, 0.9996 );
    5523             185 :     SetNormProjParm( SRS_PP_FALSE_EASTING, 500000.0 );
    5524                 : 
    5525             185 :     if( bNorth )
    5526             152 :         SetNormProjParm( SRS_PP_FALSE_NORTHING, 0 );
    5527                 :     else
    5528              33 :         SetNormProjParm( SRS_PP_FALSE_NORTHING, 10000000 );
    5529                 : 
    5530             185 :     if( EQUAL(GetAttrValue("PROJCS"),"unnamed") )
    5531                 :     {
    5532                 :         char    szUTMName[128];
    5533                 : 
    5534             179 :         if( bNorth )
    5535             147 :             sprintf( szUTMName, "UTM Zone %d, Northern Hemisphere", nZone );
    5536                 :         else
    5537              32 :             sprintf( szUTMName, "UTM Zone %d, Southern Hemisphere", nZone );
    5538                 : 
    5539             179 :         SetNode( "PROJCS", szUTMName );
    5540                 :     }
    5541                 : 
    5542             185 :     SetLinearUnits( SRS_UL_METER, 1.0 );
    5543                 : 
    5544             185 :     return OGRERR_NONE;
    5545                 : }
    5546                 : 
    5547                 : /************************************************************************/
    5548                 : /*                             OSRSetUTM()                              */
    5549                 : /************************************************************************/
    5550                 : 
    5551                 : /**
    5552                 :  * \brief Set UTM projection definition.
    5553                 :  *
    5554                 :  * This is the same as the C++ method OGRSpatialReference::SetUTM()
    5555                 :  */
    5556              12 : OGRErr OSRSetUTM( OGRSpatialReferenceH hSRS, int nZone, int bNorth )
    5557                 : 
    5558                 : {
    5559              12 :     VALIDATE_POINTER1( hSRS, "OSRSetUTM", CE_Failure );
    5560                 : 
    5561              12 :     return ((OGRSpatialReference *) hSRS)->SetUTM( nZone, bNorth );
    5562                 : }
    5563                 : 
    5564                 : /************************************************************************/
    5565                 : /*                             GetUTMZone()                             */
    5566                 : /*                                                                      */
    5567                 : /*      Returns zero if it isn't UTM.                                   */
    5568                 : /************************************************************************/
    5569                 : 
    5570                 : /**
    5571                 :  * \brief Get utm zone information.
    5572                 :  *
    5573                 :  * This is the same as the C function OSRGetUTMZone().
    5574                 :  *
    5575                 :  * In SWIG bindings (Python, Java, etc) the GetUTMZone() method returns a 
    5576                 :  * zone which is negative in the southern hemisphere instead of having the 
    5577                 :  * pbNorth flag used in the C and C++ interface.
    5578                 :  *
    5579                 :  * @param pbNorth pointer to in to set to TRUE if northern hemisphere, or
    5580                 :  * FALSE if southern. 
    5581                 :  * 
    5582                 :  * @return UTM zone number or zero if this isn't a UTM definition. 
    5583                 :  */
    5584                 : 
    5585           15608 : int OGRSpatialReference::GetUTMZone( int * pbNorth ) const
    5586                 : 
    5587                 : {
    5588           15608 :     const char  *pszProjection = GetAttrValue( "PROJECTION" );
    5589                 : 
    5590           15608 :     if( pszProjection == NULL
    5591                 :         || !EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR) )
    5592            6258 :         return 0;
    5593                 : 
    5594            9350 :     if( GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) != 0.0 )
    5595            2270 :         return 0;
    5596                 : 
    5597            7080 :     if( GetProjParm( SRS_PP_SCALE_FACTOR, 1.0 ) != 0.9996 )
    5598            3232 :         return 0;
    5599                 :           
    5600            3848 :     if( fabs(GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 )-500000.0) > 0.001 )
    5601             160 :         return 0;
    5602                 : 
    5603            3688 :     double      dfFalseNorthing = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0);
    5604                 : 
    5605            3688 :     if( dfFalseNorthing != 0.0 
    5606                 :         && fabs(dfFalseNorthing-10000000.0) > 0.001 )
    5607               8 :         return 0;
    5608                 : 
    5609            3680 :     if( pbNorth != NULL )
    5610            3639 :         *pbNorth = (dfFalseNorthing == 0);
    5611                 : 
    5612                 :     double      dfCentralMeridian = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 
    5613            3680 :                                                      0.0);
    5614            3680 :     double      dfZone = ( dfCentralMeridian + 186.0 ) / 6.0;
    5615                 : 
    5616            3680 :     if( ABS(dfZone - (int) dfZone - 0.5 ) > 0.00001
    5617                 :         || dfCentralMeridian < -177.00001
    5618                 :         || dfCentralMeridian > 177.000001 )
    5619              78 :         return 0;
    5620                 :     else
    5621            3602 :         return (int) dfZone;
    5622                 : }
    5623                 : 
    5624                 : /************************************************************************/
    5625                 : /*                           OSRGetUTMZone()                            */
    5626                 : /************************************************************************/
    5627                 : 
    5628                 : /**
    5629                 :  * \brief Get utm zone information.
    5630                 :  *
    5631                 :  * This is the same as the C++ method OGRSpatialReference::GetUTMZone()
    5632                 :  */
    5633               2 : int OSRGetUTMZone( OGRSpatialReferenceH hSRS, int *pbNorth )
    5634                 : 
    5635                 : {
    5636               2 :     VALIDATE_POINTER1( hSRS, "OSRGetUTMZone", 0 );
    5637                 : 
    5638               2 :     return ((OGRSpatialReference *) hSRS)->GetUTMZone( pbNorth );
    5639                 : }
    5640                 : 
    5641                 : /************************************************************************/
    5642                 : /*                             SetWagner()                              */
    5643                 : /************************************************************************/
    5644                 : 
    5645               7 : OGRErr OGRSpatialReference::SetWagner( int nVariation /* 1 -- 7 */,
    5646                 :                                        double dfCenterLat,
    5647                 :                                        double dfFalseEasting,
    5648                 :                                        double dfFalseNorthing )
    5649                 : 
    5650                 : {
    5651               7 :     if( nVariation == 1 )
    5652               1 :         SetProjection( SRS_PT_WAGNER_I );
    5653               6 :     else if( nVariation == 2 )
    5654               1 :         SetProjection( SRS_PT_WAGNER_II );
    5655               5 :     else if( nVariation == 3 )
    5656                 :     {
    5657               1 :         SetProjection( SRS_PT_WAGNER_III );
    5658               1 :         SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    5659                 :     }
    5660               4 :     else if( nVariation == 4 )
    5661               1 :         SetProjection( SRS_PT_WAGNER_IV );
    5662               3 :     else if( nVariation == 5 )
    5663               1 :         SetProjection( SRS_PT_WAGNER_V );
    5664               2 :     else if( nVariation == 6 )
    5665               1 :         SetProjection( SRS_PT_WAGNER_VI );
    5666               1 :     else if( nVariation == 7 )
    5667               1 :         SetProjection( SRS_PT_WAGNER_VII );
    5668                 :     else
    5669                 :     {
    5670                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    5671               0 :                   "Unsupported Wagner variation (%d).", nVariation );
    5672               0 :         return OGRERR_UNSUPPORTED_SRS;
    5673                 :     }
    5674                 : 
    5675               7 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5676               7 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5677                 : 
    5678               7 :     return OGRERR_NONE;
    5679                 : }
    5680                 : 
    5681                 : /************************************************************************/
    5682                 : /*                            OSRSetWagner()                            */
    5683                 : /************************************************************************/
    5684                 : 
    5685               0 : OGRErr OSRSetWagner( OGRSpatialReferenceH hSRS, 
    5686                 :                      int nVariation, double dfCenterLat,
    5687                 :                      double dfFalseEasting,
    5688                 :                      double dfFalseNorthing )
    5689                 : 
    5690                 : {
    5691               0 :     VALIDATE_POINTER1( hSRS, "OSRSetWagner", CE_Failure );
    5692                 : 
    5693                 :     return ((OGRSpatialReference *) hSRS)->SetWagner( 
    5694               0 :         nVariation, dfCenterLat, dfFalseEasting, dfFalseNorthing );
    5695                 : }
    5696                 : 
    5697                 : /************************************************************************/
    5698                 : /*                            SetAuthority()                            */
    5699                 : /************************************************************************/
    5700                 : 
    5701                 : /**
    5702                 :  * \brief Set the authority for a node.
    5703                 :  *
    5704                 :  * This method is the same as the C function OSRSetAuthority().
    5705                 :  *
    5706                 :  * @param pszTargetKey the partial or complete path to the node to 
    5707                 :  * set an authority on.  ie. "PROJCS", "GEOGCS" or "GEOGCS|UNIT".
    5708                 :  *
    5709                 :  * @param pszAuthority authority name, such as "EPSG".
    5710                 :  *
    5711                 :  * @param nCode code for value with this authority.
    5712                 :  *
    5713                 :  * @return OGRERR_NONE on success.
    5714                 :  */
    5715                 : 
    5716          152634 : OGRErr OGRSpatialReference::SetAuthority( const char *pszTargetKey,
    5717                 :                                           const char * pszAuthority, 
    5718                 :                                           int nCode )
    5719                 : 
    5720                 : {
    5721                 : /* -------------------------------------------------------------------- */
    5722                 : /*      Find the node below which the authority should be put.          */
    5723                 : /* -------------------------------------------------------------------- */
    5724          152634 :     OGR_SRSNode  *poNode = GetAttrNode( pszTargetKey );
    5725                 : 
    5726          152634 :     if( poNode == NULL )
    5727               3 :         return OGRERR_FAILURE;
    5728                 : 
    5729                 : /* -------------------------------------------------------------------- */
    5730                 : /*      If there is an existing AUTHORITY child blow it away before     */
    5731                 : /*      trying to set a new one.                                        */
    5732                 : /* -------------------------------------------------------------------- */
    5733          152631 :     int iOldChild = poNode->FindChild( "AUTHORITY" );
    5734          152631 :     if( iOldChild != -1 )
    5735               0 :         poNode->DestroyChild( iOldChild );
    5736                 : 
    5737                 : /* -------------------------------------------------------------------- */
    5738                 : /*      Create a new authority node.                                    */
    5739                 : /* -------------------------------------------------------------------- */
    5740                 :     char   szCode[32];
    5741                 :     OGR_SRSNode *poAuthNode;
    5742                 : 
    5743          152631 :     sprintf( szCode, "%d", nCode );
    5744                 : 
    5745          152631 :     poAuthNode = new OGR_SRSNode( "AUTHORITY" );
    5746          305262 :     poAuthNode->AddChild( new OGR_SRSNode( pszAuthority ) );
    5747          305262 :     poAuthNode->AddChild( new OGR_SRSNode( szCode ) );
    5748                 :     
    5749          152631 :     poNode->AddChild( poAuthNode );
    5750                 : 
    5751          152631 :     return OGRERR_NONE;
    5752                 : }
    5753                 : 
    5754                 : /************************************************************************/
    5755                 : /*                          OSRSetAuthority()                           */
    5756                 : /************************************************************************/
    5757                 : 
    5758                 : /**
    5759                 :  * \brief Set the authority for a node.
    5760                 :  *
    5761                 :  * This function is the same as OGRSpatialReference::SetAuthority().
    5762                 :  */
    5763               0 : OGRErr OSRSetAuthority( OGRSpatialReferenceH hSRS, 
    5764                 :                         const char *pszTargetKey,
    5765                 :                         const char * pszAuthority, 
    5766                 :                         int nCode )
    5767                 : 
    5768                 : {
    5769               0 :     VALIDATE_POINTER1( hSRS, "OSRSetAuthority", CE_Failure );
    5770                 : 
    5771                 :     return ((OGRSpatialReference *) hSRS)->SetAuthority( pszTargetKey, 
    5772                 :                                                          pszAuthority,
    5773               0 :                                                          nCode );
    5774                 : }
    5775                 : 
    5776                 : /************************************************************************/
    5777                 : /*                          GetAuthorityCode()                          */
    5778                 : /************************************************************************/
    5779                 : 
    5780                 : /**
    5781                 :  * \brief Get the authority code for a node.
    5782                 :  *
    5783                 :  * This method is used to query an AUTHORITY[] node from within the 
    5784                 :  * WKT tree, and fetch the code value.  
    5785                 :  *
    5786                 :  * While in theory values may be non-numeric, for the EPSG authority all
    5787                 :  * code values should be integral.
    5788                 :  *
    5789                 :  * This method is the same as the C function OSRGetAuthorityCode().
    5790                 :  *
    5791                 :  * @param pszTargetKey the partial or complete path to the node to 
    5792                 :  * get an authority from.  ie. "PROJCS", "GEOGCS", "GEOGCS|UNIT" or NULL to 
    5793                 :  * search for an authority node on the root element.
    5794                 :  *
    5795                 :  * @return value code from authority node, or NULL on failure.  The value
    5796                 :  * returned is internal and should not be freed or modified.
    5797                 :  */
    5798                 : 
    5799                 : const char *
    5800            6624 : OGRSpatialReference::GetAuthorityCode( const char *pszTargetKey ) const
    5801                 : 
    5802                 : {
    5803                 : /* -------------------------------------------------------------------- */
    5804                 : /*      Find the node below which the authority should be put.          */
    5805                 : /* -------------------------------------------------------------------- */
    5806                 :     const OGR_SRSNode  *poNode;
    5807                 : 
    5808            6624 :     if( pszTargetKey == NULL )
    5809             169 :         poNode = poRoot;
    5810                 :     else
    5811            6455 :         poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
    5812                 : 
    5813            6624 :     if( poNode == NULL )
    5814               9 :         return NULL;
    5815                 : 
    5816                 : /* -------------------------------------------------------------------- */
    5817                 : /*      Fetch AUTHORITY child if there is one.                          */
    5818                 : /* -------------------------------------------------------------------- */
    5819            6615 :     if( poNode->FindChild("AUTHORITY") == -1 )
    5820             602 :         return NULL;
    5821                 :         
    5822            6013 :     poNode = poNode->GetChild(poNode->FindChild("AUTHORITY"));
    5823                 : 
    5824                 : /* -------------------------------------------------------------------- */
    5825                 : /*      Create a new authority node.                                    */
    5826                 : /* -------------------------------------------------------------------- */
    5827            6013 :     if( poNode->GetChildCount() < 2 )
    5828               0 :         return NULL;
    5829                 : 
    5830            6013 :     return poNode->GetChild(1)->GetValue();
    5831                 : }
    5832                 : 
    5833                 : /************************************************************************/
    5834                 : /*                          OSRGetAuthorityCode()                       */
    5835                 : /************************************************************************/
    5836                 : 
    5837                 : /**
    5838                 :  * \brief Get the authority code for a node.
    5839                 :  *
    5840                 :  * This function is the same as OGRSpatialReference::GetAuthorityCode().
    5841                 :  */
    5842            1323 : const char *OSRGetAuthorityCode( OGRSpatialReferenceH hSRS, 
    5843                 :                                  const char *pszTargetKey )
    5844                 : 
    5845                 : {
    5846            1323 :     VALIDATE_POINTER1( hSRS, "OSRGetAuthorityCode", NULL );
    5847                 : 
    5848            1323 :     return ((OGRSpatialReference *) hSRS)->GetAuthorityCode( pszTargetKey );
    5849                 : }
    5850                 : 
    5851                 : /************************************************************************/
    5852                 : /*                          GetAuthorityName()                          */
    5853                 : /************************************************************************/
    5854                 : 
    5855                 : /**
    5856                 :  * \brief Get the authority name for a node.
    5857                 :  *
    5858                 :  * This method is used to query an AUTHORITY[] node from within the 
    5859                 :  * WKT tree, and fetch the authority name value.  
    5860                 :  *
    5861                 :  * The most common authority is "EPSG".
    5862                 :  *
    5863                 :  * This method is the same as the C function OSRGetAuthorityName().
    5864                 :  *
    5865                 :  * @param pszTargetKey the partial or complete path to the node to 
    5866                 :  * get an authority from.  ie. "PROJCS", "GEOGCS", "GEOGCS|UNIT" or NULL to 
    5867                 :  * search for an authority node on the root element.
    5868                 :  *
    5869                 :  * @return value code from authority node, or NULL on failure. The value
    5870                 :  * returned is internal and should not be freed or modified.
    5871                 :  */
    5872                 : 
    5873                 : const char *
    5874           51308 : OGRSpatialReference::GetAuthorityName( const char *pszTargetKey ) const
    5875                 : 
    5876                 : {
    5877                 : /* -------------------------------------------------------------------- */
    5878                 : /*      Find the node below which the authority should be put.          */
    5879                 : /* -------------------------------------------------------------------- */
    5880                 :     const OGR_SRSNode  *poNode;
    5881                 : 
    5882           51308 :     if( pszTargetKey == NULL )
    5883             154 :         poNode = poRoot;
    5884                 :     else
    5885           51154 :         poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
    5886                 : 
    5887           51308 :     if( poNode == NULL )
    5888            3644 :         return NULL;
    5889                 : 
    5890                 : /* -------------------------------------------------------------------- */
    5891                 : /*      Fetch AUTHORITY child if there is one.                          */
    5892                 : /* -------------------------------------------------------------------- */
    5893           47664 :     if( poNode->FindChild("AUTHORITY") == -1 )
    5894           16852 :         return NULL;
    5895                 :         
    5896           30812 :     poNode = poNode->GetChild(poNode->FindChild("AUTHORITY"));
    5897                 : 
    5898                 : /* -------------------------------------------------------------------- */
    5899                 : /*      Create a new authority node.                                    */
    5900                 : /* -------------------------------------------------------------------- */
    5901           30812 :     if( poNode->GetChildCount() < 2 )
    5902               0 :         return NULL;
    5903                 : 
    5904           30812 :     return poNode->GetChild(0)->GetValue();
    5905                 : }
    5906                 : 
    5907                 : /************************************************************************/
    5908                 : /*                        OSRGetAuthorityName()                         */
    5909                 : /************************************************************************/
    5910                 : 
    5911                 : /**
    5912                 :  * \brief Get the authority name for a node.
    5913                 :  *
    5914                 :  * This function is the same as OGRSpatialReference::GetAuthorityName().
    5915                 :  */
    5916              73 : const char *OSRGetAuthorityName( OGRSpatialReferenceH hSRS, 
    5917                 :                                  const char *pszTargetKey )
    5918                 : 
    5919                 : {
    5920              73 :     VALIDATE_POINTER1( hSRS, "OSRGetAuthorityName", NULL );
    5921                 : 
    5922              73 :     return ((OGRSpatialReference *) hSRS)->GetAuthorityName( pszTargetKey );
    5923                 : }
    5924                 : 
    5925                 : /************************************************************************/
    5926                 : /*                           StripVertical()                            */
    5927                 : /************************************************************************/
    5928                 : 
    5929                 : /**
    5930                 :  * \brief Convert a compound cs into a horizontal CS.
    5931                 :  *
    5932                 :  * If this SRS is of type COMPD_CS[] then the vertical CS and the root COMPD_CS 
    5933                 :  * nodes are stripped resulting and only the horizontal coordinate system
    5934                 :  * portion remains (normally PROJCS, GEOGCS or LOCAL_CS). 
    5935                 :  *
    5936                 :  * If this is not a compound coordinate system then nothing is changed.
    5937                 :  *
    5938                 :  * @since OGR 1.8.0
    5939                 :  */
    5940                 : 
    5941           36073 : OGRErr OGRSpatialReference::StripVertical()
    5942                 : 
    5943                 : {
    5944           36073 :     if( GetRoot() == NULL 
    5945                 :         || !EQUAL(GetRoot()->GetValue(),"COMPD_CS") )
    5946           36072 :         return OGRERR_NONE;
    5947                 : 
    5948               1 :     OGR_SRSNode *poHorizontalCS = GetRoot()->GetChild( 1 );
    5949               1 :     if( poHorizontalCS != NULL )
    5950               1 :         poHorizontalCS = poHorizontalCS->Clone();
    5951               1 :     SetRoot( poHorizontalCS );
    5952                 : 
    5953               1 :     return OGRERR_NONE;
    5954                 : }
    5955                 : 
    5956                 : /************************************************************************/
    5957                 : /*                            StripCTParms()                            */
    5958                 : /************************************************************************/
    5959                 : 
    5960                 : /** 
    5961                 :  * \brief Strip OGC CT Parameters.
    5962                 :  *
    5963                 :  * This method will remove all components of the coordinate system
    5964                 :  * that are specific to the OGC CT Specification.  That is it will attempt
    5965                 :  * to strip it down to being compatible with the Simple Features 1.0 
    5966                 :  * specification.
    5967                 :  *
    5968                 :  * This method is the same as the C function OSRStripCTParms().
    5969                 :  *
    5970                 :  * @param poCurrent node to operate on.  NULL to operate on whole tree.
    5971                 :  *
    5972                 :  * @return OGRERR_NONE on success or an error code.
    5973                 :  */
    5974                 : 
    5975           36072 : OGRErr OGRSpatialReference::StripCTParms( OGR_SRSNode * poCurrent )
    5976                 : 
    5977                 : {
    5978           36072 :     if( poCurrent == NULL )
    5979                 :     {
    5980           36072 :         StripVertical();
    5981           36072 :         poCurrent = GetRoot();
    5982                 :     }
    5983                 : 
    5984           36072 :     if( poCurrent == NULL )
    5985               0 :         return OGRERR_NONE;
    5986                 : 
    5987           36072 :     if( poCurrent == GetRoot() && EQUAL(poCurrent->GetValue(),"LOCAL_CS") )
    5988                 :     {
    5989               0 :         delete poCurrent;
    5990               0 :         poRoot = NULL;
    5991                 : 
    5992               0 :         return OGRERR_NONE;
    5993                 :     }
    5994                 :     
    5995           36072 :     if( poCurrent == NULL )
    5996               0 :         return OGRERR_NONE;
    5997                 : 
    5998           36072 :     poCurrent->StripNodes( "AUTHORITY" );
    5999           36072 :     poCurrent->StripNodes( "TOWGS84" );
    6000           36072 :     poCurrent->StripNodes( "AXIS" );
    6001           36072 :     poCurrent->StripNodes( "EXTENSION" );
    6002                 : 
    6003           36072 :     return OGRERR_NONE;
    6004                 : }
    6005                 : 
    6006                 : /************************************************************************/
    6007                 : /*                          OSRStripCTParms()                           */
    6008                 : /************************************************************************/
    6009                 : 
    6010                 : /** 
    6011                 :  * \brief Strip OGC CT Parameters.
    6012                 :  *
    6013                 :  * This function is the same as OGRSpatialReference::StripCTParms().
    6014                 :  */
    6015           17037 : OGRErr OSRStripCTParms( OGRSpatialReferenceH hSRS )
    6016                 : 
    6017                 : {
    6018           17037 :     VALIDATE_POINTER1( hSRS, "OSRStripCTParms", CE_Failure );
    6019                 : 
    6020           17037 :     return ((OGRSpatialReference *) hSRS)->StripCTParms( NULL );
    6021                 : }
    6022                 : 
    6023                 : /************************************************************************/
    6024                 : /*                             IsCompound()                             */
    6025                 : /************************************************************************/
    6026                 : 
    6027                 : /**
    6028                 :  * \brief Check if coordinate system is compound.
    6029                 :  *
    6030                 :  * This method is the same as the C function OSRIsCompound().
    6031                 :  *
    6032                 :  * @return TRUE if this is rooted with a COMPD_CS node.
    6033                 :  */
    6034                 : 
    6035               1 : int OGRSpatialReference::IsCompound() const
    6036                 : 
    6037                 : {
    6038               1 :     if( poRoot == NULL )
    6039               0 :         return FALSE;
    6040                 : 
    6041               1 :     return EQUAL(poRoot->GetValue(),"COMPD_CS");
    6042                 : }
    6043                 : 
    6044                 : /************************************************************************/
    6045                 : /*                           OSRIsCompound()                            */
    6046                 : /************************************************************************/
    6047                 : 
    6048                 : /** 
    6049                 :  * \brief Check if the coordinate system is compound.
    6050                 :  *
    6051                 :  * This function is the same as OGRSpatialReference::IsCompound().
    6052                 :  */
    6053               1 : int OSRIsCompound( OGRSpatialReferenceH hSRS ) 
    6054                 : 
    6055                 : {
    6056               1 :     VALIDATE_POINTER1( hSRS, "OSRIsCompound", 0 );
    6057                 : 
    6058               1 :     return ((OGRSpatialReference *) hSRS)->IsCompound();
    6059                 : }
    6060                 : 
    6061                 : /************************************************************************/
    6062                 : /*                            IsProjected()                             */
    6063                 : /************************************************************************/
    6064                 : 
    6065                 : /**
    6066                 :  * \brief Check if projected coordinate system.
    6067                 :  *
    6068                 :  * This method is the same as the C function OSRIsProjected().
    6069                 :  *
    6070                 :  * @return TRUE if this contains a PROJCS node indicating a it is a 
    6071                 :  * projected coordinate system. 
    6072                 :  */
    6073                 : 
    6074           66802 : int OGRSpatialReference::IsProjected() const
    6075                 : 
    6076                 : {
    6077           66802 :     if( poRoot == NULL )
    6078             291 :         return FALSE;
    6079                 : 
    6080           66511 :     if( EQUAL(poRoot->GetValue(),"PROJCS") )
    6081           49958 :         return TRUE;
    6082           16553 :     else if( EQUAL(poRoot->GetValue(),"COMPD_CS") )
    6083              18 :         return GetAttrNode( "PROJCS" ) != NULL;
    6084                 :     else 
    6085           16535 :         return FALSE;
    6086                 : }
    6087                 : 
    6088                 : /************************************************************************/
    6089                 : /*                           OSRIsProjected()                           */
    6090                 : /************************************************************************/
    6091                 : /** 
    6092                 :  * \brief Check if projected coordinate system.
    6093                 :  *
    6094                 :  * This function is the same as OGRSpatialReference::IsProjected().
    6095                 :  */
    6096               6 : int OSRIsProjected( OGRSpatialReferenceH hSRS ) 
    6097                 : 
    6098                 : {
    6099               6 :     VALIDATE_POINTER1( hSRS, "OSRIsProjected", 0 );
    6100                 : 
    6101               6 :     return ((OGRSpatialReference *) hSRS)->IsProjected();
    6102                 : }
    6103                 : 
    6104                 : /************************************************************************/
    6105                 : /*                            IsGeocentric()                            */
    6106                 : /************************************************************************/
    6107                 : 
    6108                 : /**
    6109                 :  * \brief Check if geocentric coordinate system.
    6110                 :  *
    6111                 :  * This method is the same as the C function OSRIsGeocentric().
    6112                 :  *
    6113                 :  * @return TRUE if this contains a GEOCCS node indicating a it is a 
    6114                 :  * geocentric coordinate system.
    6115                 :  *
    6116                 :  * @since OGR 1.9.0
    6117                 :  */
    6118                 : 
    6119           34877 : int OGRSpatialReference::IsGeocentric() const
    6120                 : 
    6121                 : {
    6122           34877 :     if( poRoot == NULL )
    6123            9444 :         return FALSE;
    6124                 : 
    6125           25433 :     if( EQUAL(poRoot->GetValue(),"GEOCCS") )
    6126              12 :         return TRUE;
    6127                 :     else 
    6128           25421 :         return FALSE;
    6129                 : }
    6130                 : 
    6131                 : /************************************************************************/
    6132                 : /*                           OSRIsGeocentric()                          */
    6133                 : /************************************************************************/
    6134                 : /** 
    6135                 :  * \brief Check if geocentric coordinate system.
    6136                 :  *
    6137                 :  * This function is the same as OGRSpatialReference::IsGeocentric().
    6138                 :  *
    6139                 :  * @since OGR 1.9.0
    6140                 :  */
    6141               2 : int OSRIsGeocentric( OGRSpatialReferenceH hSRS ) 
    6142                 : 
    6143                 : {
    6144               2 :     VALIDATE_POINTER1( hSRS, "OSRIsGeocentric", 0 );
    6145                 : 
    6146               2 :     return ((OGRSpatialReference *) hSRS)->IsGeocentric();
    6147                 : }
    6148                 : 
    6149                 : /************************************************************************/
    6150                 : /*                            IsGeographic()                            */
    6151                 : /************************************************************************/
    6152                 : 
    6153                 : /**
    6154                 :  * \brief Check if geographic coordinate system.
    6155                 :  *
    6156                 :  * This method is the same as the C function OSRIsGeographic().
    6157                 :  *
    6158                 :  * @return TRUE if this spatial reference is geographic ... that is the 
    6159                 :  * root is a GEOGCS node. 
    6160                 :  */
    6161                 : 
    6162            4517 : int OGRSpatialReference::IsGeographic() const
    6163                 : 
    6164                 : {
    6165            4517 :     if( GetRoot() == NULL )
    6166               9 :         return FALSE;
    6167                 : 
    6168            4508 :     if( EQUAL(poRoot->GetValue(),"GEOGCS") )
    6169            3493 :         return TRUE;
    6170            1015 :     else if( EQUAL(poRoot->GetValue(),"COMPD_CS") )
    6171                 :         return GetAttrNode( "GEOGCS" ) != NULL 
    6172               2 :             && GetAttrNode( "PROJCS" ) == NULL;
    6173                 :     else 
    6174            1013 :         return FALSE;
    6175                 : }
    6176                 : 
    6177                 : /************************************************************************/
    6178                 : /*                          OSRIsGeographic()                           */
    6179                 : /************************************************************************/
    6180                 : /** 
    6181                 :  * \brief Check if geographic coordinate system.
    6182                 :  *
    6183                 :  * This function is the same as OGRSpatialReference::IsGeographic().
    6184                 :  */
    6185              49 : int OSRIsGeographic( OGRSpatialReferenceH hSRS )
    6186                 : 
    6187                 : {
    6188              49 :     VALIDATE_POINTER1( hSRS, "OSRIsGeographic", 0 );
    6189                 : 
    6190              49 :     return ((OGRSpatialReference *) hSRS)->IsGeographic();
    6191                 : }
    6192                 : 
    6193                 : /************************************************************************/
    6194                 : /*                              IsLocal()                               */
    6195                 : /************************************************************************/
    6196                 : 
    6197                 : /**
    6198                 :  * \brief Check if local coordinate system.
    6199                 :  *
    6200                 :  * This method is the same as the C function OSRIsLocal().
    6201                 :  *
    6202                 :  * @return TRUE if this spatial reference is local ... that is the 
    6203                 :  * root is a LOCAL_CS node. 
    6204                 :  */
    6205                 : 
    6206           15876 : int OGRSpatialReference::IsLocal() const
    6207                 : 
    6208                 : {
    6209           15876 :     if( GetRoot() == NULL )
    6210              14 :         return FALSE;
    6211                 : 
    6212           15862 :     return EQUAL(GetRoot()->GetValue(),"LOCAL_CS");
    6213                 : }
    6214                 : 
    6215                 : /************************************************************************/
    6216                 : /*                          OSRIsLocal()                                */
    6217                 : /************************************************************************/
    6218                 : /** 
    6219                 :  * \brief Check if local coordinate system.
    6220                 :  *
    6221                 :  * This function is the same as OGRSpatialReference::IsLocal().
    6222                 :  */
    6223               1 : int OSRIsLocal( OGRSpatialReferenceH hSRS )
    6224                 : 
    6225                 : {
    6226               1 :     VALIDATE_POINTER1( hSRS, "OSRIsLocal", 0 );
    6227                 : 
    6228               1 :     return ((OGRSpatialReference *) hSRS)->IsLocal();
    6229                 : }
    6230                 : 
    6231                 : /************************************************************************/
    6232                 : /*                            IsVertical()                              */
    6233                 : /************************************************************************/
    6234                 : 
    6235                 : /**
    6236                 :  * \brief Check if vertical coordinate system.
    6237                 :  *
    6238                 :  * This method is the same as the C function OSRIsVertical().
    6239                 :  *
    6240                 :  * @return TRUE if this contains a VERT_CS node indicating a it is a 
    6241                 :  * vertical coordinate system.
    6242                 :  *
    6243                 :  * @since OGR 1.8.0
    6244                 :  */
    6245                 : 
    6246           16407 : int OGRSpatialReference::IsVertical() const
    6247                 : 
    6248                 : {
    6249           16407 :     if( poRoot == NULL )
    6250              53 :         return FALSE;
    6251                 : 
    6252           16354 :     if( EQUAL(poRoot->GetValue(),"VERT_CS") )
    6253               1 :         return TRUE;
    6254           16353 :     else if( EQUAL(poRoot->GetValue(),"COMPD_CS") )
    6255               5 :         return GetAttrNode( "VERT_CS" ) != NULL;
    6256                 :     else 
    6257           16348 :         return FALSE;
    6258                 : }
    6259                 : 
    6260                 : /************************************************************************/
    6261                 : /*                           OSRIsVertical()                            */
    6262                 : /************************************************************************/
    6263                 : /** 
    6264                 :  * \brief Check if vertical coordinate system.
    6265                 :  *
    6266                 :  * This function is the same as OGRSpatialReference::IsVertical().
    6267                 :  *
    6268                 :  * @since OGR 1.8.0
    6269                 :  */
    6270               0 : int OSRIsVertical( OGRSpatialReferenceH hSRS ) 
    6271                 : 
    6272                 : {
    6273               0 :     VALIDATE_POINTER1( hSRS, "OSRIsVertical", 0 );
    6274                 : 
    6275               0 :     return ((OGRSpatialReference *) hSRS)->IsVertical();
    6276                 : }
    6277                 : 
    6278                 : /************************************************************************/
    6279                 : /*                            CloneGeogCS()                             */
    6280                 : /************************************************************************/
    6281                 : 
    6282                 : /**
    6283                 :  * \brief Make a duplicate of the GEOGCS node of this OGRSpatialReference object.
    6284                 :  *
    6285                 :  * @return a new SRS, which becomes the responsibility of the caller. 
    6286                 :  */
    6287            4587 : OGRSpatialReference *OGRSpatialReference::CloneGeogCS() const
    6288                 : 
    6289                 : {
    6290                 :     const OGR_SRSNode *poGeogCS;
    6291                 :     OGRSpatialReference * poNewSRS;
    6292                 : 
    6293                 : /* -------------------------------------------------------------------- */
    6294                 : /*      We have to reconstruct the GEOGCS node for geocentric           */
    6295                 : /*      coordinate systems.                                             */
    6296                 : /* -------------------------------------------------------------------- */
    6297            4587 :     if( IsGeocentric() )
    6298                 :     {
    6299               0 :         const OGR_SRSNode *poDatum = GetAttrNode( "DATUM" );
    6300               0 :         const OGR_SRSNode *poPRIMEM = GetAttrNode( "PRIMEM" );
    6301                 :         OGR_SRSNode *poGeogCS;
    6302                 :         
    6303               0 :         if( poDatum == NULL || poPRIMEM == NULL )
    6304               0 :             return NULL;
    6305                 :         
    6306               0 :         poGeogCS = new OGR_SRSNode( "GEOGCS" );
    6307               0 :         poGeogCS->AddChild( new OGR_SRSNode( "unnamed" ) );
    6308               0 :         poGeogCS->AddChild( poDatum->Clone() );
    6309               0 :         poGeogCS->AddChild( poPRIMEM->Clone() );
    6310                 : 
    6311               0 :         poNewSRS = new OGRSpatialReference();
    6312               0 :         poNewSRS->SetRoot( poGeogCS );
    6313                 : 
    6314               0 :         poNewSRS->SetAngularUnits( "degree", CPLAtof(SRS_UA_DEGREE_CONV) );
    6315                 : 
    6316               0 :         return poNewSRS;
    6317                 :     }
    6318                 : 
    6319                 : /* -------------------------------------------------------------------- */
    6320                 : /*      For all others we just search the tree, and duplicate.          */
    6321                 : /* -------------------------------------------------------------------- */
    6322            4587 :     poGeogCS = GetAttrNode( "GEOGCS" );
    6323            4587 :     if( poGeogCS == NULL )
    6324               2 :         return NULL;
    6325                 : 
    6326            4585 :     poNewSRS = new OGRSpatialReference();
    6327            4585 :     poNewSRS->SetRoot( poGeogCS->Clone() );
    6328                 : 
    6329            4585 :     return poNewSRS;
    6330                 : }
    6331                 : 
    6332                 : /************************************************************************/
    6333                 : /*                           OSRCloneGeogCS()                           */
    6334                 : /************************************************************************/
    6335                 : /**
    6336                 :  * \brief Make a duplicate of the GEOGCS node of this OGRSpatialReference object.
    6337                 :  *
    6338                 :  * This function is the same as OGRSpatialReference::CloneGeogCS().
    6339                 :  */
    6340              75 : OGRSpatialReferenceH CPL_STDCALL OSRCloneGeogCS( OGRSpatialReferenceH hSource )
    6341                 : 
    6342                 : {
    6343              75 :     VALIDATE_POINTER1( hSource, "OSRCloneGeogCS", NULL );
    6344                 : 
    6345                 :     return (OGRSpatialReferenceH) 
    6346              75 :         ((OGRSpatialReference *) hSource)->CloneGeogCS();
    6347                 : }
    6348                 : 
    6349                 : /************************************************************************/
    6350                 : /*                            IsSameGeogCS()                            */
    6351                 : /************************************************************************/
    6352                 : 
    6353                 : /**
    6354                 :  * \brief Do the GeogCS'es match?
    6355                 :  *
    6356                 :  * This method is the same as the C function OSRIsSameGeogCS().
    6357                 :  *
    6358                 :  * @param poOther the SRS being compared against. 
    6359                 :  *
    6360                 :  * @return TRUE if they are the same or FALSE otherwise. 
    6361                 :  */
    6362                 : 
    6363           30606 : int OGRSpatialReference::IsSameGeogCS( const OGRSpatialReference *poOther ) const
    6364                 : 
    6365                 : {
    6366                 :     const char *pszThisValue, *pszOtherValue;
    6367                 : 
    6368                 : /* -------------------------------------------------------------------- */
    6369                 : /*      Does the datum name match?  Note that we assume                 */
    6370                 : /*      compatibility if either is missing a datum.                     */
    6371                 : /* -------------------------------------------------------------------- */
    6372           30606 :     pszThisValue = this->GetAttrValue( "DATUM" );
    6373           30606 :     pszOtherValue = poOther->GetAttrValue( "DATUM" );
    6374                 : 
    6375           30606 :     if( pszThisValue != NULL && pszOtherValue != NULL 
    6376                 :         && !EQUAL(pszThisValue,pszOtherValue) )
    6377           11361 :         return FALSE;
    6378                 : 
    6379                 : /* -------------------------------------------------------------------- */
    6380                 : /*      Do the datum TOWGS84 values match if present?                   */
    6381                 : /* -------------------------------------------------------------------- */
    6382                 :     double adfTOWGS84[7], adfOtherTOWGS84[7];
    6383                 :     int i;
    6384                 : 
    6385           19245 :     this->GetTOWGS84( adfTOWGS84, 7 );
    6386           19245 :     poOther->GetTOWGS84( adfOtherTOWGS84, 7 );
    6387                 : 
    6388          153960 :     for( i = 0; i < 7; i++ )
    6389                 :     {
    6390          134715 :         if( fabs(adfTOWGS84[i] - adfOtherTOWGS84[i]) > 0.00001 )
    6391               0 :             return FALSE;
    6392                 :     }
    6393                 : 
    6394                 : /* -------------------------------------------------------------------- */
    6395                 : /*      Do the prime meridians match?  If missing assume a value of zero.*/
    6396                 : /* -------------------------------------------------------------------- */
    6397           19245 :     pszThisValue = this->GetAttrValue( "PRIMEM", 1 );
    6398           19245 :     if( pszThisValue == NULL )
    6399              11 :         pszThisValue = "0.0";
    6400                 : 
    6401           19245 :     pszOtherValue = poOther->GetAttrValue( "PRIMEM", 1 );
    6402           19245 :     if( pszOtherValue == NULL )
    6403              13 :         pszOtherValue = "0.0";
    6404                 : 
    6405           19245 :     if( CPLAtof(pszOtherValue) != CPLAtof(pszThisValue) )
    6406              96 :         return FALSE;
    6407                 :     
    6408                 : /* -------------------------------------------------------------------- */
    6409                 : /*      Do the units match?                                             */
    6410                 : /* -------------------------------------------------------------------- */
    6411           19149 :     pszThisValue = this->GetAttrValue( "GEOGCS|UNIT", 1 );
    6412           19149 :     if( pszThisValue == NULL )
    6413              13 :         pszThisValue = SRS_UA_DEGREE_CONV;
    6414                 : 
    6415           19149 :     pszOtherValue = poOther->GetAttrValue( "GEOGCS|UNIT", 1 );
    6416           19149 :     if( pszOtherValue == NULL )
    6417             127 :         pszOtherValue = SRS_UA_DEGREE_CONV;
    6418                 : 
    6419           19149 :     if( ABS(CPLAtof(pszOtherValue) - CPLAtof(pszThisValue)) > 0.00000001 )
    6420               4 :         return FALSE;
    6421                 : 
    6422                 : /* -------------------------------------------------------------------- */
    6423                 : /*      Does the spheroid match.  Check semi major, and inverse         */
    6424                 : /*      flattening.                                                     */
    6425                 : /* -------------------------------------------------------------------- */
    6426           19145 :     pszThisValue = this->GetAttrValue( "SPHEROID", 1 );
    6427           19145 :     pszOtherValue = poOther->GetAttrValue( "SPHEROID", 1 );
    6428           19145 :     if( pszThisValue != NULL && pszOtherValue != NULL 
    6429                 :         && ABS(CPLAtof(pszThisValue) - CPLAtof(pszOtherValue)) > 0.01 )
    6430              13 :         return FALSE;
    6431                 : 
    6432           19132 :     pszThisValue = this->GetAttrValue( "SPHEROID", 2 );
    6433           19132 :     pszOtherValue = poOther->GetAttrValue( "SPHEROID", 2 );
    6434           19132 :     if( pszThisValue != NULL && pszOtherValue != NULL 
    6435                 :         && ABS(CPLAtof(pszThisValue) - CPLAtof(pszOtherValue)) > 0.0001 )
    6436              20 :         return FALSE;
    6437                 :     
    6438           19112 :     return TRUE;
    6439                 : }
    6440                 : 
    6441                 : /************************************************************************/
    6442                 : /*                          OSRIsSameGeogCS()                           */
    6443                 : /************************************************************************/
    6444                 : 
    6445                 : /** 
    6446                 :  * \brief Do the GeogCS'es match?
    6447                 :  *
    6448                 :  * This function is the same as OGRSpatialReference::IsSameGeogCS().
    6449                 :  */
    6450               0 : int OSRIsSameGeogCS( OGRSpatialReferenceH hSRS1, OGRSpatialReferenceH hSRS2 )
    6451                 : 
    6452                 : {
    6453               0 :     VALIDATE_POINTER1( hSRS1, "OSRIsSameGeogCS", 0 );
    6454               0 :     VALIDATE_POINTER1( hSRS2, "OSRIsSameGeogCS", 0 );
    6455                 : 
    6456                 :     return ((OGRSpatialReference *) hSRS1)->IsSameGeogCS( 
    6457               0 :         (OGRSpatialReference *) hSRS2 );
    6458                 : }
    6459                 : 
    6460                 : /************************************************************************/
    6461                 : /*                            IsSameVertCS()                            */
    6462                 : /************************************************************************/
    6463                 : 
    6464                 : /**
    6465                 :  * \brief Do the VertCS'es match?
    6466                 :  *
    6467                 :  * This method is the same as the C function OSRIsSameVertCS().
    6468                 :  *
    6469                 :  * @param poOther the SRS being compared against. 
    6470                 :  *
    6471                 :  * @return TRUE if they are the same or FALSE otherwise. 
    6472                 :  */
    6473                 : 
    6474               5 : int OGRSpatialReference::IsSameVertCS( const OGRSpatialReference *poOther ) const
    6475                 : 
    6476                 : {
    6477                 :     const char *pszThisValue, *pszOtherValue;
    6478                 : 
    6479                 : /* -------------------------------------------------------------------- */
    6480                 : /*      Does the datum name match?                                      */
    6481                 : /* -------------------------------------------------------------------- */
    6482               5 :     pszThisValue = this->GetAttrValue( "VERT_DATUM" );
    6483               5 :     pszOtherValue = poOther->GetAttrValue( "VERT_DATUM" );
    6484                 : 
    6485               5 :     if( pszThisValue == NULL || pszOtherValue == NULL 
    6486                 :         || !EQUAL(pszThisValue, pszOtherValue) )
    6487               0 :         return FALSE;
    6488                 : 
    6489                 : /* -------------------------------------------------------------------- */
    6490                 : /*      Do the units match?                                             */
    6491                 : /* -------------------------------------------------------------------- */
    6492               5 :     pszThisValue = this->GetAttrValue( "VERT_CS|UNIT", 1 );
    6493               5 :     if( pszThisValue == NULL )
    6494               0 :         pszThisValue = "1.0";
    6495                 : 
    6496               5 :     pszOtherValue = poOther->GetAttrValue( "VERT_CS|UNIT", 1 );
    6497               5 :     if( pszOtherValue == NULL )
    6498               0 :         pszOtherValue = "1.0";
    6499                 : 
    6500               5 :     if( ABS(CPLAtof(pszOtherValue) - CPLAtof(pszThisValue)) > 0.00000001 )
    6501               0 :         return FALSE;
    6502                 : 
    6503               5 :     return TRUE;
    6504                 : }
    6505                 : 
    6506                 : /************************************************************************/
    6507                 : /*                          OSRIsSameVertCS()                           */
    6508                 : /************************************************************************/
    6509                 : 
    6510                 : /** 
    6511                 :  * \brief Do the VertCS'es match?
    6512                 :  *
    6513                 :  * This function is the same as OGRSpatialReference::IsSameVertCS().
    6514                 :  */
    6515               0 : int OSRIsSameVertCS( OGRSpatialReferenceH hSRS1, OGRSpatialReferenceH hSRS2 )
    6516                 : 
    6517                 : {
    6518               0 :     VALIDATE_POINTER1( hSRS1, "OSRIsSameVertCS", 0 );
    6519               0 :     VALIDATE_POINTER1( hSRS2, "OSRIsSameVertCS", 0 );
    6520                 : 
    6521                 :     return ((OGRSpatialReference *) hSRS1)->IsSameVertCS( 
    6522               0 :         (OGRSpatialReference *) hSRS2 );
    6523                 : }
    6524                 : 
    6525                 : /************************************************************************/
    6526                 : /*                               IsSame()                               */
    6527                 : /************************************************************************/
    6528                 : 
    6529                 : /**
    6530                 :  * \brief Do these two spatial references describe the same system ?
    6531                 :  *
    6532                 :  * @param poOtherSRS the SRS being compared to.
    6533                 :  *
    6534                 :  * @return TRUE if equivalent or FALSE otherwise. 
    6535                 :  */
    6536                 : 
    6537           26179 : int OGRSpatialReference::IsSame( const OGRSpatialReference * poOtherSRS ) const
    6538                 : 
    6539                 : {
    6540           26179 :     if( GetRoot() == NULL && poOtherSRS->GetRoot() == NULL )
    6541               8 :         return TRUE;
    6542           26171 :     else if( GetRoot() == NULL || poOtherSRS->GetRoot() == NULL )
    6543               0 :         return FALSE;
    6544                 : 
    6545                 : /* -------------------------------------------------------------------- */
    6546                 : /*      Compare geographic coordinate system.                           */
    6547                 : /* -------------------------------------------------------------------- */
    6548           26171 :     if( !IsSameGeogCS( poOtherSRS ) )
    6549           11223 :         return FALSE;
    6550                 : 
    6551                 : /* -------------------------------------------------------------------- */
    6552                 : /*      Do the have the same root types?  Ie. is one PROJCS and one     */
    6553                 : /*      GEOGCS or perhaps LOCALCS?                                      */
    6554                 : /* -------------------------------------------------------------------- */
    6555           14948 :     if( !EQUAL(GetRoot()->GetValue(),poOtherSRS->GetRoot()->GetValue()) )
    6556               8 :         return FALSE;
    6557                 : 
    6558                 : /* -------------------------------------------------------------------- */
    6559                 : /*      Compare projected coordinate system.                            */
    6560                 : /* -------------------------------------------------------------------- */
    6561           14940 :     if( IsProjected() )
    6562                 :     {
    6563                 :         const char *pszValue1, *pszValue2;
    6564           12244 :         const OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
    6565                 : 
    6566           12244 :         pszValue1 = this->GetAttrValue( "PROJECTION" );
    6567           12244 :         pszValue2 = poOtherSRS->GetAttrValue( "PROJECTION" );
    6568           12244 :         if( pszValue1 == NULL || pszValue2 == NULL
    6569                 :             || !EQUAL(pszValue1,pszValue2) )
    6570               1 :             return FALSE;
    6571                 : 
    6572          124879 :         for( int iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
    6573                 :         {
    6574                 :             const OGR_SRSNode    *poNode;
    6575                 : 
    6576          112676 :             poNode = poPROJCS->GetChild( iChild );
    6577          112676 :             if( !EQUAL(poNode->GetValue(),"PARAMETER") 
    6578                 :                 || poNode->GetChildCount() != 2 )
    6579           49091 :                 continue;
    6580                 : 
    6581                 :             /* this this eventually test within some epsilon? */
    6582           63585 :             if( this->GetProjParm( poNode->GetChild(0)->GetValue() )
    6583                 :                 != poOtherSRS->GetProjParm( poNode->GetChild(0)->GetValue() ) )
    6584              40 :                 return FALSE;
    6585                 :         }
    6586                 :     }
    6587                 : 
    6588                 : /* -------------------------------------------------------------------- */
    6589                 : /*      If they are LOCALCS/PROJCS, do they have the same units?        */
    6590                 : /* -------------------------------------------------------------------- */
    6591           14899 :     if( IsLocal() || IsProjected() )
    6592                 :     {
    6593           12214 :         if( GetLinearUnits() != 0.0 )
    6594                 :         {
    6595                 :             double      dfRatio;
    6596                 : 
    6597           12214 :             dfRatio = poOtherSRS->GetLinearUnits() / GetLinearUnits();
    6598           12214 :             if( dfRatio < 0.9999999999 || dfRatio > 1.000000001 )
    6599               0 :                 return FALSE;
    6600                 :         }
    6601                 :     }
    6602                 : 
    6603                 : /* -------------------------------------------------------------------- */
    6604                 : /*      Compare vertical coordinate system.                             */
    6605                 : /* -------------------------------------------------------------------- */
    6606           14899 :     if( IsVertical() && !IsSameVertCS( poOtherSRS ) )
    6607               0 :         return FALSE;
    6608                 : 
    6609           14899 :     return TRUE;
    6610                 : }
    6611                 : 
    6612                 : /************************************************************************/
    6613                 : /*                             OSRIsSame()                              */
    6614                 : /************************************************************************/
    6615                 : 
    6616                 : /** 
    6617                 :  * \brief Do these two spatial references describe the same system ?
    6618                 :  *
    6619                 :  * This function is the same as OGRSpatialReference::IsSame().
    6620                 :  */
    6621           14699 : int OSRIsSame( OGRSpatialReferenceH hSRS1, OGRSpatialReferenceH hSRS2 )
    6622                 : 
    6623                 : {
    6624           14699 :     VALIDATE_POINTER1( hSRS1, "OSRIsSame", 0 );
    6625           14699 :     VALIDATE_POINTER1( hSRS2, "OSRIsSame", 0 );
    6626                 : 
    6627                 :     return ((OGRSpatialReference *) hSRS1)->IsSame( 
    6628           14699 :         (OGRSpatialReference *) hSRS2 );
    6629                 : }
    6630                 : 
    6631                 : /************************************************************************/
    6632                 : /*                             SetTOWGS84()                             */
    6633                 : /************************************************************************/
    6634                 : 
    6635                 : /**
    6636                 :  * \brief Set the Bursa-Wolf conversion to WGS84. 
    6637                 :  * 
    6638                 :  * This will create the TOWGS84 node as a child of the DATUM.  It will fail
    6639                 :  * if there is no existing DATUM node.  Unlike most OGRSpatialReference
    6640                 :  * methods it will insert itself in the appropriate order, and will replace
    6641                 :  * an existing TOWGS84 node if there is one. 
    6642                 :  *
    6643                 :  * The parameters have the same meaning as EPSG transformation 9606
    6644                 :  * (Position Vector 7-param. transformation). 
    6645                 :  * 
    6646                 :  * This method is the same as the C function OSRSetTOWGS84().
    6647                 :  * 
    6648                 :  * @param dfDX X child in meters.
    6649                 :  * @param dfDY Y child in meters.
    6650                 :  * @param dfDZ Z child in meters.
    6651                 :  * @param dfEX X rotation in arc seconds (optional, defaults to zero).
    6652                 :  * @param dfEY Y rotation in arc seconds (optional, defaults to zero).
    6653                 :  * @param dfEZ Z rotation in arc seconds (optional, defaults to zero).
    6654                 :  * @param dfPPM scaling factor (parts per million).
    6655                 :  * 
    6656                 :  * @return OGRERR_NONE on success. 
    6657                 :  */ 
    6658                 : 
    6659             119 : OGRErr OGRSpatialReference::SetTOWGS84( double dfDX, double dfDY, double dfDZ,
    6660                 :                                         double dfEX, double dfEY, double dfEZ, 
    6661                 :                                         double dfPPM )
    6662                 : 
    6663                 : {
    6664                 :     OGR_SRSNode     *poDatum, *poTOWGS84;
    6665                 :     int             iPosition;
    6666                 :     char            szValue[64];
    6667                 : 
    6668             119 :     poDatum = GetAttrNode( "DATUM" );
    6669             119 :     if( poDatum == NULL )
    6670               0 :         return OGRERR_FAILURE;
    6671                 :     
    6672             119 :     if( poDatum->FindChild( "TOWGS84" ) != -1 )
    6673              35 :         poDatum->DestroyChild( poDatum->FindChild( "TOWGS84" ) );
    6674                 : 
    6675             119 :     iPosition = poDatum->GetChildCount();
    6676             119 :     if( poDatum->FindChild("AUTHORITY") != -1 )
    6677                 :     {
    6678              63 :         iPosition = poDatum->FindChild("AUTHORITY");
    6679                 :     }
    6680                 : 
    6681             119 :     poTOWGS84 = new OGR_SRSNode("TOWGS84");
    6682                 : 
    6683             119 :     OGRPrintDouble( szValue, dfDX );
    6684             238 :     poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
    6685                 : 
    6686             119 :     OGRPrintDouble( szValue, dfDY );
    6687             238 :     poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
    6688                 : 
    6689             119 :     OGRPrintDouble( szValue, dfDZ );
    6690             238 :     poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
    6691                 : 
    6692             119 :     OGRPrintDouble( szValue, dfEX );
    6693             238 :     poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
    6694                 : 
    6695             119 :     OGRPrintDouble( szValue, dfEY );
    6696             238 :     poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
    6697                 : 
    6698             119 :     OGRPrintDouble( szValue, dfEZ );
    6699             238 :     poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
    6700                 : 
    6701             119 :     OGRPrintDouble( szValue, dfPPM );
    6702             238 :     poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
    6703                 : 
    6704             119 :     poDatum->InsertChild( poTOWGS84, iPosition );
    6705                 : 
    6706             119 :     return OGRERR_NONE;
    6707                 : }
    6708                 : 
    6709                 : /************************************************************************/
    6710                 : /*                           OSRSetTOWGS84()                            */
    6711                 : /************************************************************************/
    6712                 : 
    6713                 : /** 
    6714                 :  * \brief Set the Bursa-Wolf conversion to WGS84. 
    6715                 :  *
    6716                 :  * This function is the same as OGRSpatialReference::SetTOWGS84().
    6717                 :  */
    6718              22 : OGRErr OSRSetTOWGS84( OGRSpatialReferenceH hSRS, 
    6719                 :                       double dfDX, double dfDY, double dfDZ, 
    6720                 :                       double dfEX, double dfEY, double dfEZ, 
    6721                 :                       double dfPPM )
    6722                 : 
    6723                 : {
    6724              22 :     VALIDATE_POINTER1( hSRS, "OSRSetTOWGS84", CE_Failure );
    6725                 : 
    6726                 :     return ((OGRSpatialReference *) hSRS)->SetTOWGS84( dfDX, dfDY, dfDZ, 
    6727                 :                                                        dfEX, dfEY, dfEZ, 
    6728              22 :                                                        dfPPM );
    6729                 : }
    6730                 : 
    6731                 : /************************************************************************/
    6732                 : /*                             GetTOWGS84()                             */
    6733                 : /************************************************************************/
    6734                 : 
    6735                 : /**
    6736                 :  * \brief Fetch TOWGS84 parameters, if available. 
    6737                 :  * 
    6738                 :  * @param padfCoeff array into which up to 7 coefficients are placed.
    6739                 :  * @param nCoeffCount size of padfCoeff - defaults to 7.
    6740                 :  * 
    6741                 :  * @return OGRERR_NONE on success, or OGRERR_FAILURE if there is no
    6742                 :  * TOWGS84 node available. 
    6743                 :  */
    6744                 : 
    6745           39506 : OGRErr OGRSpatialReference::GetTOWGS84( double * padfCoeff, 
    6746                 :                                         int nCoeffCount ) const
    6747                 : 
    6748                 : {
    6749           39506 :     const OGR_SRSNode   *poNode = GetAttrNode( "TOWGS84" );
    6750                 : 
    6751           39506 :     memset( padfCoeff, 0, sizeof(double) * nCoeffCount );
    6752                 : 
    6753           39506 :     if( poNode == NULL )
    6754           39059 :         return OGRERR_FAILURE;
    6755                 : 
    6756            3576 :     for( int i = 0; i < nCoeffCount && i < poNode->GetChildCount(); i++ )
    6757                 :     {
    6758            3129 :         padfCoeff[i] = CPLAtof(poNode->GetChild(i)->GetValue());
    6759                 :     }
    6760                 : 
    6761             447 :     return OGRERR_NONE;
    6762                 : }
    6763                 : 
    6764                 : /************************************************************************/
    6765                 : /*                           OSRGetTOWGS84()                            */
    6766                 : /************************************************************************/
    6767                 : 
    6768                 : /** 
    6769                 :  * \brief Fetch TOWGS84 parameters, if available. 
    6770                 :  *
    6771                 :  * This function is the same as OGRSpatialReference::GetTOWGS84().
    6772                 :  */
    6773               3 : OGRErr OSRGetTOWGS84( OGRSpatialReferenceH hSRS, 
    6774                 :                       double * padfCoeff, int nCoeffCount )
    6775                 : 
    6776                 : {
    6777               3 :     VALIDATE_POINTER1( hSRS, "OSRGetTOWGS84", CE_Failure );
    6778                 : 
    6779               3 :     return ((OGRSpatialReference *) hSRS)->GetTOWGS84( padfCoeff, nCoeffCount);
    6780                 : }
    6781                 : 
    6782                 : /************************************************************************/
    6783                 : /*                         IsAngularParameter()                         */
    6784                 : /*                                                                      */
    6785                 : /*      Is the passed projection parameter an angular one?              */
    6786                 : /************************************************************************/
    6787                 : 
    6788            2131 : int OGRSpatialReference::IsAngularParameter( const char *pszParameterName )
    6789                 : 
    6790                 : {
    6791            2131 :     if( EQUALN(pszParameterName,"long",4)
    6792                 :         || EQUALN(pszParameterName,"lati",4)
    6793                 :         || EQUAL(pszParameterName,SRS_PP_CENTRAL_MERIDIAN)
    6794                 :         || EQUALN(pszParameterName,"standard_parallel",17)
    6795                 :         || EQUAL(pszParameterName,SRS_PP_AZIMUTH)
    6796                 :         || EQUAL(pszParameterName,SRS_PP_RECTIFIED_GRID_ANGLE) )
    6797             890 :         return TRUE;
    6798                 :     else
    6799            1241 :         return FALSE;
    6800                 : }
    6801                 : 
    6802                 : /************************************************************************/
    6803                 : /*                        IsLongitudeParameter()                        */
    6804                 : /*                                                                      */
    6805                 : /*      Is the passed projection parameter an angular longitude         */
    6806                 : /*      (relative to a prime meridian)?                                 */
    6807                 : /************************************************************************/
    6808                 : 
    6809               0 : int OGRSpatialReference::IsLongitudeParameter( const char *pszParameterName )
    6810                 : 
    6811                 : {
    6812               0 :     if( EQUALN(pszParameterName,"long",4)
    6813                 :         || EQUAL(pszParameterName,SRS_PP_CENTRAL_MERIDIAN) )
    6814               0 :         return TRUE;
    6815                 :     else
    6816               0 :         return FALSE;
    6817                 : }
    6818                 : 
    6819                 : /************************************************************************/
    6820                 : /*                         IsLinearParameter()                          */
    6821                 : /*                                                                      */
    6822                 : /*      Is the passed projection parameter an linear one measured in    */
    6823                 : /*      meters or some similar linear measure.                          */
    6824                 : /************************************************************************/
    6825                 : 
    6826           13433 : int OGRSpatialReference::IsLinearParameter( const char *pszParameterName )
    6827                 : 
    6828                 : {
    6829           13433 :     if( EQUALN(pszParameterName,"false_",6) 
    6830                 :         || EQUAL(pszParameterName,SRS_PP_SATELLITE_HEIGHT) )
    6831            4640 :         return TRUE;
    6832                 :     else
    6833            8793 :         return FALSE;
    6834                 : }
    6835                 : 
    6836                 : /************************************************************************/
    6837                 : /*                            GetNormInfo()                             */
    6838                 : /************************************************************************/
    6839                 : 
    6840                 : /**
    6841                 :  * \brief Set the internal information for normalizing linear, and angular values.
    6842                 :  */
    6843          109335 : void OGRSpatialReference::GetNormInfo(void) const
    6844                 : 
    6845                 : {
    6846          109335 :     if( bNormInfoSet )
    6847           82847 :         return;
    6848                 : 
    6849                 : /* -------------------------------------------------------------------- */
    6850                 : /*      Initialize values.                                              */
    6851                 : /* -------------------------------------------------------------------- */
    6852           26488 :     OGRSpatialReference *poThis = (OGRSpatialReference *) this;
    6853                 : 
    6854           26488 :     poThis->bNormInfoSet = TRUE;
    6855                 : 
    6856           26488 :     poThis->dfFromGreenwich = GetPrimeMeridian(NULL);
    6857           26488 :     poThis->dfToMeter = GetLinearUnits(NULL);
    6858           26488 :     poThis->dfToDegrees = GetAngularUnits(NULL) / CPLAtof(SRS_UA_DEGREE_CONV);
    6859           26488 :     if( fabs(poThis->dfToDegrees-1.0) < 0.000000001 )
    6860           26394 :         poThis->dfToDegrees = 1.0;
    6861                 : }
    6862                 : 
    6863                 : /************************************************************************/
    6864                 : /*                           FixupOrdering()                            */
    6865                 : /************************************************************************/
    6866                 : 
    6867                 : /**
    6868                 :  * \brief Correct parameter ordering to match CT Specification.
    6869                 :  *
    6870                 :  * Some mechanisms to create WKT using OGRSpatialReference, and some
    6871                 :  * imported WKT fail to maintain the order of parameters required according
    6872                 :  * to the BNF definitions in the OpenGIS SF-SQL and CT Specifications.  This
    6873                 :  * method attempts to massage things back into the required order.
    6874                 :  *
    6875                 :  * This method is the same as the C function OSRFixupOrdering().
    6876                 :  *
    6877                 :  * @return OGRERR_NONE on success or an error code if something goes 
    6878                 :  * wrong.  
    6879                 :  */
    6880                 : 
    6881           39328 : OGRErr OGRSpatialReference::FixupOrdering()
    6882                 : 
    6883                 : {
    6884           39328 :     if( GetRoot() != NULL )
    6885           39328 :         return GetRoot()->FixupOrdering();
    6886                 :     else
    6887               0 :         return OGRERR_NONE;
    6888                 : }
    6889                 : 
    6890                 : /************************************************************************/
    6891                 : /*                          OSRFixupOrdering()                          */
    6892                 : /************************************************************************/
    6893                 : 
    6894                 : /** 
    6895                 :  * \brief Correct parameter ordering to match CT Specification.
    6896                 :  *
    6897                 :  * This function is the same as OGRSpatialReference::FixupOrdering().
    6898                 :  */
    6899               0 : OGRErr OSRFixupOrdering( OGRSpatialReferenceH hSRS )
    6900                 : 
    6901                 : {
    6902               0 :     VALIDATE_POINTER1( hSRS, "OSRFixupOrdering", CE_Failure );
    6903                 : 
    6904               0 :     return ((OGRSpatialReference *) hSRS)->FixupOrdering();
    6905                 : }
    6906                 : 
    6907                 : /************************************************************************/
    6908                 : /*                               Fixup()                                */
    6909                 : /************************************************************************/
    6910                 : 
    6911                 : /**
    6912                 :  * \brief Fixup as needed.
    6913                 :  *
    6914                 :  * Some mechanisms to create WKT using OGRSpatialReference, and some
    6915                 :  * imported WKT, are not valid according to the OGC CT specification.  This
    6916                 :  * method attempts to fill in any missing defaults that are required, and
    6917                 :  * fixup ordering problems (using OSRFixupOrdering()) so that the resulting
    6918                 :  * WKT is valid. 
    6919                 :  *
    6920                 :  * This method should be expected to evolve over time to as problems are
    6921                 :  * discovered.  The following are amoung the fixup actions this method will
    6922                 :  * take:
    6923                 :  *
    6924                 :  * - Fixup the ordering of nodes to match the BNF WKT ordering, using
    6925                 :  * the FixupOrdering() method. 
    6926                 :  *
    6927                 :  * - Add missing linear or angular units nodes.  
    6928                 :  *
    6929                 :  * This method is the same as the C function OSRFixup().
    6930                 :  *
    6931                 :  * @return OGRERR_NONE on success or an error code if something goes 
    6932                 :  * wrong.  
    6933                 :  */
    6934                 : 
    6935           14966 : OGRErr OGRSpatialReference::Fixup()
    6936                 : 
    6937                 : {
    6938                 : /* -------------------------------------------------------------------- */
    6939                 : /*      Ensure linear units defaulted to METER if missing for PROJCS,   */
    6940                 : /*      GEOCCS or LOCAL_CS.                                             */
    6941                 : /* -------------------------------------------------------------------- */
    6942           14966 :     const OGR_SRSNode *poCS = GetAttrNode( "PROJCS" );
    6943                 : 
    6944           14966 :     if( poCS == NULL )
    6945            2710 :         poCS = GetAttrNode( "LOCAL_CS" );
    6946                 : 
    6947           14966 :     if( poCS == NULL )
    6948            2709 :         poCS = GetAttrNode( "GEOCCS" );
    6949                 : 
    6950           14966 :     if( poCS != NULL && poCS->FindChild( "UNIT" ) == -1 )
    6951              15 :         SetLinearUnits( SRS_UL_METER, 1.0 );
    6952                 : 
    6953                 : /* -------------------------------------------------------------------- */
    6954                 : /*      Ensure angular units defaulted to degrees on the GEOGCS.        */
    6955                 : /* -------------------------------------------------------------------- */
    6956           14966 :     poCS = GetAttrNode( "GEOGCS" );
    6957           14966 :     if( poCS != NULL && poCS->FindChild( "UNIT" ) == -1 )
    6958               0 :         SetAngularUnits( SRS_UA_DEGREE, CPLAtof(SRS_UA_DEGREE_CONV) );
    6959                 : 
    6960           14966 :     return FixupOrdering();
    6961                 : }
    6962                 : 
    6963                 : /************************************************************************/
    6964                 : /*                              OSRFixup()                              */
    6965                 : /************************************************************************/
    6966                 : 
    6967                 : /** 
    6968                 :  * \brief Fixup as needed.
    6969                 :  *
    6970                 :  * This function is the same as OGRSpatialReference::Fixup().
    6971                 :  */
    6972               1 : OGRErr OSRFixup( OGRSpatialReferenceH hSRS )
    6973                 : 
    6974                 : {
    6975               1 :     VALIDATE_POINTER1( hSRS, "OSRFixup", CE_Failure );
    6976                 : 
    6977               1 :     return ((OGRSpatialReference *) hSRS)->Fixup();
    6978                 : }
    6979                 : 
    6980                 : /************************************************************************/
    6981                 : /*                            GetExtension()                            */
    6982                 : /************************************************************************/
    6983                 : 
    6984                 : /**
    6985                 :  * \brief Fetch extension value.
    6986                 :  *
    6987                 :  * Fetch the value of the named EXTENSION item for the identified
    6988                 :  * target node.
    6989                 :  *
    6990                 :  * @param pszTargetKey the name or path to the parent node of the EXTENSION.
    6991                 :  * @param pszName the name of the extension being fetched.
    6992                 :  * @param pszDefault the value to return if the extension is not found.
    6993                 :  *
    6994                 :  * @return node value if successful or pszDefault on failure.
    6995                 :  */
    6996                 : 
    6997            5302 : const char *OGRSpatialReference::GetExtension( const char *pszTargetKey, 
    6998                 :                                                const char *pszName, 
    6999                 :                                                const char *pszDefault ) const
    7000                 : 
    7001                 : {
    7002                 : /* -------------------------------------------------------------------- */
    7003                 : /*      Find the target node.                                           */
    7004                 : /* -------------------------------------------------------------------- */
    7005                 :     const OGR_SRSNode  *poNode;
    7006                 : 
    7007            5302 :     if( pszTargetKey == NULL )
    7008               0 :         poNode = poRoot;
    7009                 :     else
    7010            5302 :         poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
    7011                 : 
    7012            5302 :     if( poNode == NULL )
    7013            1442 :         return NULL;
    7014                 : 
    7015                 : /* -------------------------------------------------------------------- */
    7016                 : /*      Fetch matching EXTENSION if there is one.                       */
    7017                 : /* -------------------------------------------------------------------- */
    7018           23743 :     for( int i = poNode->GetChildCount()-1; i >= 0; i-- )
    7019                 :     {
    7020           19976 :         const OGR_SRSNode *poChild = poNode->GetChild(i);
    7021                 : 
    7022           19976 :         if( EQUAL(poChild->GetValue(),"EXTENSION") 
    7023                 :             && poChild->GetChildCount() >= 2 )
    7024                 :         {
    7025             165 :             if( EQUAL(poChild->GetChild(0)->GetValue(),pszName) )
    7026              93 :                 return poChild->GetChild(1)->GetValue();
    7027                 :         }
    7028                 :     }
    7029                 : 
    7030            3767 :     return pszDefault;
    7031                 : }
    7032                 : 
    7033                 : /************************************************************************/
    7034                 : /*                            SetExtension()                            */
    7035                 : /************************************************************************/
    7036                 : /**
    7037                 :  * \brief Set extension value.
    7038                 :  *
    7039                 :  * Set the value of the named EXTENSION item for the identified
    7040                 :  * target node.
    7041                 :  *
    7042                 :  * @param pszTargetKey the name or path to the parent node of the EXTENSION.
    7043                 :  * @param pszName the name of the extension being fetched.
    7044                 :  * @param pszValue the value to set
    7045                 :  *
    7046                 :  * @return OGRERR_NONE on success
    7047                 :  */
    7048                 : 
    7049              80 : OGRErr OGRSpatialReference::SetExtension( const char *pszTargetKey, 
    7050                 :                                           const char *pszName, 
    7051                 :                                           const char *pszValue )
    7052                 : 
    7053                 : {
    7054                 : /* -------------------------------------------------------------------- */
    7055                 : /*      Find the target node.                                           */
    7056                 : /* -------------------------------------------------------------------- */
    7057                 :     OGR_SRSNode  *poNode;
    7058                 : 
    7059              80 :     if( pszTargetKey == NULL )
    7060               0 :         poNode = poRoot;
    7061                 :     else
    7062              80 :         poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
    7063                 : 
    7064              80 :     if( poNode == NULL )
    7065               0 :         return OGRERR_FAILURE;
    7066                 : 
    7067                 : /* -------------------------------------------------------------------- */
    7068                 : /*      Fetch matching EXTENSION if there is one.                       */
    7069                 : /* -------------------------------------------------------------------- */
    7070             684 :     for( int i = poNode->GetChildCount()-1; i >= 0; i-- )
    7071                 :     {
    7072             604 :         OGR_SRSNode *poChild = poNode->GetChild(i);
    7073                 :         
    7074             604 :         if( EQUAL(poChild->GetValue(),"EXTENSION") 
    7075                 :             && poChild->GetChildCount() >= 2 )
    7076                 :         {
    7077               0 :             if( EQUAL(poChild->GetChild(0)->GetValue(),pszName) )
    7078                 :             {
    7079               0 :                 poChild->GetChild(1)->SetValue( pszValue );
    7080               0 :                 return OGRERR_NONE;
    7081                 :             }
    7082                 :         }
    7083                 :     }
    7084                 : 
    7085                 : /* -------------------------------------------------------------------- */
    7086                 : /*      Create a new EXTENSION node.                                    */
    7087                 : /* -------------------------------------------------------------------- */
    7088                 :     OGR_SRSNode *poAuthNode;
    7089                 : 
    7090              80 :     poAuthNode = new OGR_SRSNode( "EXTENSION" );
    7091             160 :     poAuthNode->AddChild( new OGR_SRSNode( pszName ) );
    7092             160 :     poAuthNode->AddChild( new OGR_SRSNode( pszValue ) );
    7093                 :     
    7094              80 :     poNode->AddChild( poAuthNode );
    7095                 : 
    7096              80 :     return OGRERR_NONE;
    7097                 : }
    7098                 : 
    7099                 : /************************************************************************/
    7100                 : /*                             OSRCleanup()                             */
    7101                 : /************************************************************************/
    7102                 : 
    7103                 : CPL_C_START 
    7104                 : void CleanupESRIDatumMappingTable();
    7105                 : CPL_C_END
    7106                 : 
    7107                 : /**
    7108                 :  * \brief Cleanup cached SRS related memory.
    7109                 :  *
    7110                 :  * This function will attempt to cleanup any cache spatial reference
    7111                 :  * related information, such as cached tables of coordinate systems. 
    7112                 :  */
    7113            1035 : void OSRCleanup( void )
    7114                 : 
    7115                 : {
    7116            1035 :     CleanupESRIDatumMappingTable();
    7117            1035 :     CSVDeaccess( NULL );
    7118            1035 : }
    7119                 : 
    7120                 : /************************************************************************/
    7121                 : /*                              GetAxis()                               */
    7122                 : /************************************************************************/
    7123                 : 
    7124                 : /**
    7125                 :  * \brief Fetch the orientation of one axis.
    7126                 :  *
    7127                 :  * Fetches the the request axis (iAxis - zero based) from the
    7128                 :  * indicated portion of the coordinate system (pszTargetKey) which
    7129                 :  * should be either "GEOGCS" or "PROJCS". 
    7130                 :  *
    7131                 :  * No CPLError is issued on routine failures (such as not finding the AXIS).
    7132                 :  *
    7133                 :  * This method is equivalent to the C function OSRGetAxis().
    7134                 :  *
    7135                 :  * @param pszTargetKey the coordinate system part to query ("PROJCS" or "GEOGCS").
    7136                 :  * @param iAxis the axis to query (0 for first, 1 for second). 
    7137                 :  * @param peOrientation location into which to place the fetch orientation, may be NULL.
    7138                 :  *
    7139                 :  * @return the name of the axis or NULL on failure.
    7140                 :  */
    7141                 : 
    7142                 : const char *
    7143               1 : OGRSpatialReference::GetAxis( const char *pszTargetKey, int iAxis, 
    7144                 :                               OGRAxisOrientation *peOrientation ) const
    7145                 : 
    7146                 : {
    7147               1 :     if( peOrientation != NULL )
    7148               0 :         *peOrientation = OAO_Other;
    7149                 : 
    7150                 : /* -------------------------------------------------------------------- */
    7151                 : /*      Find the target node.                                           */
    7152                 : /* -------------------------------------------------------------------- */
    7153                 :     OGR_SRSNode  *poNode;
    7154                 : 
    7155               1 :     if( pszTargetKey == NULL )
    7156               1 :         poNode = poRoot;
    7157                 :     else
    7158               0 :         poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
    7159                 : 
    7160               1 :     if( poNode == NULL )
    7161               0 :         return NULL;
    7162                 : 
    7163                 : /* -------------------------------------------------------------------- */
    7164                 : /*      Find desired child AXIS.                                        */
    7165                 : /* -------------------------------------------------------------------- */
    7166               1 :     OGR_SRSNode *poAxis = NULL;
    7167               1 :     int iChild, nChildCount = poNode->GetChildCount();
    7168                 : 
    7169              10 :     for( iChild = 0; iChild < nChildCount; iChild++ )
    7170                 :     {
    7171              10 :         OGR_SRSNode *poChild = poNode->GetChild( iChild );
    7172                 : 
    7173              10 :         if( !EQUAL(poChild->GetValue(),"AXIS") )
    7174               9 :             continue;
    7175                 : 
    7176               1 :         if( iAxis == 0 )
    7177                 :         {
    7178               1 :             poAxis = poChild;
    7179               1 :             break;
    7180                 :         }
    7181               0 :         iAxis--;
    7182                 :     }
    7183                 : 
    7184               1 :     if( poAxis == NULL )
    7185               0 :         return NULL;
    7186                 : 
    7187               1 :     if( poAxis->GetChildCount() < 2 )
    7188               0 :         return NULL;
    7189                 : 
    7190                 : /* -------------------------------------------------------------------- */
    7191                 : /*      Extract name and orientation if possible.                       */
    7192                 : /* -------------------------------------------------------------------- */
    7193               1 :     if( peOrientation != NULL )
    7194                 :     {
    7195               0 :         const char *pszOrientation = poAxis->GetChild(1)->GetValue();
    7196                 : 
    7197               0 :         if( EQUAL(pszOrientation,"NORTH") )
    7198               0 :             *peOrientation = OAO_North;
    7199               0 :         else if( EQUAL(pszOrientation,"EAST") )
    7200               0 :             *peOrientation = OAO_East;
    7201               0 :         else if( EQUAL(pszOrientation,"SOUTH") )
    7202               0 :             *peOrientation = OAO_South;
    7203               0 :         else if( EQUAL(pszOrientation,"WEST") )
    7204               0 :             *peOrientation = OAO_West;
    7205               0 :         else if( EQUAL(pszOrientation,"UP") )
    7206               0 :             *peOrientation = OAO_Up;
    7207               0 :         else if( EQUAL(pszOrientation,"DOWN") )
    7208               0 :             *peOrientation = OAO_Down;
    7209               0 :         else if( EQUAL(pszOrientation,"OTHER") )
    7210               0 :             *peOrientation = OAO_Other;
    7211                 :         else
    7212                 :         {
    7213                 :             CPLDebug( "OSR", "Unrecognised orientation value '%s'.",
    7214               0 :                       pszOrientation );
    7215                 :         }
    7216                 :     }
    7217                 : 
    7218               1 :     return poAxis->GetChild(0)->GetValue();
    7219                 : }
    7220                 : 
    7221                 : /************************************************************************/
    7222                 : /*                             OSRGetAxis()                             */
    7223                 : /************************************************************************/
    7224                 : 
    7225                 : /**
    7226                 :  * \brief Fetch the orientation of one axis.
    7227                 :  *
    7228                 :  * This method is the equivalent of the C++ method OGRSpatialReference::GetAxis
    7229                 :  */
    7230               0 : const char *OSRGetAxis( OGRSpatialReferenceH hSRS,
    7231                 :                         const char *pszTargetKey, int iAxis, 
    7232                 :                         OGRAxisOrientation *peOrientation )
    7233                 : 
    7234                 : {
    7235               0 :     VALIDATE_POINTER1( hSRS, "OSRGetAxis", NULL );
    7236                 : 
    7237                 :     return ((OGRSpatialReference *) hSRS)->GetAxis( pszTargetKey, iAxis,
    7238               0 :                                                     peOrientation );
    7239                 : }
    7240                 : 
    7241                 : /************************************************************************/
    7242                 : /*                         OSRAxisEnumToName()                          */
    7243                 : /************************************************************************/
    7244                 : 
    7245                 : /**
    7246                 :  * \brief Return the string representation for the OGRAxisOrientation enumeration.
    7247                 :  *
    7248                 :  * For example "NORTH" for OAO_North.
    7249                 :  *
    7250                 :  * @return an internal string
    7251                 :  */
    7252          221814 : const char *OSRAxisEnumToName( OGRAxisOrientation eOrientation )
    7253                 : 
    7254                 : {
    7255          221814 :     if( eOrientation == OAO_North )
    7256           59408 :         return "NORTH";
    7257          162406 :     if( eOrientation == OAO_East )
    7258           59406 :         return "EAST";
    7259          103000 :     if( eOrientation == OAO_South )
    7260           20748 :         return "SOUTH";
    7261           82252 :     if( eOrientation == OAO_West )
    7262           20748 :         return "WEST";
    7263           61504 :     if( eOrientation == OAO_Up )
    7264           20500 :         return "UP";
    7265           41004 :     if( eOrientation == OAO_Down )
    7266           20500 :         return "DOWN";
    7267           20504 :     if( eOrientation == OAO_Other )
    7268           20504 :         return "OTHER";
    7269                 : 
    7270               0 :     return "UNKNOWN";
    7271                 : }
    7272                 : 
    7273                 : /************************************************************************/
    7274                 : /*                              SetAxes()                               */
    7275                 : /************************************************************************/
    7276                 : 
    7277                 : /**
    7278                 :  * \brief Set the axes for a coordinate system.
    7279                 :  *
    7280                 :  * Set the names, and orientations of the axes for either a projected 
    7281                 :  * (PROJCS) or geographic (GEOGCS) coordinate system.  
    7282                 :  *
    7283                 :  * This method is equivalent to the C function OSRSetAxes().
    7284                 :  *
    7285                 :  * @param pszTargetKey either "PROJCS" or "GEOGCS", must already exist in SRS.
    7286                 :  * @param pszXAxisName name of first axis, normally "Long" or "Easting". 
    7287                 :  * @param eXAxisOrientation normally OAO_East.
    7288                 :  * @param pszYAxisName name of second axis, normally "Lat" or "Northing". 
    7289                 :  * @param eYAxisOrientation normally OAO_North. 
    7290                 :  * 
    7291                 :  * @return OGRERR_NONE on success or an error code.
    7292                 :  */
    7293                 : 
    7294                 : OGRErr 
    7295           39154 : OGRSpatialReference::SetAxes( const char *pszTargetKey, 
    7296                 :                               const char *pszXAxisName, 
    7297                 :                               OGRAxisOrientation eXAxisOrientation,
    7298                 :                               const char *pszYAxisName, 
    7299                 :                               OGRAxisOrientation eYAxisOrientation )
    7300                 : 
    7301                 : {
    7302                 : /* -------------------------------------------------------------------- */
    7303                 : /*      Find the target node.                                           */
    7304                 : /* -------------------------------------------------------------------- */
    7305                 :     OGR_SRSNode  *poNode;
    7306                 : 
    7307           39154 :     if( pszTargetKey == NULL )
    7308               0 :         poNode = poRoot;
    7309                 :     else
    7310           39154 :         poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
    7311                 : 
    7312           39154 :     if( poNode == NULL )
    7313               0 :         return OGRERR_FAILURE;
    7314                 : 
    7315                 : /* -------------------------------------------------------------------- */
    7316                 : /*      Strip any existing AXIS children.                               */
    7317                 : /* -------------------------------------------------------------------- */
    7318           78308 :     while( poNode->FindChild( "AXIS" ) >= 0 )
    7319               0 :         poNode->DestroyChild( poNode->FindChild( "AXIS" ) );
    7320                 : 
    7321                 : /* -------------------------------------------------------------------- */
    7322                 : /*      Insert desired axes                                             */
    7323                 : /* -------------------------------------------------------------------- */
    7324           39154 :     OGR_SRSNode *poAxis = new OGR_SRSNode( "AXIS" );
    7325                 : 
    7326           78308 :     poAxis->AddChild( new OGR_SRSNode( pszXAxisName ) );
    7327           78308 :     poAxis->AddChild( new OGR_SRSNode( OSRAxisEnumToName(eXAxisOrientation) ));
    7328                 : 
    7329           39154 :     poNode->AddChild( poAxis );
    7330                 :     
    7331           78308 :     poAxis = new OGR_SRSNode( "AXIS" );
    7332                 : 
    7333           78308 :     poAxis->AddChild( new OGR_SRSNode( pszYAxisName ) );
    7334           78308 :     poAxis->AddChild( new OGR_SRSNode( OSRAxisEnumToName(eYAxisOrientation) ));
    7335                 : 
    7336           39154 :     poNode->AddChild( poAxis );
    7337                 : 
    7338           39154 :     return OGRERR_NONE;
    7339                 : }
    7340                 : 
    7341                 : /************************************************************************/
    7342                 : /*                             OSRSetAxes()                             */
    7343                 : /************************************************************************/
    7344                 : /**
    7345                 :  * \brief Set the axes for a coordinate system.
    7346                 :  *
    7347                 :  * This method is the equivalent of the C++ method OGRSpatialReference::SetAxes
    7348                 :  */
    7349               0 : OGRErr OSRSetAxes( OGRSpatialReferenceH hSRS,
    7350                 :                    const char *pszTargetKey, 
    7351                 :                    const char *pszXAxisName, 
    7352                 :                    OGRAxisOrientation eXAxisOrientation,
    7353                 :                    const char *pszYAxisName, 
    7354                 :                    OGRAxisOrientation eYAxisOrientation )
    7355                 : {
    7356               0 :     VALIDATE_POINTER1( hSRS, "OSRSetAxes", OGRERR_FAILURE );
    7357                 : 
    7358                 :     return ((OGRSpatialReference *) hSRS)->SetAxes( pszTargetKey,
    7359                 :                                                     pszXAxisName, 
    7360                 :                                                     eXAxisOrientation,
    7361                 :                                                     pszYAxisName, 
    7362               0 :                                                     eYAxisOrientation );
    7363                 : }
    7364                 : 
    7365                 : #ifdef HAVE_MITAB
    7366                 : char CPL_DLL *MITABSpatialRef2CoordSys( OGRSpatialReference * );
    7367                 : OGRSpatialReference CPL_DLL * MITABCoordSys2SpatialRef( const char * );
    7368                 : #endif
    7369                 : 
    7370                 : /************************************************************************/
    7371                 : /*                       OSRExportToMICoordSys()                        */
    7372                 : /************************************************************************/
    7373                 : /**
    7374                 :  * \brief Export coordinate system in Mapinfo style CoordSys format.
    7375                 :  *
    7376                 :  * This method is the equivalent of the C++ method OGRSpatialReference::exportToMICoordSys
    7377                 :  */
    7378               1 : OGRErr OSRExportToMICoordSys( OGRSpatialReferenceH hSRS, char ** ppszReturn )
    7379                 : 
    7380                 : {
    7381               1 :     VALIDATE_POINTER1( hSRS, "OSRExportToMICoordSys", CE_Failure );
    7382                 : 
    7383               1 :     *ppszReturn = NULL;
    7384                 : 
    7385               1 :     return ((OGRSpatialReference *) hSRS)->exportToMICoordSys( ppszReturn );
    7386                 : }
    7387                 : 
    7388                 : /************************************************************************/
    7389                 : /*                         exportToMICoordSys()                         */
    7390                 : /************************************************************************/
    7391                 : 
    7392                 : /**
    7393                 :  * \brief Export coordinate system in Mapinfo style CoordSys format.
    7394                 :  *
    7395                 :  * Note that the returned WKT string should be freed with OGRFree() or
    7396                 :  * CPLFree() when no longer needed.  It is the responsibility of the caller.
    7397                 :  *
    7398                 :  * This method is the same as the C function OSRExportToMICoordSys().
    7399                 :  *
    7400                 :  * @param ppszResult pointer to which dynamically allocated Mapinfo CoordSys
    7401                 :  * definition will be assigned.
    7402                 :  *
    7403                 :  * @return  OGRERR_NONE on success, OGRERR_FAILURE on failure,
    7404                 :  * OGRERR_UNSUPPORTED_OPERATION if MITAB library was not linked in.
    7405                 :  */
    7406                 :  
    7407               2 : OGRErr OGRSpatialReference::exportToMICoordSys( char **ppszResult ) const
    7408                 : 
    7409                 : {
    7410                 : #ifdef HAVE_MITAB
    7411               2 :     *ppszResult = MITABSpatialRef2CoordSys( (OGRSpatialReference *) this );
    7412               2 :     if( *ppszResult != NULL && strlen(*ppszResult) > 0 )
    7413               2 :         return OGRERR_NONE;
    7414                 :     else
    7415               0 :         return OGRERR_FAILURE;
    7416                 : #else
    7417                 :     CPLError( CE_Failure, CPLE_NotSupported,
    7418                 :               "MITAB not available, CoordSys support disabled." );
    7419                 : 
    7420                 :     return OGRERR_UNSUPPORTED_OPERATION;
    7421                 : #endif    
    7422                 : }
    7423                 : 
    7424                 : /************************************************************************/
    7425                 : /*                       OSRImportFromMICoordSys()                      */
    7426                 : /************************************************************************/
    7427                 : /**
    7428                 :  * \brief Import Mapinfo style CoordSys definition.
    7429                 :  *
    7430                 :  * This method is the equivalent of the C++ method OGRSpatialReference::importFromMICoordSys
    7431                 :  */
    7432                 : 
    7433               1 : OGRErr OSRImportFromMICoordSys( OGRSpatialReferenceH hSRS,
    7434                 :                                 const char *pszCoordSys )
    7435                 : 
    7436                 : {
    7437               1 :     VALIDATE_POINTER1( hSRS, "OSRImportFromMICoordSys", CE_Failure );
    7438                 : 
    7439               1 :     return ((OGRSpatialReference *)hSRS)->importFromMICoordSys( pszCoordSys );
    7440                 : }
    7441                 : 
    7442                 : /************************************************************************/
    7443                 : /*                        importFromMICoordSys()                        */
    7444                 : /************************************************************************/
    7445                 : 
    7446                 : /**
    7447                 :  * \brief Import Mapinfo style CoordSys definition.
    7448                 :  *
    7449                 :  * The OGRSpatialReference is initialized from the passed Mapinfo style CoordSys definition string.
    7450                 :  *
    7451                 :  * This method is the equivalent of the C function OSRImportFromMICoordSys().
    7452                 :  *
    7453                 :  * @param pszCoordSys Mapinfo style CoordSys definition string.
    7454                 :  *
    7455                 :  * @return OGRERR_NONE on success, OGRERR_FAILURE on failure,
    7456                 :  * OGRERR_UNSUPPORTED_OPERATION if MITAB library was not linked in.
    7457                 :  */
    7458                 : 
    7459               3 : OGRErr OGRSpatialReference::importFromMICoordSys( const char *pszCoordSys )
    7460                 : 
    7461                 : {
    7462                 : #ifdef HAVE_MITAB
    7463               3 :     OGRSpatialReference *poResult = MITABCoordSys2SpatialRef( pszCoordSys );
    7464                 : 
    7465               3 :     if( poResult == NULL )
    7466               0 :         return OGRERR_FAILURE;
    7467                 :     
    7468               3 :     *this = *poResult;
    7469               3 :     delete poResult;
    7470                 : 
    7471               3 :     return OGRERR_NONE;
    7472                 : #else
    7473                 :     CPLError( CE_Failure, CPLE_NotSupported,
    7474                 :               "MITAB not available, CoordSys support disabled." );
    7475                 : 
    7476                 :     return OGRERR_UNSUPPORTED_OPERATION;
    7477                 : #endif    
    7478                 : }

Generated by: LCOV version 1.7