LCOV - code coverage report
Current view: directory - ogr - ogrspatialreference.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 1920 1454 75.7 %
Date: 2011-12-18 Functions: 238 167 70.2 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrspatialreference.cpp 22974 2011-08-24 18:37:09Z 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 22974 2011-08-24 18:37:09Z 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          123391 : void OGRPrintDouble( char * pszStrBuf, double dfValue )
      49                 : 
      50                 : {
      51          123391 :     sprintf( pszStrBuf, "%.16g", dfValue );
      52                 : 
      53          123391 :     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          123391 :     if( nLen > 15 
      58                 :         && (strcmp(pszStrBuf+nLen-6,"999999") == 0
      59                 :             || strcmp(pszStrBuf+nLen-6,"000001") == 0) )
      60                 :     {
      61             825 :         sprintf( pszStrBuf, "%.15g", dfValue );
      62                 :     }
      63                 : 
      64                 :     // force to user periods regardless of locale.
      65          123391 :     if( strchr( pszStrBuf, ',' ) != NULL )
      66                 :     {
      67               0 :         char *pszDelim = strchr( pszStrBuf, ',' );
      68               0 :         *pszDelim = '.';
      69                 :     }
      70          123391 : }
      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           64294 : OGRSpatialReference::OGRSpatialReference( const char * pszWKT )
      93                 : 
      94                 : {
      95           64294 :     bNormInfoSet = FALSE;
      96           64294 :     nRefCount = 1;
      97           64294 :     poRoot = NULL;
      98                 : 
      99           64294 :     if( pszWKT != NULL )
     100            1690 :         importFromWkt( (char **) &pszWKT );
     101           64294 : }
     102                 : 
     103                 : /************************************************************************/
     104                 : /*                       OSRNewSpatialReference()                       */
     105                 : /************************************************************************/
     106                 : 
     107                 : /**
     108                 :  * \brief Constructor.
     109                 :  *
     110                 :  * This function is the same as OGRSpatialReference::OGRSpatialReference()
     111                 :  */
     112           15613 : OGRSpatialReferenceH CPL_STDCALL OSRNewSpatialReference( const char *pszWKT )
     113                 : 
     114                 : {
     115                 :     OGRSpatialReference * poSRS;
     116                 : 
     117           15613 :     poSRS = new OGRSpatialReference();
     118                 : 
     119           31175 :     if( pszWKT != NULL && strlen(pszWKT) > 0 )
     120                 :     {
     121             196 :         if( poSRS->importFromWkt( (char **) (&pszWKT) ) != OGRERR_NONE )
     122                 :         {
     123               0 :             delete poSRS;
     124               0 :             poSRS = NULL;
     125                 :         }
     126                 :     }
     127                 : 
     128           15613 :     return (OGRSpatialReferenceH) poSRS;
     129                 : }
     130                 : 
     131                 : /************************************************************************/
     132                 : /*                        OGRSpatialReference()                         */
     133                 : /*                                                                      */
     134                 : /*      Simple copy constructor.  See also Clone().                     */
     135                 : /************************************************************************/
     136                 : 
     137              85 : OGRSpatialReference::OGRSpatialReference(const OGRSpatialReference &oOther)
     138                 : 
     139                 : {
     140              85 :     bNormInfoSet = FALSE;
     141              85 :     nRefCount = 1;
     142              85 :     poRoot = NULL;
     143                 : 
     144              85 :     if( oOther.poRoot != NULL )
     145              85 :         poRoot = oOther.poRoot->Clone();
     146              85 : }
     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           64379 : OGRSpatialReference::~OGRSpatialReference()
     162                 : 
     163                 : {
     164           64379 :     if( poRoot != NULL )
     165           62116 :         delete poRoot;
     166           64379 : }
     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             130 : void OGRSpatialReference::DestroySpatialReference(OGRSpatialReference* poSRS)
     188                 : {
     189             130 :     delete poSRS;
     190             130 : }
     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           44134 : void CPL_STDCALL OSRDestroySpatialReference( OGRSpatialReferenceH hSRS )
     205                 : 
     206                 : {
     207           44134 :     delete ((OGRSpatialReference *) hSRS);
     208           44134 : }
     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           13484 : void OGRSpatialReference::Clear()
     222                 : 
     223                 : {
     224           13484 :     if( poRoot )
     225             872 :         delete poRoot;
     226                 : 
     227           13484 :     poRoot = NULL;
     228                 : 
     229           13484 :     bNormInfoSet = FALSE;
     230           13484 :     dfFromGreenwich = 1.0;
     231           13484 :     dfToMeter = 1.0;
     232           13484 :     dfToDegrees = 1.0;
     233           13484 : }
     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          629021 : int OGRSpatialReference::Reference()
     267                 : 
     268                 : {
     269          629021 :     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             161 : int OSRReference( OGRSpatialReferenceH hSRS )
     282                 : 
     283                 : {
     284             161 :     VALIDATE_POINTER1( hSRS, "OSRReference", 0 );
     285                 : 
     286             161 :     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          675934 : int OGRSpatialReference::Dereference()
     302                 : 
     303                 : {
     304          675934 :     if( nRefCount <= 0 )
     305                 :         CPLDebug( "OSR", 
     306                 :                   "Dereference() called on an object with refcount %d,"
     307                 :                   "likely already destroyed!", 
     308               0 :                   nRefCount );
     309          675934 :     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           44174 : int OSRDereference( OGRSpatialReferenceH hSRS )
     322                 : 
     323                 : {
     324           44174 :     VALIDATE_POINTER1( hSRS, "OSRDereference", 0 );
     325                 : 
     326           44174 :     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          631069 : void OGRSpatialReference::Release()
     352                 : 
     353                 : {
     354          631069 :     CPLAssert( NULL != this );
     355                 : 
     356          631069 :     if( Dereference() <= 0 ) 
     357            2415 :         delete this;
     358          631069 : }
     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           25581 : void OGRSpatialReference::SetRoot( OGR_SRSNode * poNewRoot )
     392                 : 
     393                 : {
     394           25581 :     if( poRoot != NULL )
     395               1 :         delete poRoot;
     396                 : 
     397           25581 :     poRoot = poNewRoot;
     398           25581 : }
     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         1351459 : OGR_SRSNode *OGRSpatialReference::GetAttrNode( const char * pszNodePath )
     423                 : 
     424                 : {
     425                 :     char        **papszPathTokens;
     426                 :     OGR_SRSNode *poNode;
     427                 : 
     428         1351459 :     papszPathTokens = CSLTokenizeStringComplex(pszNodePath, "|", TRUE, FALSE);
     429                 : 
     430         1351459 :     if( CSLCount( papszPathTokens ) < 1 )
     431                 :     {
     432               0 :         CSLDestroy(papszPathTokens);
     433               0 :         return NULL;
     434                 :     }
     435                 : 
     436         1351459 :     poNode = GetRoot();
     437         2834670 :     for( int i = 0; poNode != NULL && papszPathTokens[i] != NULL; i++ )
     438                 :     {
     439         1483211 :         poNode = poNode->GetNode( papszPathTokens[i] );
     440                 :     }
     441                 : 
     442         1351459 :     CSLDestroy( papszPathTokens );
     443                 : 
     444         1351459 :     return poNode;
     445                 : }
     446                 : 
     447                 : const OGR_SRSNode *
     448          800459 : OGRSpatialReference::GetAttrNode( const char * pszNodePath ) const
     449                 : 
     450                 : {
     451                 :     OGR_SRSNode *poNode;
     452                 : 
     453          800459 :     poNode = ((OGRSpatialReference *) this)->GetAttrNode(pszNodePath);
     454                 : 
     455          800459 :     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          400665 : const char *OGRSpatialReference::GetAttrValue( const char * pszNodeName,
     479                 :                                                int iAttr ) const
     480                 : 
     481                 : {
     482                 :     const OGR_SRSNode *poNode;
     483                 : 
     484          400665 :     poNode = GetAttrNode( pszNodeName );
     485          400665 :     if( poNode == NULL )
     486           20526 :         return NULL;
     487                 : 
     488          380139 :     if( iAttr < 0 || iAttr >= poNode->GetChildCount() )
     489               0 :         return NULL;
     490                 : 
     491          380139 :     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           20272 : const char * CPL_STDCALL OSRGetAttrValue( OGRSpatialReferenceH hSRS,
     504                 :                              const char * pszKey, int iChild )
     505                 : 
     506                 : {
     507           20272 :     VALIDATE_POINTER1( hSRS, "OSRGetAttrValue", NULL );
     508                 : 
     509           20272 :     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           29373 : OGRSpatialReference *OGRSpatialReference::Clone() const
     525                 : 
     526                 : {
     527                 :     OGRSpatialReference *poNewRef;
     528                 : 
     529           29373 :     poNewRef = new OGRSpatialReference();
     530                 : 
     531           29373 :     if( poRoot != NULL )
     532           29373 :         poNewRef->poRoot = poRoot->Clone();
     533                 : 
     534           29373 :     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           28486 : OGRSpatialReferenceH CPL_STDCALL OSRClone( OGRSpatialReferenceH hSRS )
     547                 : 
     548                 : {
     549           28486 :     VALIDATE_POINTER1( hSRS, "OSRClone", NULL );
     550                 : 
     551           28486 :     return (OGRSpatialReferenceH) ((OGRSpatialReference *) hSRS)->Clone();
     552                 : }
     553                 : 
     554                 : /************************************************************************/
     555                 : /*                         exportToPrettyWkt()                          */
     556                 : /************************************************************************/
     557                 : 
     558                 : /**
     559                 :  * Convert this SRS into a a nicely formatted WKT string for display to a person.
     560                 :  *
     561                 :  * Note that the returned WKT string should be freed with OGRFree() or
     562                 :  * CPLFree() when no longer needed.  It is the responsibility of the caller.
     563                 :  *
     564                 :  * This method is the same as the C function OSRExportToPrettyWkt().
     565                 :  *
     566                 :  * @param ppszResult the resulting string is returned in this pointer.
     567                 :  * @param bSimplify TRUE if the AXIS, AUTHORITY and EXTENSION nodes should be stripped off
     568                 :  *
     569                 :  * @return currently OGRERR_NONE is always returned, but the future it
     570                 :  * is possible error conditions will develop. 
     571                 :  */
     572                 : 
     573              66 : OGRErr OGRSpatialReference::exportToPrettyWkt( char ** ppszResult, 
     574                 :                                                int bSimplify ) const
     575                 : 
     576                 : {
     577              66 :     if( poRoot == NULL )
     578                 :     {
     579               0 :         *ppszResult = CPLStrdup("");
     580               0 :         return OGRERR_NONE;
     581                 :     }
     582                 : 
     583              66 :     if( bSimplify )
     584                 :     {
     585               1 :         OGRSpatialReference *poSimpleClone = Clone();
     586                 :         OGRErr eErr;
     587                 : 
     588               1 :         poSimpleClone->GetRoot()->StripNodes( "AXIS" );
     589               1 :         poSimpleClone->GetRoot()->StripNodes( "AUTHORITY" );
     590               1 :         poSimpleClone->GetRoot()->StripNodes( "EXTENSION" );
     591               1 :         eErr = poSimpleClone->GetRoot()->exportToPrettyWkt( ppszResult, 1 );
     592               1 :         delete poSimpleClone;
     593               1 :         return eErr;
     594                 :     }
     595                 :     else
     596              65 :         return poRoot->exportToPrettyWkt( ppszResult, 1 );
     597                 : }
     598                 : 
     599                 : /************************************************************************/
     600                 : /*                        OSRExportToPrettyWkt()                        */
     601                 : /************************************************************************/
     602                 : 
     603                 : 
     604                 : /**
     605                 :  * \brief Convert this SRS into a a nicely formatted WKT string for display to a person.
     606                 :  *
     607                 :  * This function is the same as OGRSpatialReference::exportToPrettyWkt().
     608                 :  */
     609                 : 
     610              53 : OGRErr CPL_STDCALL OSRExportToPrettyWkt( OGRSpatialReferenceH hSRS, char ** ppszReturn,
     611                 :                              int bSimplify)
     612                 : 
     613                 : {
     614              53 :     VALIDATE_POINTER1( hSRS, "OSRExportToPrettyWkt", CE_Failure );
     615                 : 
     616              53 :     *ppszReturn = NULL;
     617                 : 
     618                 :     return ((OGRSpatialReference *) hSRS)->exportToPrettyWkt( ppszReturn,
     619              53 :                                                               bSimplify );
     620                 : }
     621                 : 
     622                 : /************************************************************************/
     623                 : /*                            exportToWkt()                             */
     624                 : /************************************************************************/
     625                 : 
     626                 : /**
     627                 :  * \brief Convert this SRS into WKT format.
     628                 :  *
     629                 :  * Note that the returned WKT string should be freed with OGRFree() or
     630                 :  * CPLFree() when no longer needed.  It is the responsibility of the caller.
     631                 :  *
     632                 :  * This method is the same as the C function OSRExportToWkt().
     633                 :  *
     634                 :  * @param ppszResult the resulting string is returned in this pointer.
     635                 :  *
     636                 :  * @return currently OGRERR_NONE is always returned, but the future it
     637                 :  * is possible error conditions will develop. 
     638                 :  */
     639                 :  
     640           67336 : OGRErr OGRSpatialReference::exportToWkt( char ** ppszResult ) const
     641                 : 
     642                 : {
     643           67336 :     if( poRoot == NULL )
     644                 :     {
     645              63 :         *ppszResult = CPLStrdup("");
     646              63 :         return OGRERR_NONE;
     647                 :     }
     648                 :     else
     649                 :     {
     650           67273 :         return poRoot->exportToWkt(ppszResult);
     651                 :     }
     652                 : }
     653                 : 
     654                 : /************************************************************************/
     655                 : /*                           OSRExportToWkt()                           */
     656                 : /************************************************************************/
     657                 : 
     658                 : /** 
     659                 :  * \brief Convert this SRS into WKT format.
     660                 :  *
     661                 :  * This function is the same as OGRSpatialReference::exportToWkt().
     662                 :  */
     663                 : 
     664           60444 : OGRErr CPL_STDCALL OSRExportToWkt( OGRSpatialReferenceH hSRS,
     665                 :                                    char ** ppszReturn )
     666                 : 
     667                 : {
     668           60444 :     VALIDATE_POINTER1( hSRS, "OSRExportToWkt", CE_Failure );
     669                 : 
     670           60444 :     *ppszReturn = NULL;
     671                 : 
     672           60444 :     return ((OGRSpatialReference *) hSRS)->exportToWkt( ppszReturn );
     673                 : }
     674                 : 
     675                 : /************************************************************************/
     676                 : /*                           importFromWkt()                            */
     677                 : /************************************************************************/
     678                 : 
     679                 : /**
     680                 :  * \brief Import from WKT string.
     681                 :  *
     682                 :  * This method will wipe the existing SRS definition, and
     683                 :  * reassign it based on the contents of the passed WKT string.  Only as
     684                 :  * much of the input string as needed to construct this SRS is consumed from
     685                 :  * the input string, and the input string pointer
     686                 :  * is then updated to point to the remaining (unused) input.
     687                 :  *
     688                 :  * This method is the same as the C function OSRImportFromWkt().
     689                 :  *
     690                 :  * @param ppszInput Pointer to pointer to input.  The pointer is updated to
     691                 :  * point to remaining unused input text.
     692                 :  *
     693                 :  * @return OGRERR_NONE if import succeeds, or OGRERR_CORRUPT_DATA if it
     694                 :  * fails for any reason.
     695                 :  */
     696                 : 
     697           12278 : OGRErr OGRSpatialReference::importFromWkt( char ** ppszInput )
     698                 : 
     699                 : {
     700           12278 :     if ( !ppszInput || !*ppszInput )
     701               1 :         return OGRERR_FAILURE;
     702                 : 
     703           12277 :     Clear();
     704                 : 
     705           12277 :     poRoot = new OGR_SRSNode();
     706                 : 
     707           12277 :     OGRErr eErr = poRoot->importFromWkt( ppszInput ); 
     708           12277 :     if (eErr != OGRERR_NONE)
     709              18 :         return eErr;
     710                 : 
     711                 : /* -------------------------------------------------------------------- */
     712                 : /*      The following seems to try and detect and unconsumed            */
     713                 : /*      VERTCS[] coordinate system definition (ESRI style) and to       */
     714                 : /*      import and attach it to the existing root.  Likely we will      */
     715                 : /*      need to extend this somewhat to bring it into an acceptable     */
     716                 : /*      OGRSpatialReference organization at some point.                 */
     717                 : /* -------------------------------------------------------------------- */
     718           12259 :     if (strlen(*ppszInput) > 0 && strstr(*ppszInput, "VERTCS"))
     719                 :     {
     720               0 :         if(((*ppszInput)[0]) == ',')
     721               0 :             (*ppszInput)++;
     722               0 :         OGR_SRSNode *poNewChild = new OGR_SRSNode();
     723               0 :         poRoot->AddChild( poNewChild );
     724               0 :         return poNewChild->importFromWkt( ppszInput );
     725                 :     }
     726                 : 
     727           12259 :     return eErr;
     728                 : }
     729                 : 
     730                 : /************************************************************************/
     731                 : /*                          OSRImportFromWkt()                          */
     732                 : /************************************************************************/
     733                 : 
     734                 : /**
     735                 :  * \brief Import from WKT string.
     736                 :  *
     737                 :  * This function is the same as OGRSpatialReference::importFromWkt().
     738                 :  */
     739                 : 
     740            6038 : OGRErr OSRImportFromWkt( OGRSpatialReferenceH hSRS, char **ppszInput )
     741                 : 
     742                 : {
     743            6038 :     VALIDATE_POINTER1( hSRS, "OSRImportFromWkt", CE_Failure );
     744                 : 
     745            6038 :     return ((OGRSpatialReference *) hSRS)->importFromWkt( ppszInput );
     746                 : }
     747                 : 
     748                 : /************************************************************************/
     749                 : /*                              SetNode()                               */
     750                 : /************************************************************************/
     751                 : 
     752                 : /**
     753                 :  * \brief Set attribute value in spatial reference.
     754                 :  *
     755                 :  * Missing intermediate nodes in the path will be created if not already
     756                 :  * in existance.  If the attribute has no children one will be created and
     757                 :  * assigned the value otherwise the zeroth child will be assigned the value.
     758                 :  *
     759                 :  * This method does the same as the C function OSRSetAttrValue(). 
     760                 :  *
     761                 :  * @param pszNodePath full path to attribute to be set.  For instance
     762                 :  * "PROJCS|GEOGCS|UNIT".
     763                 :  * 
     764                 :  * @param pszNewNodeValue value to be assigned to node, such as "meter". 
     765                 :  * This may be NULL if you just want to force creation of the intermediate
     766                 :  * path.
     767                 :  *
     768                 :  * @return OGRERR_NONE on success. 
     769                 :  */
     770                 : 
     771           28850 : OGRErr OGRSpatialReference::SetNode( const char * pszNodePath,
     772                 :                                      const char * pszNewNodeValue )
     773                 : 
     774                 : {
     775                 :     char        **papszPathTokens;
     776                 :     int         i;
     777                 :     OGR_SRSNode *poNode;
     778                 : 
     779           28850 :     papszPathTokens = CSLTokenizeStringComplex(pszNodePath, "|", TRUE, FALSE);
     780                 : 
     781           28850 :     if( CSLCount( papszPathTokens ) < 1 )
     782               0 :         return OGRERR_FAILURE;
     783                 : 
     784           28850 :     if( GetRoot() == NULL || !EQUAL(papszPathTokens[0],GetRoot()->GetValue()) )
     785                 :     {
     786           12565 :         SetRoot( new OGR_SRSNode( papszPathTokens[0] ) );
     787                 :     }
     788                 : 
     789           28850 :     poNode = GetRoot();
     790           44916 :     for( i = 1; papszPathTokens[i] != NULL; i++ )
     791                 :     {
     792                 :         int     j;
     793                 :         
     794           59642 :         for( j = 0; j < poNode->GetChildCount(); j++ )
     795                 :         {
     796           47261 :             if( EQUAL(poNode->GetChild( j )->GetValue(),papszPathTokens[i]) )
     797                 :             {
     798            3685 :                 poNode = poNode->GetChild(j);
     799            3685 :                 j = -1;
     800            3685 :                 break;
     801                 :             }
     802                 :         }
     803                 : 
     804           16066 :         if( j != -1 )
     805                 :         {
     806           12381 :             OGR_SRSNode *poNewNode = new OGR_SRSNode( papszPathTokens[i] );
     807           12381 :             poNode->AddChild( poNewNode );
     808           12381 :             poNode = poNewNode;
     809                 :         }
     810                 :     }
     811                 : 
     812           28850 :     CSLDestroy( papszPathTokens );
     813                 : 
     814           28850 :     if( pszNewNodeValue != NULL )
     815                 :     {
     816           28850 :         if( poNode->GetChildCount() > 0 )
     817            3904 :             poNode->GetChild(0)->SetValue( pszNewNodeValue );
     818                 :         else
     819           24946 :             poNode->AddChild( new OGR_SRSNode( pszNewNodeValue ) );
     820                 :     }
     821                 : 
     822           28850 :     return OGRERR_NONE;
     823                 : }
     824                 : 
     825                 : /************************************************************************/
     826                 : /*                          OSRSetAttrValue()                           */
     827                 : /************************************************************************/
     828                 : 
     829                 : /**
     830                 :  * \brief Set attribute value in spatial reference.
     831                 :  *
     832                 :  * This function is the same as OGRSpatialReference::SetNode()
     833                 :  */
     834             622 : OGRErr CPL_STDCALL OSRSetAttrValue( OGRSpatialReferenceH hSRS, 
     835                 :                         const char * pszPath, const char * pszValue )
     836                 : 
     837                 : {
     838             622 :     VALIDATE_POINTER1( hSRS, "OSRSetAttrValue", CE_Failure );
     839                 : 
     840             622 :     return ((OGRSpatialReference *) hSRS)->SetNode( pszPath, pszValue );
     841                 : }
     842                 : 
     843                 : /************************************************************************/
     844                 : /*                              SetNode()                               */
     845                 : /************************************************************************/
     846                 : 
     847               0 : OGRErr OGRSpatialReference::SetNode( const char *pszNodePath,
     848                 :                                      double dfValue )
     849                 : 
     850                 : {
     851                 :     char        szValue[64];
     852                 : 
     853               0 :     if( ABS(dfValue - (int) dfValue) == 0.0 )
     854               0 :         sprintf( szValue, "%d", (int) dfValue );
     855                 :     else
     856               0 :         OGRPrintDouble( szValue, dfValue );
     857                 : 
     858               0 :     return SetNode( pszNodePath, szValue );
     859                 : }
     860                 : 
     861                 : /************************************************************************/
     862                 : /*                          SetAngularUnits()                           */
     863                 : /************************************************************************/
     864                 : 
     865                 : /**
     866                 :  * \brief Set the angular units for the geographic coordinate system.
     867                 :  *
     868                 :  * This method creates a UNIT subnode with the specified values as a
     869                 :  * child of the GEOGCS node. 
     870                 :  *
     871                 :  * This method does the same as the C function OSRSetAngularUnits(). 
     872                 :  *
     873                 :  * @param pszUnitsName the units name to be used.  Some preferred units
     874                 :  * names can be found in ogr_srs_api.h such as SRS_UA_DEGREE. 
     875                 :  *
     876                 :  * @param dfInRadians the value to multiple by an angle in the indicated
     877                 :  * units to transform to radians.  Some standard conversion factors can
     878                 :  * be found in ogr_srs_api.h. 
     879                 :  *
     880                 :  * @return OGRERR_NONE on success.
     881                 :  */
     882                 : 
     883               0 : OGRErr OGRSpatialReference::SetAngularUnits( const char * pszUnitsName,
     884                 :                                              double dfInRadians )
     885                 : 
     886                 : {
     887                 :     OGR_SRSNode *poCS;
     888                 :     OGR_SRSNode *poUnits;
     889                 :     char        szValue[128];
     890                 : 
     891               0 :     bNormInfoSet = FALSE;
     892                 : 
     893               0 :     poCS = GetAttrNode( "GEOGCS" );
     894                 : 
     895               0 :     if( poCS == NULL )
     896               0 :         return OGRERR_FAILURE;
     897                 : 
     898               0 :     OGRPrintDouble( szValue, dfInRadians );
     899                 : 
     900               0 :     if( poCS->FindChild( "UNIT" ) >= 0 )
     901                 :     {
     902               0 :         poUnits = poCS->GetChild( poCS->FindChild( "UNIT" ) );
     903               0 :         if (poUnits->GetChildCount() < 2)
     904               0 :             return OGRERR_FAILURE;
     905               0 :         poUnits->GetChild(0)->SetValue( pszUnitsName );
     906               0 :         poUnits->GetChild(1)->SetValue( szValue );
     907                 :     }
     908                 :     else
     909                 :     {
     910               0 :         poUnits = new OGR_SRSNode( "UNIT" );
     911               0 :         poUnits->AddChild( new OGR_SRSNode( pszUnitsName ) );
     912               0 :         poUnits->AddChild( new OGR_SRSNode( szValue ) );
     913                 :         
     914               0 :         poCS->AddChild( poUnits );
     915                 :     }
     916                 : 
     917               0 :     return OGRERR_NONE;
     918                 : }
     919                 : 
     920                 : /************************************************************************/
     921                 : /*                         OSRSetAngularUnits()                         */
     922                 : /************************************************************************/
     923                 : 
     924                 : /**
     925                 :  * \brief Set the angular units for the geographic coordinate system.
     926                 :  *
     927                 :  * This function is the same as OGRSpatialReference::SetAngularUnits()
     928                 :  */
     929               0 : OGRErr OSRSetAngularUnits( OGRSpatialReferenceH hSRS, 
     930                 :                            const char * pszUnits, double dfInRadians )
     931                 : 
     932                 : {
     933               0 :     VALIDATE_POINTER1( hSRS, "OSRSetAngularUnits", CE_Failure );
     934                 : 
     935                 :     return ((OGRSpatialReference *) hSRS)->SetAngularUnits( pszUnits, 
     936               0 :                                                             dfInRadians );
     937                 : }
     938                 : 
     939                 : /************************************************************************/
     940                 : /*                          GetAngularUnits()                           */
     941                 : /************************************************************************/
     942                 : 
     943                 : /**
     944                 :  * \brief Fetch angular geographic coordinate system units.
     945                 :  *
     946                 :  * If no units are available, a value of "degree" and SRS_UA_DEGREE_CONV 
     947                 :  * will be assumed.  This method only checks directly under the GEOGCS node
     948                 :  * for units.
     949                 :  *
     950                 :  * This method does the same thing as the C function OSRGetAngularUnits().
     951                 :  *
     952                 :  * @param ppszName a pointer to be updated with the pointer to the 
     953                 :  * units name.  The returned value remains internal to the OGRSpatialReference
     954                 :  * and shouldn't be freed, or modified.  It may be invalidated on the next
     955                 :  * OGRSpatialReference call. 
     956                 :  *
     957                 :  * @return the value to multiply by angular distances to transform them to 
     958                 :  * radians.
     959                 :  */
     960                 : 
     961           51435 : double OGRSpatialReference::GetAngularUnits( char ** ppszName ) const
     962                 : 
     963                 : {
     964           51435 :     const OGR_SRSNode *poCS = GetAttrNode( "GEOGCS" );
     965                 : 
     966           51435 :     if( ppszName != NULL )
     967             893 :         *ppszName = (char* ) "degree";
     968                 :         
     969           51435 :     if( poCS == NULL )
     970             313 :         return CPLAtof(SRS_UA_DEGREE_CONV);
     971                 : 
     972          204486 :     for( int iChild = 0; iChild < poCS->GetChildCount(); iChild++ )
     973                 :     {
     974          204484 :         const OGR_SRSNode     *poChild = poCS->GetChild(iChild);
     975                 :         
     976          204484 :         if( EQUAL(poChild->GetValue(),"UNIT")
     977                 :             && poChild->GetChildCount() >= 2 )
     978                 :         {
     979           51120 :             if( ppszName != NULL )
     980             891 :                 *ppszName = (char *) poChild->GetChild(0)->GetValue();
     981                 :             
     982           51120 :             return CPLAtof( poChild->GetChild(1)->GetValue() );
     983                 :         }
     984                 :     }
     985                 : 
     986               2 :     return 1.0;
     987                 : }
     988                 : 
     989                 : /************************************************************************/
     990                 : /*                         OSRGetAngularUnits()                         */
     991                 : /************************************************************************/
     992                 : 
     993                 : /**
     994                 :  * \brief Fetch angular geographic coordinate system units.
     995                 :  *
     996                 :  * This function is the same as OGRSpatialReference::GetAngularUnits()
     997                 :  */
     998               0 : double OSRGetAngularUnits( OGRSpatialReferenceH hSRS, char ** ppszName )
     999                 :     
    1000                 : {
    1001               0 :     VALIDATE_POINTER1( hSRS, "OSRGetAngularUnits", 0 );
    1002                 : 
    1003               0 :     return ((OGRSpatialReference *) hSRS)->GetAngularUnits( ppszName );
    1004                 : }
    1005                 : 
    1006                 : /************************************************************************/
    1007                 : /*                 SetLinearUnitsAndUpdateParameters()                  */
    1008                 : /************************************************************************/
    1009                 : 
    1010                 : /**
    1011                 :  * \brief Set the linear units for the projection.
    1012                 :  *
    1013                 :  * This method creates a UNIT subnode with the specified values as a
    1014                 :  * child of the PROJCS or LOCAL_CS node.   It works the same as the
    1015                 :  * SetLinearUnits() method, but it also updates all existing linear
    1016                 :  * projection parameter values from the old units to the new units. 
    1017                 :  *
    1018                 :  * @param pszName the units name to be used.  Some preferred units
    1019                 :  * names can be found in ogr_srs_api.h such as SRS_UL_METER, SRS_UL_FOOT 
    1020                 :  * and SRS_UL_US_FOOT. 
    1021                 :  *
    1022                 :  * @param dfInMeters the value to multiple by a length in the indicated
    1023                 :  * units to transform to meters.  Some standard conversion factors can
    1024                 :  * be found in ogr_srs_api.h. 
    1025                 :  *
    1026                 :  * @return OGRERR_NONE on success.
    1027                 :  */
    1028                 : 
    1029              20 : OGRErr OGRSpatialReference::SetLinearUnitsAndUpdateParameters(
    1030                 :     const char *pszName, double dfInMeters )
    1031                 : 
    1032                 : {
    1033              20 :     double dfOldInMeters = GetLinearUnits();
    1034              20 :     OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
    1035                 : 
    1036              20 :     if( dfInMeters == 0.0 )
    1037               0 :         return OGRERR_FAILURE;
    1038                 : 
    1039              20 :     if( dfInMeters == dfOldInMeters || poPROJCS == NULL )
    1040              16 :         return SetLinearUnits( pszName, dfInMeters );
    1041                 : 
    1042              52 :     for( int iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
    1043                 :     {
    1044              48 :         const OGR_SRSNode     *poChild = poPROJCS->GetChild(iChild);
    1045                 :         
    1046              48 :         if( EQUAL(poChild->GetValue(),"PARAMETER")
    1047                 :             && poChild->GetChildCount() > 1 )
    1048                 :         {
    1049              23 :             char *pszParmName = CPLStrdup(poChild->GetChild(0)->GetValue());
    1050                 :             
    1051              23 :             if( IsLinearParameter( pszParmName ) )
    1052                 :             {
    1053               8 :                 double dfOldValue = GetProjParm( pszParmName );
    1054                 : 
    1055                 :                 SetProjParm( pszParmName, 
    1056               8 :                              dfOldValue * dfOldInMeters / dfInMeters );
    1057                 :             }
    1058                 : 
    1059              23 :             CPLFree( pszParmName );
    1060                 :         }
    1061                 :     }
    1062                 : 
    1063               4 :     return SetLinearUnits( pszName, dfInMeters );
    1064                 : }
    1065                 : 
    1066                 : /************************************************************************/
    1067                 : /*                OSRSetLinearUnitsAndUpdateParameters()                */
    1068                 : /************************************************************************/
    1069                 : 
    1070                 : /**
    1071                 :  * \brief Set the linear units for the projection.
    1072                 :  *
    1073                 :  * This function is the same as OGRSpatialReference::SetLinearUnitsAndUpdateParameters()
    1074                 :  */
    1075               1 : OGRErr OSRSetLinearUnitsAndUpdateParameters( OGRSpatialReferenceH hSRS, 
    1076                 :                                              const char * pszUnits, 
    1077                 :                                              double dfInMeters )
    1078                 : 
    1079                 : {
    1080               1 :     VALIDATE_POINTER1( hSRS, "OSRSetLinearUnitsAndUpdateParameters", 
    1081                 :                        CE_Failure );
    1082                 : 
    1083                 :     return ((OGRSpatialReference *) hSRS)->
    1084               1 :         SetLinearUnitsAndUpdateParameters( pszUnits, dfInMeters );
    1085                 : }
    1086                 : 
    1087                 : /************************************************************************/
    1088                 : /*                           SetLinearUnits()                           */
    1089                 : /************************************************************************/
    1090                 : 
    1091                 : /**
    1092                 :  * \brief Set the linear units for the projection.
    1093                 :  *
    1094                 :  * This method creates a UNIT subnode with the specified values as a
    1095                 :  * child of the PROJCS, GEOCCS or LOCAL_CS node. 
    1096                 :  *
    1097                 :  * This method does the same as the C function OSRSetLinearUnits(). 
    1098                 :  *
    1099                 :  * @param pszUnitsName the units name to be used.  Some preferred units
    1100                 :  * names can be found in ogr_srs_api.h such as SRS_UL_METER, SRS_UL_FOOT 
    1101                 :  * and SRS_UL_US_FOOT. 
    1102                 :  *
    1103                 :  * @param dfInMeters the value to multiple by a length in the indicated
    1104                 :  * units to transform to meters.  Some standard conversion factors can
    1105                 :  * be found in ogr_srs_api.h. 
    1106                 :  *
    1107                 :  * @return OGRERR_NONE on success.
    1108                 :  */
    1109                 : 
    1110           12560 : OGRErr OGRSpatialReference::SetLinearUnits( const char * pszUnitsName,
    1111                 :                                             double dfInMeters )
    1112                 : 
    1113                 : {
    1114           12560 :     return SetTargetLinearUnits( NULL, pszUnitsName, dfInMeters );
    1115                 : }
    1116                 : 
    1117                 : /************************************************************************/
    1118                 : /*                         OSRSetLinearUnits()                          */
    1119                 : /************************************************************************/
    1120                 : 
    1121                 : /**
    1122                 :  * \brief Set the linear units for the projection.
    1123                 :  *
    1124                 :  * This function is the same as OGRSpatialReference::SetLinearUnits()
    1125                 :  */
    1126               2 : OGRErr OSRSetLinearUnits( OGRSpatialReferenceH hSRS, 
    1127                 :                           const char * pszUnits, double dfInMeters )
    1128                 : 
    1129                 : {
    1130               2 :     VALIDATE_POINTER1( hSRS, "OSRSetLinearUnits", CE_Failure );
    1131                 : 
    1132                 :     return ((OGRSpatialReference *) hSRS)->SetLinearUnits( pszUnits, 
    1133               2 :                                                            dfInMeters );
    1134                 : }
    1135                 : 
    1136                 : /************************************************************************/
    1137                 : /*                        SetTargetLinearUnits()                        */
    1138                 : /************************************************************************/
    1139                 : 
    1140                 : /**
    1141                 :  * \brief Set the linear units for the projection.
    1142                 :  *
    1143                 :  * This method creates a UNIT subnode with the specified values as a
    1144                 :  * child of the target node. 
    1145                 :  *
    1146                 :  * This method does the same as the C function OSRSetTargetLinearUnits(). 
    1147                 :  *
    1148                 :  * @param pszTargetKey the keyword to set the linear units for.  ie. "PROJCS" or "VERT_CS"
    1149                 :  *
    1150                 :  * @param pszUnitsName the units name to be used.  Some preferred units
    1151                 :  * names can be found in ogr_srs_api.h such as SRS_UL_METER, SRS_UL_FOOT 
    1152                 :  * and SRS_UL_US_FOOT. 
    1153                 :  *
    1154                 :  * @param dfInMeters the value to multiple by a length in the indicated
    1155                 :  * units to transform to meters.  Some standard conversion factors can
    1156                 :  * be found in ogr_srs_api.h. 
    1157                 :  *
    1158                 :  * @return OGRERR_NONE on success.
    1159                 :  *
    1160                 :  * @since OGR 1.9.0
    1161                 :  */
    1162                 : 
    1163           12569 : OGRErr OGRSpatialReference::SetTargetLinearUnits( const char *pszTargetKey,
    1164                 :                                                   const char * pszUnitsName,
    1165                 :                                                   double dfInMeters )
    1166                 : 
    1167                 : {
    1168                 :     OGR_SRSNode *poCS;
    1169                 :     OGR_SRSNode *poUnits;
    1170                 :     char        szValue[128];
    1171                 : 
    1172           12569 :     bNormInfoSet = FALSE;
    1173                 : 
    1174           12569 :     if( pszTargetKey == NULL )
    1175                 :     {
    1176           12560 :         poCS = GetAttrNode( "PROJCS" );
    1177                 : 
    1178           12560 :         if( poCS == NULL )
    1179              51 :             poCS = GetAttrNode( "LOCAL_CS" );
    1180           12560 :         if( poCS == NULL )
    1181               5 :             poCS = GetAttrNode( "GEOCCS" );
    1182           12560 :         if( poCS == NULL && IsVertical() )
    1183               0 :             poCS = GetAttrNode( "VERT_CS" );
    1184                 :     }
    1185                 :     else
    1186               9 :         poCS = GetAttrNode( pszTargetKey );
    1187                 : 
    1188           12569 :     if( poCS == NULL )
    1189               0 :         return OGRERR_FAILURE;
    1190                 : 
    1191           12569 :     if( dfInMeters == (int) dfInMeters )
    1192           10885 :         sprintf( szValue, "%d", (int) dfInMeters );
    1193                 :     else
    1194            1684 :         OGRPrintDouble( szValue, dfInMeters );
    1195                 : 
    1196           12569 :     if( poCS->FindChild( "UNIT" ) >= 0 )
    1197                 :     {
    1198              96 :         poUnits = poCS->GetChild( poCS->FindChild( "UNIT" ) );
    1199              96 :         if (poUnits->GetChildCount() < 2)
    1200               0 :             return OGRERR_FAILURE;
    1201              96 :         poUnits->GetChild(0)->SetValue( pszUnitsName );
    1202              96 :         poUnits->GetChild(1)->SetValue( szValue );
    1203              96 :         if( poUnits->FindChild( "AUTHORITY" ) != -1 )
    1204               6 :             poUnits->DestroyChild( poUnits->FindChild( "AUTHORITY" ) );
    1205                 :     }
    1206                 :     else
    1207                 :     {
    1208           12473 :         poUnits = new OGR_SRSNode( "UNIT" );
    1209           24946 :         poUnits->AddChild( new OGR_SRSNode( pszUnitsName ) );
    1210           24946 :         poUnits->AddChild( new OGR_SRSNode( szValue ) );
    1211                 :         
    1212           12473 :         poCS->AddChild( poUnits );
    1213                 :     }
    1214                 : 
    1215           12569 :     return OGRERR_NONE;
    1216                 : }
    1217                 : 
    1218                 : /************************************************************************/
    1219                 : /*                         OSRSetLinearUnits()                          */
    1220                 : /************************************************************************/
    1221                 : 
    1222                 : /**
    1223                 :  * \brief Set the linear units for the target node.
    1224                 :  *
    1225                 :  * This function is the same as OGRSpatialReference::SetTargetLinearUnits()
    1226                 :  *
    1227                 :  * @since OGR 1.9.0
    1228                 :  */
    1229               1 : OGRErr OSRSetTargetLinearUnits( OGRSpatialReferenceH hSRS, 
    1230                 :                                 const char *pszTargetKey,
    1231                 :                                 const char * pszUnits, double dfInMeters )
    1232                 : 
    1233                 : {
    1234               1 :     VALIDATE_POINTER1( hSRS, "OSRSetTargetLinearUnits", CE_Failure );
    1235                 : 
    1236                 :     return ((OGRSpatialReference *) hSRS)->
    1237               1 :         SetTargetLinearUnits( pszTargetKey, pszUnits, dfInMeters );
    1238                 : }
    1239                 : 
    1240                 : /************************************************************************/
    1241                 : /*                           GetLinearUnits()                           */
    1242                 : /************************************************************************/
    1243                 : 
    1244                 : /**
    1245                 :  * \brief Fetch linear projection units. 
    1246                 :  *
    1247                 :  * If no units are available, a value of "Meters" and 1.0 will be assumed.
    1248                 :  * This method only checks directly under the PROJCS, GEOCCS or LOCAL_CS node 
    1249                 :  * for units.
    1250                 :  *
    1251                 :  * This method does the same thing as the C function OSRGetLinearUnits()/
    1252                 :  *
    1253                 :  * @param ppszName a pointer to be updated with the pointer to the 
    1254                 :  * units name.  The returned value remains internal to the OGRSpatialReference
    1255                 :  * and shouldn't be freed, or modified.  It may be invalidated on the next
    1256                 :  * OGRSpatialReference call. 
    1257                 :  *
    1258                 :  * @return the value to multiply by linear distances to transform them to 
    1259                 :  * meters.
    1260                 :  */
    1261                 : 
    1262           83608 : double OGRSpatialReference::GetLinearUnits( char ** ppszName ) const
    1263                 : 
    1264                 : {
    1265           83608 :     return GetTargetLinearUnits( NULL, ppszName );
    1266                 : }
    1267                 : 
    1268                 : /************************************************************************/
    1269                 : /*                         OSRGetLinearUnits()                          */
    1270                 : /************************************************************************/
    1271                 : 
    1272                 : /**
    1273                 :  * \brief Fetch linear projection units. 
    1274                 :  *
    1275                 :  * This function is the same as OGRSpatialReference::GetLinearUnits()
    1276                 :  */
    1277               0 : double OSRGetLinearUnits( OGRSpatialReferenceH hSRS, char ** ppszName )
    1278                 :     
    1279                 : {
    1280               0 :     VALIDATE_POINTER1( hSRS, "OSRGetLinearUnits", 0 );
    1281                 : 
    1282               0 :     return ((OGRSpatialReference *) hSRS)->GetLinearUnits( ppszName );
    1283                 : }
    1284                 : 
    1285                 : /************************************************************************/
    1286                 : /*                        GetTargetLinearUnits()                        */
    1287                 : /************************************************************************/
    1288                 : 
    1289                 : /**
    1290                 :  * \brief Fetch linear units for target. 
    1291                 :  *
    1292                 :  * If no units are available, a value of "Meters" and 1.0 will be assumed.
    1293                 :  *
    1294                 :  * This method does the same thing as the C function OSRGetTargetLinearUnits()/
    1295                 :  *
    1296                 :  * @param pszTargetKey the key to look on. ie. "PROJCS" or "VERT_CS".
    1297                 :  * @param ppszName a pointer to be updated with the pointer to the 
    1298                 :  * units name.  The returned value remains internal to the OGRSpatialReference
    1299                 :  * and shouldn't be freed, or modified.  It may be invalidated on the next
    1300                 :  * OGRSpatialReference call. 
    1301                 :  *
    1302                 :  * @return the value to multiply by linear distances to transform them to 
    1303                 :  * meters.
    1304                 :  *
    1305                 :  * @since OGR 1.9.0
    1306                 :  */
    1307                 : 
    1308           83608 : double OGRSpatialReference::GetTargetLinearUnits( const char *pszTargetKey,
    1309                 :                                                   char ** ppszName ) const
    1310                 : 
    1311                 : {
    1312                 :     const OGR_SRSNode *poCS;
    1313                 : 
    1314           83608 :     if( pszTargetKey == NULL )
    1315                 :     {
    1316           83608 :         poCS = GetAttrNode( "PROJCS" );
    1317                 : 
    1318           83608 :         if( poCS == NULL )
    1319            1025 :             poCS = GetAttrNode( "LOCAL_CS" );
    1320           83608 :         if( poCS == NULL )
    1321            1022 :             poCS = GetAttrNode( "GEOCCS" );
    1322           83608 :         if( poCS == NULL && IsVertical() )
    1323               0 :             poCS = GetAttrNode( "VERT_CS" );
    1324                 :     }
    1325                 :     else
    1326               0 :         poCS = GetAttrNode( pszTargetKey );
    1327                 : 
    1328           83608 :     if( ppszName != NULL )
    1329            2196 :         *ppszName = (char*) "unknown";
    1330                 :         
    1331           83608 :     if( poCS == NULL )
    1332            1017 :         return 1.0;
    1333                 : 
    1334          678564 :     for( int iChild = 0; iChild < poCS->GetChildCount(); iChild++ )
    1335                 :     {
    1336          676727 :         const OGR_SRSNode     *poChild = poCS->GetChild(iChild);
    1337                 :         
    1338          676727 :         if( EQUAL(poChild->GetValue(),"UNIT")
    1339                 :             && poChild->GetChildCount() >= 2 )
    1340                 :         {
    1341           80754 :             if( ppszName != NULL )
    1342             615 :                 *ppszName = (char *) poChild->GetChild(0)->GetValue();
    1343                 :             
    1344           80754 :             return CPLAtof( poChild->GetChild(1)->GetValue() );
    1345                 :         }
    1346                 :     }
    1347                 : 
    1348            1837 :     return 1.0;
    1349                 : }
    1350                 : 
    1351                 : /************************************************************************/
    1352                 : /*                      OSRGetTargetLinearUnits()                       */
    1353                 : /************************************************************************/
    1354                 : 
    1355                 : /**
    1356                 :  * \brief Fetch linear projection units. 
    1357                 :  *
    1358                 :  * This function is the same as OGRSpatialReference::GetTargetLinearUnits()
    1359                 :  *
    1360                 :  * @since OGR 1.9.0
    1361                 :  */
    1362               0 : double OSRGetTargetLinearUnits( OGRSpatialReferenceH hSRS, 
    1363                 :                                 const char *pszTargetKey, 
    1364                 :                                 char ** ppszName )
    1365                 :     
    1366                 : {
    1367               0 :     VALIDATE_POINTER1( hSRS, "OSRGetTargetLinearUnits", 0 );
    1368                 : 
    1369                 :     return ((OGRSpatialReference *) hSRS)->GetTargetLinearUnits( pszTargetKey,
    1370               0 :                                                                  ppszName );
    1371                 : }
    1372                 : 
    1373                 : /************************************************************************/
    1374                 : /*                          GetPrimeMeridian()                          */
    1375                 : /************************************************************************/
    1376                 : 
    1377                 : /**
    1378                 :  * \brief Fetch prime meridian info.
    1379                 :  *
    1380                 :  * Returns the offset of the prime meridian from greenwich in degrees,
    1381                 :  * and the prime meridian name (if requested).   If no PRIMEM value exists
    1382                 :  * in the coordinate system definition a value of "Greenwich" and an
    1383                 :  * offset of 0.0 is assumed.
    1384                 :  *
    1385                 :  * If the prime meridian name is returned, the pointer is to an internal
    1386                 :  * copy of the name. It should not be freed, altered or depended on after
    1387                 :  * the next OGR call.
    1388                 :  *
    1389                 :  * This method is the same as the C function OSRGetPrimeMeridian().
    1390                 :  *
    1391                 :  * @param ppszName return location for prime meridian name.  If NULL, name
    1392                 :  * is not returned.
    1393                 :  *
    1394                 :  * @return the offset to the GEOGCS prime meridian from greenwich in decimal
    1395                 :  * degrees.
    1396                 :  */
    1397                 : 
    1398           33128 : double OGRSpatialReference::GetPrimeMeridian( char **ppszName ) const 
    1399                 : 
    1400                 : {
    1401           33128 :     const OGR_SRSNode *poPRIMEM = GetAttrNode( "PRIMEM" );
    1402                 : 
    1403           33128 :     if( poPRIMEM != NULL && poPRIMEM->GetChildCount() >= 2 
    1404                 :         && CPLAtof(poPRIMEM->GetChild(1)->GetValue()) != 0.0 )
    1405                 :     {
    1406             467 :         if( ppszName != NULL )
    1407               0 :             *ppszName = (char *) poPRIMEM->GetChild(0)->GetValue();
    1408             467 :         return CPLAtof(poPRIMEM->GetChild(1)->GetValue());
    1409                 :     }
    1410                 :     
    1411           32661 :     if( ppszName != NULL )
    1412               5 :         *ppszName = (char*) SRS_PM_GREENWICH;
    1413                 : 
    1414           32661 :     return 0.0;
    1415                 : }
    1416                 : 
    1417                 : /************************************************************************/
    1418                 : /*                        OSRGetPrimeMeridian()                         */
    1419                 : /************************************************************************/
    1420                 : 
    1421                 : /**
    1422                 :  * \brief Fetch prime meridian info.
    1423                 :  *
    1424                 :  * This function is the same as OGRSpatialReference::GetPrimeMeridian()
    1425                 :  */
    1426               1 : double OSRGetPrimeMeridian( OGRSpatialReferenceH hSRS, char **ppszName )
    1427                 : 
    1428                 : {
    1429               1 :     VALIDATE_POINTER1( hSRS, "OSRGetPrimeMeridian", 0 );
    1430                 : 
    1431               1 :     return ((OGRSpatialReference *) hSRS)->GetPrimeMeridian( ppszName );
    1432                 : }
    1433                 : 
    1434                 : /************************************************************************/
    1435                 : /*                             SetGeogCS()                              */
    1436                 : /************************************************************************/
    1437                 : 
    1438                 : /**
    1439                 :  * \brief Set geographic coordinate system. 
    1440                 :  *
    1441                 :  * This method is used to set the datum, ellipsoid, prime meridian and
    1442                 :  * angular units for a geographic coordinate system.  It can be used on it's
    1443                 :  * own to establish a geographic spatial reference, or applied to a 
    1444                 :  * projected coordinate system to establish the underlying geographic 
    1445                 :  * coordinate system. 
    1446                 :  *
    1447                 :  * This method does the same as the C function OSRSetGeogCS(). 
    1448                 :  *
    1449                 :  * @param pszGeogName user visible name for the geographic coordinate system
    1450                 :  * (not to serve as a key).
    1451                 :  * 
    1452                 :  * @param pszDatumName key name for this datum.  The OpenGIS specification 
    1453                 :  * lists some known values, and otherwise EPSG datum names with a standard
    1454                 :  * transformation are considered legal keys. 
    1455                 :  * 
    1456                 :  * @param pszSpheroidName user visible spheroid name (not to serve as a key)
    1457                 :  *
    1458                 :  * @param dfSemiMajor the semi major axis of the spheroid.
    1459                 :  * 
    1460                 :  * @param dfInvFlattening the inverse flattening for the spheroid.
    1461                 :  * This can be computed from the semi minor axis as 
    1462                 :  * 1/f = 1.0 / (1.0 - semiminor/semimajor).
    1463                 :  *
    1464                 :  * @param pszPMName the name of the prime merdidian (not to serve as a key)
    1465                 :  * If this is NULL a default value of "Greenwich" will be used. 
    1466                 :  * 
    1467                 :  * @param dfPMOffset the longitude of greenwich relative to this prime
    1468                 :  * meridian.
    1469                 :  *
    1470                 :  * @param pszAngularUnits the angular units name (see ogr_srs_api.h for some
    1471                 :  * standard names).  If NULL a value of "degrees" will be assumed. 
    1472                 :  * 
    1473                 :  * @param dfConvertToRadians value to multiply angular units by to transform
    1474                 :  * them to radians.  A value of SRS_UL_DEGREE_CONV will be used if
    1475                 :  * pszAngularUnits is NULL.
    1476                 :  *
    1477                 :  * @return OGRERR_NONE on success.
    1478                 :  */
    1479                 : 
    1480                 : OGRErr
    1481           18828 : OGRSpatialReference::SetGeogCS( const char * pszGeogName,
    1482                 :                                 const char * pszDatumName,
    1483                 :                                 const char * pszSpheroidName,
    1484                 :                                 double dfSemiMajor, double dfInvFlattening,
    1485                 :                                 const char * pszPMName, double dfPMOffset,
    1486                 :                                 const char * pszAngularUnits,
    1487                 :                                 double dfConvertToRadians )
    1488                 : 
    1489                 : {
    1490           18828 :     bNormInfoSet = FALSE;
    1491                 : 
    1492                 : /* -------------------------------------------------------------------- */
    1493                 : /*      For a geocentric coordinate system we want to set the datum     */
    1494                 : /*      and ellipsoid based on the GEOGCS.  Create the GEOGCS in a      */
    1495                 : /*      temporary srs and use the copy method which has special         */
    1496                 : /*      handling for GEOCCS.                                            */
    1497                 : /* -------------------------------------------------------------------- */
    1498           18828 :     if( IsGeocentric() )
    1499                 :     {
    1500               2 :         OGRSpatialReference oGCS;
    1501                 : 
    1502                 :         oGCS.SetGeogCS( pszGeogName, pszDatumName, pszSpheroidName,
    1503                 :                         dfSemiMajor, dfInvFlattening, 
    1504                 :                         pszPMName, dfPMOffset, 
    1505               2 :                         pszAngularUnits, dfConvertToRadians );
    1506               2 :         return CopyGeogCSFrom( &oGCS );
    1507                 :     }        
    1508                 : 
    1509                 : /* -------------------------------------------------------------------- */
    1510                 : /*      Do we already have a GEOGCS?  If so, blow it away so it can     */
    1511                 : /*      be properly replaced.                                           */
    1512                 : /* -------------------------------------------------------------------- */
    1513           18826 :     if( GetAttrNode( "GEOGCS" ) != NULL )
    1514                 :     {
    1515                 :         OGR_SRSNode *poCS;
    1516                 : 
    1517               0 :         if( EQUAL(GetRoot()->GetValue(),"GEOGCS") )
    1518               0 :             Clear();
    1519               0 :         else if( (poCS = GetAttrNode( "PROJCS" )) != NULL
    1520                 :                  && poCS->FindChild( "GEOGCS" ) != -1 )
    1521               0 :             poCS->DestroyChild( poCS->FindChild( "GEOGCS" ) );
    1522                 :         else
    1523               0 :             return OGRERR_FAILURE;
    1524                 :     }
    1525                 : 
    1526                 : /* -------------------------------------------------------------------- */
    1527                 : /*      Set defaults for various parameters.                            */
    1528                 : /* -------------------------------------------------------------------- */
    1529           18826 :     if( pszGeogName == NULL )
    1530               0 :         pszGeogName = "unnamed";
    1531                 : 
    1532           18826 :     if( pszPMName == NULL )
    1533             195 :         pszPMName = SRS_PM_GREENWICH;
    1534                 : 
    1535           18826 :     if( pszDatumName == NULL )
    1536             117 :         pszDatumName = "unknown";
    1537                 : 
    1538           18826 :     if( pszSpheroidName == NULL )
    1539               0 :         pszSpheroidName = "unnamed";
    1540                 : 
    1541           18826 :     if( pszAngularUnits == NULL )
    1542                 :     {
    1543             309 :         pszAngularUnits = SRS_UA_DEGREE;
    1544             309 :         dfConvertToRadians = CPLAtof(SRS_UA_DEGREE_CONV);
    1545                 :     }
    1546                 : 
    1547                 : /* -------------------------------------------------------------------- */
    1548                 : /*      Build the GEOGCS object.                                        */
    1549                 : /* -------------------------------------------------------------------- */
    1550                 :     char                szValue[128];
    1551                 :     OGR_SRSNode         *poGeogCS, *poSpheroid, *poDatum, *poPM, *poUnits;
    1552                 : 
    1553           18826 :     poGeogCS = new OGR_SRSNode( "GEOGCS" );
    1554           37652 :     poGeogCS->AddChild( new OGR_SRSNode( pszGeogName ) );
    1555                 :     
    1556                 : /* -------------------------------------------------------------------- */
    1557                 : /*      Setup the spheroid.                                             */
    1558                 : /* -------------------------------------------------------------------- */
    1559           37652 :     poSpheroid = new OGR_SRSNode( "SPHEROID" );
    1560           37652 :     poSpheroid->AddChild( new OGR_SRSNode( pszSpheroidName ) );
    1561                 : 
    1562           18826 :     OGRPrintDouble( szValue, dfSemiMajor );
    1563           37652 :     poSpheroid->AddChild( new OGR_SRSNode(szValue) );
    1564                 : 
    1565           18826 :     OGRPrintDouble( szValue, dfInvFlattening );
    1566           37652 :     poSpheroid->AddChild( new OGR_SRSNode(szValue) );
    1567                 : 
    1568                 : /* -------------------------------------------------------------------- */
    1569                 : /*      Setup the Datum.                                                */
    1570                 : /* -------------------------------------------------------------------- */
    1571           37652 :     poDatum = new OGR_SRSNode( "DATUM" );
    1572           37652 :     poDatum->AddChild( new OGR_SRSNode(pszDatumName) );
    1573           18826 :     poDatum->AddChild( poSpheroid );
    1574                 : 
    1575                 : /* -------------------------------------------------------------------- */
    1576                 : /*      Setup the prime meridian.                                       */
    1577                 : /* -------------------------------------------------------------------- */
    1578           18826 :     if( dfPMOffset == 0.0 )
    1579           18414 :         strcpy( szValue, "0" );
    1580                 :     else
    1581             412 :         OGRPrintDouble( szValue, dfPMOffset );
    1582                 :     
    1583           18826 :     poPM = new OGR_SRSNode( "PRIMEM" );
    1584           37652 :     poPM->AddChild( new OGR_SRSNode( pszPMName ) );
    1585           37652 :     poPM->AddChild( new OGR_SRSNode( szValue ) );
    1586                 : 
    1587                 : /* -------------------------------------------------------------------- */
    1588                 : /*      Setup the rotational units.                                     */
    1589                 : /* -------------------------------------------------------------------- */
    1590           18826 :     OGRPrintDouble( szValue, dfConvertToRadians );
    1591                 :     
    1592           37652 :     poUnits = new OGR_SRSNode( "UNIT" );
    1593           37652 :     poUnits->AddChild( new OGR_SRSNode(pszAngularUnits) );
    1594           37652 :     poUnits->AddChild( new OGR_SRSNode(szValue) );
    1595                 :     
    1596                 : /* -------------------------------------------------------------------- */
    1597                 : /*      Complete the GeogCS                                             */
    1598                 : /* -------------------------------------------------------------------- */
    1599           18826 :     poGeogCS->AddChild( poDatum );
    1600           18826 :     poGeogCS->AddChild( poPM );
    1601           18826 :     poGeogCS->AddChild( poUnits );
    1602                 : 
    1603                 : /* -------------------------------------------------------------------- */
    1604                 : /*      Attach below the PROJCS if there is one, or make this the root. */
    1605                 : /* -------------------------------------------------------------------- */
    1606           31060 :     if( GetRoot() != NULL && EQUAL(GetRoot()->GetValue(),"PROJCS") )
    1607           12234 :         poRoot->InsertChild( poGeogCS, 1 );
    1608                 :     else
    1609            6592 :         SetRoot( poGeogCS );
    1610                 : 
    1611           18826 :     return OGRERR_NONE;
    1612                 : }
    1613                 : 
    1614                 : /************************************************************************/
    1615                 : /*                            OSRSetGeogCS()                            */
    1616                 : /************************************************************************/
    1617                 : 
    1618                 : /**
    1619                 :  * \brief Set geographic coordinate system. 
    1620                 :  *
    1621                 :  * This function is the same as OGRSpatialReference::SetGeogCS()
    1622                 :  */
    1623               5 : OGRErr OSRSetGeogCS( OGRSpatialReferenceH hSRS,
    1624                 :                      const char * pszGeogName,
    1625                 :                      const char * pszDatumName,
    1626                 :                      const char * pszSpheroidName,
    1627                 :                      double dfSemiMajor, double dfInvFlattening,
    1628                 :                      const char * pszPMName, double dfPMOffset,
    1629                 :                      const char * pszAngularUnits,
    1630                 :                      double dfConvertToRadians )
    1631                 : 
    1632                 : {
    1633               5 :     VALIDATE_POINTER1( hSRS, "OSRSetGeogCS", CE_Failure );
    1634                 : 
    1635                 :     return ((OGRSpatialReference *) hSRS)->SetGeogCS( 
    1636                 :         pszGeogName, pszDatumName, 
    1637                 :         pszSpheroidName, dfSemiMajor, dfInvFlattening, 
    1638               5 :         pszPMName, dfPMOffset, pszAngularUnits, dfConvertToRadians );
    1639                 :                                                       
    1640                 : }
    1641                 : 
    1642                 : /************************************************************************/
    1643                 : /*                         SetWellKnownGeogCS()                         */
    1644                 : /************************************************************************/
    1645                 : 
    1646                 : /**
    1647                 :  * \brief Set a GeogCS based on well known name.
    1648                 :  *
    1649                 :  * This may be called on an empty OGRSpatialReference to make a geographic
    1650                 :  * coordinate system, or on something with an existing PROJCS node to 
    1651                 :  * set the underlying geographic coordinate system of a projected coordinate
    1652                 :  * system. 
    1653                 :  *
    1654                 :  * The following well known text values are currently supported:
    1655                 :  * <ul>
    1656                 :  * <li> "WGS84": same as "EPSG:4326" but has no dependence on EPSG data files.
    1657                 :  * <li> "WGS72": same as "EPSG:4322" but has no dependence on EPSG data files.
    1658                 :  * <li> "NAD27": same as "EPSG:4267" but has no dependence on EPSG data files.
    1659                 :  * <li> "NAD83": same as "EPSG:4269" but has no dependence on EPSG data files.
    1660                 :  * <li> "EPSG:n": same as doing an ImportFromEPSG(n).
    1661                 :  * </ul>
    1662                 :  * 
    1663                 :  * @param pszName name of well known geographic coordinate system.
    1664                 :  * @return OGRERR_NONE on success, or OGRERR_FAILURE if the name isn't
    1665                 :  * recognised, the target object is already initialized, or an EPSG value
    1666                 :  * can't be successfully looked up.
    1667                 :  */ 
    1668                 : 
    1669            1392 : OGRErr OGRSpatialReference::SetWellKnownGeogCS( const char * pszName )
    1670                 : 
    1671                 : {
    1672            1392 :     OGRSpatialReference   oSRS2;
    1673                 :     OGRErr eErr;
    1674                 : 
    1675                 : /* -------------------------------------------------------------------- */
    1676                 : /*      Check for EPSG authority numbers.                               */
    1677                 : /* -------------------------------------------------------------------- */
    1678            1392 :     if( EQUALN(pszName, "EPSG:",5) )
    1679                 :     {
    1680               9 :         eErr = oSRS2.importFromEPSG( atoi(pszName+5) );
    1681               9 :         if( eErr != OGRERR_NONE )
    1682               0 :             return eErr;
    1683                 : 
    1684               9 :         if( !oSRS2.IsGeographic() )
    1685               0 :             return OGRERR_FAILURE;
    1686                 : 
    1687               9 :         return CopyGeogCSFrom( &oSRS2 );
    1688                 :     }
    1689                 : 
    1690                 : /* -------------------------------------------------------------------- */
    1691                 : /*      Check for EPSGA authority numbers.                               */
    1692                 : /* -------------------------------------------------------------------- */
    1693            1383 :     if( EQUALN(pszName, "EPSGA:",6) )
    1694                 :     {
    1695               0 :         eErr = oSRS2.importFromEPSGA( atoi(pszName+6) );
    1696               0 :         if( eErr != OGRERR_NONE )
    1697               0 :             return eErr;
    1698                 : 
    1699               0 :         if( !oSRS2.IsGeographic() )
    1700               0 :             return OGRERR_FAILURE;
    1701                 : 
    1702               0 :         return CopyGeogCSFrom( &oSRS2 );
    1703                 :     }
    1704                 : 
    1705                 : /* -------------------------------------------------------------------- */
    1706                 : /*      Check for simple names.                                         */
    1707                 : /* -------------------------------------------------------------------- */
    1708            1383 :     char        *pszWKT = NULL;
    1709                 : 
    1710            2660 :     if( EQUAL(pszName, "WGS84") || EQUAL(pszName,"CRS84") || EQUAL(pszName,"CRS:84") )
    1711            1277 :         pszWKT = (char* ) SRS_WKT_WGS84;
    1712                 : 
    1713             106 :     else if( EQUAL(pszName, "WGS72") )
    1714              27 :         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\"]]";
    1715                 : 
    1716             146 :     else if( EQUAL(pszName, "NAD27") || EQUAL(pszName, "CRS27") || EQUAL(pszName,"CRS:27") )
    1717              67 :         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\"]]";
    1718                 :         
    1719              23 :     else if( EQUAL(pszName, "NAD83") || EQUAL(pszName,"CRS83") || EQUAL(pszName,"CRS:83") )
    1720              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\"]]";
    1721                 : 
    1722                 :     else
    1723               1 :         return OGRERR_FAILURE;
    1724                 : 
    1725                 : /* -------------------------------------------------------------------- */
    1726                 : /*      Import the WKT                                                  */
    1727                 : /* -------------------------------------------------------------------- */
    1728            1382 :     eErr = oSRS2.importFromWkt( &pszWKT );
    1729            1382 :     if( eErr != OGRERR_NONE )
    1730               0 :         return eErr;
    1731                 : 
    1732                 : /* -------------------------------------------------------------------- */
    1733                 : /*      Copy over.                                                      */
    1734                 : /* -------------------------------------------------------------------- */
    1735            1382 :     return CopyGeogCSFrom( &oSRS2 );
    1736                 : }
    1737                 : 
    1738                 : /************************************************************************/
    1739                 : /*                       OSRSetWellKnownGeogCS()                        */
    1740                 : /************************************************************************/
    1741                 : 
    1742                 : /**
    1743                 :  * \brief Set a GeogCS based on well known name.
    1744                 :  *
    1745                 :  * This function is the same as OGRSpatialReference::SetWellKnownGeogCS()
    1746                 :  */
    1747              37 : OGRErr OSRSetWellKnownGeogCS( OGRSpatialReferenceH hSRS, const char *pszName )
    1748                 : 
    1749                 : {
    1750              37 :     VALIDATE_POINTER1( hSRS, "OSRSetWellKnownGeogCS", CE_Failure );
    1751                 : 
    1752              37 :     return ((OGRSpatialReference *) hSRS)->SetWellKnownGeogCS( pszName );
    1753                 : }
    1754                 : 
    1755                 : /************************************************************************/
    1756                 : /*                           CopyGeogCSFrom()                           */
    1757                 : /************************************************************************/
    1758                 : 
    1759                 : /**
    1760                 :  * \brief Copy GEOGCS from another OGRSpatialReference.
    1761                 :  *
    1762                 :  * The GEOGCS information is copied into this OGRSpatialReference from another.
    1763                 :  * If this object has a PROJCS root already, the GEOGCS is installed within
    1764                 :  * it, otherwise it is installed as the root.
    1765                 :  * 
    1766                 :  * @param poSrcSRS the spatial reference to copy the GEOGCS information from.
    1767                 :  * 
    1768                 :  * @return OGRERR_NONE on success or an error code.
    1769                 :  */
    1770                 : 
    1771                 : 
    1772            2226 : OGRErr OGRSpatialReference::CopyGeogCSFrom( 
    1773                 :     const OGRSpatialReference * poSrcSRS )
    1774                 : 
    1775                 : {
    1776            2226 :     const OGR_SRSNode  *poGeogCS = NULL;
    1777                 : 
    1778            2226 :     bNormInfoSet = FALSE;
    1779                 : 
    1780                 : /* -------------------------------------------------------------------- */
    1781                 : /*      Handle geocentric coordinate systems specially.  We just        */
    1782                 : /*      want to copy the DATUM and PRIMEM nodes.                        */
    1783                 : /* -------------------------------------------------------------------- */
    1784            2226 :     if( IsGeocentric() )
    1785                 :     {
    1786               3 :         if( GetRoot()->FindChild( "DATUM" ) != -1 )
    1787               0 :             GetRoot()->DestroyChild( GetRoot()->FindChild( "DATUM" ) );
    1788               3 :         if( GetRoot()->FindChild( "PRIMEM" ) != -1 )
    1789               0 :             GetRoot()->DestroyChild( GetRoot()->FindChild( "PRIMEM" ) );
    1790                 : 
    1791               3 :         const OGR_SRSNode *poDatum = poSrcSRS->GetAttrNode( "DATUM" );
    1792               3 :         const OGR_SRSNode *poPrimeM = poSrcSRS->GetAttrNode( "PRIMEM" );
    1793                 : 
    1794               3 :         if( poDatum == NULL || poPrimeM == NULL )
    1795               0 :             return OGRERR_FAILURE;
    1796                 :         
    1797               3 :         poRoot->InsertChild( poDatum->Clone(), 1 );
    1798               3 :         poRoot->InsertChild( poPrimeM->Clone(), 2 );
    1799                 : 
    1800               3 :         return OGRERR_NONE;
    1801                 :         
    1802                 :     }
    1803                 : 
    1804                 : /* -------------------------------------------------------------------- */
    1805                 : /*      Do we already have a GEOGCS?  If so, blow it away so it can     */
    1806                 : /*      be properly replaced.                                           */
    1807                 : /* -------------------------------------------------------------------- */
    1808            2223 :     if( GetAttrNode( "GEOGCS" ) != NULL )
    1809                 :     {
    1810                 :         OGR_SRSNode *poPROJCS;
    1811                 : 
    1812             826 :         if( EQUAL(GetRoot()->GetValue(),"GEOGCS") )
    1813             821 :             Clear();
    1814               5 :         else if( (poPROJCS = GetAttrNode( "PROJCS" )) != NULL
    1815                 :                  && poPROJCS->FindChild( "GEOGCS" ) != -1 )
    1816               5 :             poPROJCS->DestroyChild( poPROJCS->FindChild( "GEOGCS" ) );
    1817                 :         else
    1818               0 :             return OGRERR_FAILURE;
    1819                 :     }
    1820                 : 
    1821                 : /* -------------------------------------------------------------------- */
    1822                 : /*      Find the GEOGCS node on the source.                             */
    1823                 : /* -------------------------------------------------------------------- */
    1824            2223 :     poGeogCS = poSrcSRS->GetAttrNode( "GEOGCS" );
    1825            2223 :     if( poGeogCS == NULL )
    1826               0 :         return OGRERR_FAILURE;
    1827                 : 
    1828                 : /* -------------------------------------------------------------------- */
    1829                 : /*      Attach below the PROJCS if there is one, or make this the root. */
    1830                 : /* -------------------------------------------------------------------- */
    1831            2223 :     if( GetRoot() != NULL && EQUAL(GetRoot()->GetValue(),"PROJCS") )
    1832             171 :         poRoot->InsertChild( poGeogCS->Clone(), 1 );
    1833                 :     else
    1834            2052 :         SetRoot( poGeogCS->Clone() );
    1835                 : 
    1836            2223 :     return OGRERR_NONE;
    1837                 : }
    1838                 : 
    1839                 : /************************************************************************/
    1840                 : /*                         OSRCopyGeogCSFrom()                          */
    1841                 : /************************************************************************/
    1842                 : 
    1843                 : /**
    1844                 :  * \brief Copy GEOGCS from another OGRSpatialReference.
    1845                 :  *
    1846                 :  * This function is the same as OGRSpatialReference::CopyGeogCSFrom()
    1847                 :  */
    1848               0 : OGRErr OSRCopyGeogCSFrom( OGRSpatialReferenceH hSRS, 
    1849                 :                           OGRSpatialReferenceH hSrcSRS )
    1850                 : 
    1851                 : {
    1852               0 :     VALIDATE_POINTER1( hSRS, "OSRCopyGeogCSFrom", CE_Failure );
    1853               0 :     VALIDATE_POINTER1( hSrcSRS, "OSRCopyGeogCSFrom", CE_Failure );
    1854                 : 
    1855                 :     return ((OGRSpatialReference *) hSRS)->CopyGeogCSFrom( 
    1856               0 :         (const OGRSpatialReference *) hSrcSRS );
    1857                 : }
    1858                 : 
    1859                 : /************************************************************************/
    1860                 : /*                          SetFromUserInput()                          */
    1861                 : /************************************************************************/
    1862                 : 
    1863                 : /**
    1864                 :  * \brief Set spatial reference from various text formats.
    1865                 :  *
    1866                 :  * This method will examine the provided input, and try to deduce the
    1867                 :  * format, and then use it to initialize the spatial reference system.  It
    1868                 :  * may take the following forms:
    1869                 :  *
    1870                 :  * <ol>
    1871                 :  * <li> Well Known Text definition - passed on to importFromWkt().
    1872                 :  * <li> "EPSG:n" - number passed on to importFromEPSG(). 
    1873                 :  * <li> "EPSGA:n" - number passed on to importFromEPSGA(). 
    1874                 :  * <li> "AUTO:proj_id,unit_id,lon0,lat0" - WMS auto projections.
    1875                 :  * <li> "urn:ogc:def:crs:EPSG::n" - ogc urns
    1876                 :  * <li> PROJ.4 definitions - passed on to importFromProj4().
    1877                 :  * <li> filename - file read for WKT, XML or PROJ.4 definition.
    1878                 :  * <li> well known name accepted by SetWellKnownGeogCS(), such as NAD27, NAD83,
    1879                 :  * WGS84 or WGS72. 
    1880                 :  * <li> WKT (directly or in a file) in ESRI format should be prefixed with
    1881                 :  * ESRI:: to trigger an automatic morphFromESRI().
    1882                 :  * <li> "IGNF:xxx" - "+init=IGNF:xxx" passed on to importFromProj4().
    1883                 :  * </ol>
    1884                 :  *
    1885                 :  * It is expected that this method will be extended in the future to support
    1886                 :  * XML and perhaps a simplified "minilanguage" for indicating common UTM and
    1887                 :  * State Plane definitions. 
    1888                 :  *
    1889                 :  * This method is intended to be flexible, but by it's nature it is 
    1890                 :  * imprecise as it must guess information about the format intended.  When
    1891                 :  * possible applications should call the specific method appropriate if the
    1892                 :  * input is known to be in a particular format. 
    1893                 :  *
    1894                 :  * This method does the same thing as the OSRSetFromUserInput() function.
    1895                 :  * 
    1896                 :  * @param pszDefinition text definition to try to deduce SRS from.
    1897                 :  *
    1898                 :  * @return OGRERR_NONE on success, or an error code if the name isn't
    1899                 :  * recognised, the definition is corrupt, or an EPSG value can't be 
    1900                 :  * successfully looked up.
    1901                 :  */ 
    1902                 : 
    1903            1099 : OGRErr OGRSpatialReference::SetFromUserInput( const char * pszDefinition )
    1904                 : 
    1905                 : {
    1906            1099 :     int     bESRI = FALSE;
    1907                 :     OGRErr  err;
    1908                 : 
    1909            1099 :     if( EQUALN(pszDefinition,"ESRI::",6) )
    1910                 :     {
    1911               1 :         bESRI = TRUE;
    1912               1 :         pszDefinition += 6;
    1913                 :     }
    1914                 : 
    1915                 : /* -------------------------------------------------------------------- */
    1916                 : /*      Is it a recognised syntax?                                      */
    1917                 : /* -------------------------------------------------------------------- */
    1918            1099 :     if( EQUALN(pszDefinition,"PROJCS",6)
    1919                 :         || EQUALN(pszDefinition,"GEOGCS",6)
    1920                 :         || EQUALN(pszDefinition,"COMPD_CS",8)
    1921                 :         || EQUALN(pszDefinition,"GEOCCS",6)
    1922                 :         || EQUALN(pszDefinition,"VERT_CS",7)
    1923                 :         || EQUALN(pszDefinition,"LOCAL_CS",8) )
    1924                 :     {
    1925             711 :         err = importFromWkt( (char **) &pszDefinition );
    1926             711 :         if( err == OGRERR_NONE && bESRI )
    1927               1 :             err = morphFromESRI();
    1928                 : 
    1929             711 :         return err;
    1930                 :     }
    1931                 : 
    1932             388 :     if( EQUALN(pszDefinition,"EPSG:",5) 
    1933                 :         || EQUALN(pszDefinition,"EPSGA:",6) )
    1934                 :     {
    1935                 :         OGRErr eStatus; 
    1936                 : 
    1937             173 :         if( EQUALN(pszDefinition,"EPSG:",5) )
    1938             172 :             eStatus = importFromEPSG( atoi(pszDefinition+5) );
    1939                 :         
    1940                 :         else /* if( EQUALN(pszDefinition,"EPSGA:",6) ) */
    1941               1 :             eStatus = importFromEPSGA( atoi(pszDefinition+6) );
    1942                 :         
    1943                 :         // Do we want to turn this into a compound definition
    1944                 :         // with a vertical datum?
    1945             173 :         if( eStatus == OGRERR_NONE && strchr( pszDefinition, '+' ) != NULL )
    1946                 :         {
    1947               1 :             OGRSpatialReference oVertSRS;
    1948                 : 
    1949                 :             eStatus = oVertSRS.importFromEPSG( 
    1950               1 :                 atoi(strchr(pszDefinition,'+')+1) );
    1951               1 :             if( eStatus == OGRERR_NONE )
    1952                 :             {
    1953               1 :                 OGR_SRSNode *poHorizSRS = GetRoot()->Clone();
    1954                 : 
    1955               1 :                 Clear();
    1956                 : 
    1957               1 :                 CPLString osName = poHorizSRS->GetChild(0)->GetValue();
    1958               1 :                 osName += " + ";
    1959               1 :                 osName += oVertSRS.GetRoot()->GetValue();
    1960                 : 
    1961               1 :                 SetNode( "COMPD_CS", osName );
    1962               1 :                 GetRoot()->AddChild( poHorizSRS );
    1963               1 :                 GetRoot()->AddChild( oVertSRS.GetRoot()->Clone() );
    1964                 :             }
    1965                 :             
    1966               1 :             return eStatus;
    1967                 :         }
    1968                 :         else
    1969             172 :             return eStatus;
    1970                 :     }
    1971                 : 
    1972             215 :     if( EQUALN(pszDefinition,"urn:ogc:def:crs:",16)
    1973                 :         || EQUALN(pszDefinition,"urn:ogc:def:crs,crs:",20)
    1974                 :         || EQUALN(pszDefinition,"urn:x-ogc:def:crs:",18)
    1975                 :         || EQUALN(pszDefinition,"urn:opengis:crs:",16)
    1976                 :         || EQUALN(pszDefinition,"urn:opengis:def:crs:",20))
    1977              57 :         return importFromURN( pszDefinition );
    1978                 : 
    1979             158 :     if( EQUALN(pszDefinition,"AUTO:",5) )
    1980               0 :         return importFromWMSAUTO( pszDefinition );
    1981                 : 
    1982             158 :     if( EQUALN(pszDefinition,"OGC:",4) )  // WMS/WCS OGC codes like OGC:CRS84
    1983               0 :         return SetWellKnownGeogCS( pszDefinition+4 );
    1984                 : 
    1985             158 :     if( EQUALN(pszDefinition,"CRS:",4) )
    1986               1 :         return SetWellKnownGeogCS( pszDefinition );
    1987                 : 
    1988             157 :     if( EQUALN(pszDefinition,"DICT:",5) 
    1989                 :         && strstr(pszDefinition,",") )
    1990                 :     {
    1991               0 :         char *pszFile = CPLStrdup(pszDefinition+5);
    1992               0 :         char *pszCode = strstr(pszFile,",") + 1;
    1993                 :         
    1994               0 :         pszCode[-1] = '\0';
    1995                 : 
    1996               0 :         err = importFromDict( pszFile, pszCode );
    1997               0 :         CPLFree( pszFile );
    1998                 : 
    1999               0 :         if( err == OGRERR_NONE && bESRI )
    2000               0 :             err = morphFromESRI();
    2001                 : 
    2002               0 :         return err;
    2003                 :     }
    2004                 : 
    2005             157 :     if( EQUAL(pszDefinition,"NAD27") 
    2006                 :         || EQUAL(pszDefinition,"NAD83") 
    2007                 :         || EQUAL(pszDefinition,"WGS84") 
    2008                 :         || EQUAL(pszDefinition,"WGS72") )
    2009                 :     {
    2010              93 :         Clear();
    2011              93 :         return SetWellKnownGeogCS( pszDefinition );
    2012                 :     }
    2013                 : 
    2014              64 :     if( strstr(pszDefinition,"+proj") != NULL 
    2015                 :              || strstr(pszDefinition,"+init") != NULL )
    2016              58 :         return importFromProj4( pszDefinition );
    2017                 : 
    2018               6 :     if( EQUALN(pszDefinition,"IGNF:", 5) )
    2019                 :     {
    2020               0 :         char* pszProj4Str = (char*) CPLMalloc(6 + strlen(pszDefinition) + 1);
    2021               0 :         strcpy(pszProj4Str, "+init=");
    2022               0 :         strcat(pszProj4Str, pszDefinition);
    2023               0 :         err = importFromProj4( pszProj4Str );
    2024               0 :         CPLFree(pszProj4Str);
    2025                 : 
    2026               0 :         return err;
    2027                 :     }
    2028                 : 
    2029               6 :     if( EQUALN(pszDefinition,"http://",7) )
    2030                 :     {
    2031               0 :         return importFromUrl (pszDefinition);
    2032                 :     }
    2033                 : 
    2034               6 :     if( EQUAL(pszDefinition,"osgb:BNG") )
    2035                 :     {
    2036               1 :         return importFromEPSG(27700);
    2037                 :     }
    2038                 : 
    2039                 : /* -------------------------------------------------------------------- */
    2040                 : /*      Try to open it as a file.                                       */
    2041                 : /* -------------------------------------------------------------------- */
    2042                 :     FILE        *fp;
    2043               5 :     int         nBufMax = 100000;
    2044                 :     char        *pszBufPtr, *pszBuffer;
    2045                 :     int         nBytes;
    2046                 : 
    2047               5 :     fp = VSIFOpen( pszDefinition, "rt" );
    2048               5 :     if( fp == NULL )
    2049               2 :         return OGRERR_CORRUPT_DATA;
    2050                 : 
    2051               3 :     pszBuffer = (char *) CPLMalloc(nBufMax);
    2052               3 :     nBytes = VSIFRead( pszBuffer, 1, nBufMax-1, fp );
    2053               3 :     VSIFClose( fp );
    2054                 : 
    2055               3 :     if( nBytes == nBufMax-1 )
    2056                 :     {
    2057                 :         CPLDebug( "OGR", 
    2058                 :                   "OGRSpatialReference::SetFromUserInput(%s), opened file\n"
    2059                 :                   "but it is to large for our generous buffer.  Is it really\n"
    2060               0 :                   "just a WKT definition?", pszDefinition );
    2061               0 :         CPLFree( pszBuffer );
    2062               0 :         return OGRERR_FAILURE;
    2063                 :     }
    2064                 : 
    2065               3 :     pszBuffer[nBytes] = '\0';
    2066                 : 
    2067               3 :     pszBufPtr = pszBuffer;
    2068               6 :     while( pszBufPtr[0] == ' ' || pszBufPtr[0] == '\n' )
    2069               0 :         pszBufPtr++;
    2070                 : 
    2071               3 :     if( pszBufPtr[0] == '<' )
    2072               0 :         err = importFromXML( pszBufPtr );
    2073               3 :     else if( (strstr(pszBuffer,"+proj") != NULL  
    2074                 :               || strstr(pszBuffer,"+init") != NULL)
    2075                 :              && (strstr(pszBuffer,"EXTENSION") == NULL
    2076                 :                  && strstr(pszBuffer,"extension") == NULL) )
    2077               0 :         err = importFromProj4( pszBufPtr );
    2078                 :     else
    2079                 :     {
    2080               3 :         if( EQUALN(pszBufPtr,"ESRI::",6) )
    2081                 :         {
    2082               2 :             bESRI = TRUE;
    2083               2 :             pszBufPtr += 6;
    2084                 :         }
    2085                 : 
    2086               3 :         err = importFromWkt( &pszBufPtr );
    2087               3 :         if( err == OGRERR_NONE && bESRI )
    2088               2 :             err = morphFromESRI();
    2089                 :     }
    2090                 : 
    2091               3 :     CPLFree( pszBuffer );
    2092                 : 
    2093               3 :     return err;
    2094                 : }
    2095                 : 
    2096                 : /************************************************************************/
    2097                 : /*                        OSRSetFromUserInput()                         */
    2098                 : /************************************************************************/
    2099                 : 
    2100                 : /**
    2101                 :  * \brief Set spatial reference from various text formats.
    2102                 :  *
    2103                 :  * This function is the same as OGRSpatialReference::SetFromUserInput()
    2104                 :  */
    2105             258 : OGRErr CPL_STDCALL OSRSetFromUserInput( OGRSpatialReferenceH hSRS, 
    2106                 :                                         const char *pszDef )
    2107                 : 
    2108                 : {
    2109             258 :     VALIDATE_POINTER1( hSRS, "OSRSetFromUserInput", CE_Failure );
    2110                 : 
    2111             258 :     return ((OGRSpatialReference *) hSRS)->SetFromUserInput( pszDef );
    2112                 : }
    2113                 : 
    2114                 : 
    2115                 : /************************************************************************/
    2116                 : /*                          ImportFromUrl()                             */
    2117                 : /************************************************************************/
    2118                 : 
    2119                 : /**
    2120                 :  * \brief Set spatial reference from a URL.
    2121                 :  *
    2122                 :  * This method will download the spatial reference at a given URL and 
    2123                 :  * feed it into SetFromUserInput for you.  
    2124                 :  *
    2125                 :  * This method does the same thing as the OSRImportFromUrl() function.
    2126                 :  * 
    2127                 :  * @param pszUrl text definition to try to deduce SRS from.
    2128                 :  *
    2129                 :  * @return OGRERR_NONE on success, or an error code with the curl 
    2130                 :  * error message if it is unable to dowload data.
    2131                 :  */ 
    2132                 : 
    2133               2 : OGRErr OGRSpatialReference::importFromUrl( const char * pszUrl )
    2134                 : 
    2135                 : {
    2136                 : 
    2137                 : 
    2138               2 :     if( !EQUALN(pszUrl,"http://",7) )
    2139                 :     {
    2140                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2141                 :                   "The given string is not recognized as a URL"
    2142               0 :                   "starting with 'http://' -- %s", pszUrl );
    2143               0 :         return OGRERR_FAILURE;
    2144                 :     }
    2145                 : 
    2146                 : /* -------------------------------------------------------------------- */
    2147                 : /*      Fetch the result.                                               */
    2148                 : /* -------------------------------------------------------------------- */
    2149               2 :     CPLErrorReset();
    2150                 : 
    2151               2 :     const char* pszHeaders = "HEADERS=Accept: application/x-ogcwkt";
    2152               2 :     const char* pszTimeout = "TIMEOUT=10";
    2153                 :     char *apszOptions[] = { 
    2154                 :         (char *) pszHeaders,
    2155                 :         (char *) pszTimeout,
    2156                 :         NULL 
    2157               2 :     };
    2158                 :         
    2159               2 :     CPLHTTPResult *psResult = CPLHTTPFetch( pszUrl, apszOptions );
    2160                 : 
    2161                 : /* -------------------------------------------------------------------- */
    2162                 : /*      Try to handle errors.                                           */
    2163                 : /* -------------------------------------------------------------------- */
    2164                 : 
    2165               2 :     if ( psResult == NULL)
    2166               0 :         return OGRERR_FAILURE;
    2167               2 :     if( psResult->nDataLen == 0 
    2168                 :         || CPLGetLastErrorNo() != 0 || psResult->pabyData == NULL  )
    2169                 :     {
    2170               0 :         if (CPLGetLastErrorNo() == 0)
    2171                 :         {
    2172                 :             CPLError( CE_Failure, CPLE_AppDefined, 
    2173               0 :                     "No data was returned from the given URL" );
    2174                 :         }
    2175               0 :         CPLHTTPDestroyResult( psResult );
    2176               0 :         return OGRERR_FAILURE;
    2177                 :     }
    2178                 : 
    2179               2 :     if (psResult->nStatus != 0) 
    2180                 :     {
    2181                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2182               0 :                   "Curl reports error: %d: %s", psResult->nStatus, psResult->pszErrBuf );
    2183               0 :         CPLHTTPDestroyResult( psResult );
    2184               0 :         return OGRERR_FAILURE;        
    2185                 :     }
    2186                 : 
    2187               2 :     if( EQUALN( (const char*) psResult->pabyData,"http://",7) )
    2188                 :     {
    2189                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2190                 :                   "The data that was downloaded also starts with 'http://' "
    2191                 :                   "and cannot be passed into SetFromUserInput.  Is this "
    2192               0 :                   "really a spatial reference definition? ");
    2193               0 :         CPLHTTPDestroyResult( psResult );
    2194               0 :         return OGRERR_FAILURE;
    2195                 :     }
    2196               2 :     if( OGRERR_NONE != SetFromUserInput( (const char *) psResult->pabyData )) {
    2197               0 :         CPLHTTPDestroyResult( psResult );        
    2198               0 :         return OGRERR_FAILURE;
    2199                 :     }
    2200                 : 
    2201               2 :     CPLHTTPDestroyResult( psResult );
    2202               2 :     return OGRERR_NONE;
    2203                 : }
    2204                 : 
    2205                 : /************************************************************************/
    2206                 : /*                        OSRimportFromUrl()                            */
    2207                 : /************************************************************************/
    2208                 : 
    2209                 : /**
    2210                 :  * \brief Set spatial reference from a URL.
    2211                 :  *
    2212                 :  * This function is the same as OGRSpatialReference::importFromUrl()
    2213                 :  */
    2214               2 : OGRErr OSRImportFromUrl( OGRSpatialReferenceH hSRS, const char *pszUrl )
    2215                 : 
    2216                 : {
    2217               2 :     VALIDATE_POINTER1( hSRS, "OSRImportFromUrl", CE_Failure );
    2218                 : 
    2219               2 :     return ((OGRSpatialReference *) hSRS)->importFromUrl( pszUrl );
    2220                 : }
    2221                 : 
    2222                 : /************************************************************************/
    2223                 : /*                         importFromURNPart()                          */
    2224                 : /************************************************************************/
    2225              76 : OGRErr OGRSpatialReference::importFromURNPart(const char* pszAuthority,
    2226                 :                                               const char* pszCode,
    2227                 :                                               const char* pszURN)
    2228                 : {
    2229                 : 
    2230                 : /* -------------------------------------------------------------------- */
    2231                 : /*      Is this an EPSG code? Note that we import it with EPSG          */
    2232                 : /*      preferred axis ordering for geographic coordinate systems!      */
    2233                 : /* -------------------------------------------------------------------- */
    2234              76 :     if( EQUALN(pszAuthority,"EPSG:",5) )
    2235              74 :         return importFromEPSGA( atoi(pszCode) );
    2236                 : 
    2237                 : /* -------------------------------------------------------------------- */
    2238                 : /*      Is this an IAU code?  Lets try for the IAU2000 dictionary.      */
    2239                 : /* -------------------------------------------------------------------- */
    2240               2 :     if( EQUALN(pszAuthority,"IAU",3) )
    2241               0 :         return importFromDict( "IAU2000.wkt", pszCode );
    2242                 : 
    2243                 : /* -------------------------------------------------------------------- */
    2244                 : /*      Is this an OGC code?                                            */
    2245                 : /* -------------------------------------------------------------------- */
    2246               2 :     if( !EQUALN(pszAuthority,"OGC:",4) )
    2247                 :     {
    2248                 :         CPLError( CE_Failure, CPLE_AppDefined,
    2249                 :                   "URN %s has unrecognised authority.",
    2250               0 :                   pszURN );
    2251               0 :         return OGRERR_FAILURE;
    2252                 :     }
    2253                 : 
    2254               2 :     if( EQUALN(pszCode,"CRS84",5) )
    2255               1 :         return SetWellKnownGeogCS( pszCode );
    2256               1 :     else if( EQUALN(pszCode,"CRS83",5) )
    2257               0 :         return SetWellKnownGeogCS( pszCode );
    2258               1 :     else if( EQUALN(pszCode,"CRS27",5) )
    2259               0 :         return SetWellKnownGeogCS( pszCode );
    2260                 : 
    2261                 : /* -------------------------------------------------------------------- */
    2262                 : /*      Handle auto codes.  We need to convert from format              */
    2263                 : /*      AUTO42001:99:8888 to format AUTO:42001,99,8888.                 */
    2264                 : /* -------------------------------------------------------------------- */
    2265               1 :     else if( EQUALN(pszCode,"AUTO",4) )
    2266                 :     {
    2267                 :         char szWMSAuto[100];
    2268                 :         int i;
    2269                 : 
    2270               1 :         if( strlen(pszCode) > sizeof(szWMSAuto)-2 )
    2271               0 :             return OGRERR_FAILURE;
    2272                 : 
    2273               1 :         strcpy( szWMSAuto, "AUTO:" );
    2274               1 :         strcpy( szWMSAuto + 5, pszCode + 4 );
    2275              14 :         for( i = 5; szWMSAuto[i] != '\0'; i++ )
    2276                 :         {
    2277              13 :             if( szWMSAuto[i] == ':' )
    2278               2 :                 szWMSAuto[i] = ',';
    2279                 :         }
    2280                 : 
    2281               1 :         return importFromWMSAUTO( szWMSAuto );
    2282                 :     }
    2283                 : 
    2284                 : /* -------------------------------------------------------------------- */
    2285                 : /*      Not a recognise OGC item.                                       */
    2286                 : /* -------------------------------------------------------------------- */
    2287                 :     CPLError( CE_Failure, CPLE_AppDefined,
    2288                 :               "URN %s value not supported.",
    2289               0 :               pszURN );
    2290                 : 
    2291               0 :     return OGRERR_FAILURE;
    2292                 : }
    2293                 : 
    2294                 : /************************************************************************/
    2295                 : /*                           importFromURN()                            */
    2296                 : /*                                                                      */
    2297                 : /*      See OGC recommendation paper 06-023r1 or later for details.     */
    2298                 : /************************************************************************/
    2299                 : 
    2300                 : /**
    2301                 :  * \brief Initialize from OGC URN. 
    2302                 :  *
    2303                 :  * Initializes this spatial reference from a coordinate system defined
    2304                 :  * by an OGC URN prefixed with "urn:ogc:def:crs:" per recommendation 
    2305                 :  * paper 06-023r1.  Currently EPSG and OGC authority values are supported, 
    2306                 :  * including OGC auto codes, but not including CRS1 or CRS88 (NAVD88). 
    2307                 :  *
    2308                 :  * This method is also support through SetFromUserInput() which can
    2309                 :  * normally be used for URNs.
    2310                 :  * 
    2311                 :  * @param pszURN the urn string. 
    2312                 :  *
    2313                 :  * @return OGRERR_NONE on success or an error code.
    2314                 :  */
    2315                 : 
    2316              75 : OGRErr OGRSpatialReference::importFromURN( const char *pszURN )
    2317                 : 
    2318                 : {
    2319                 :     const char *pszCur;
    2320                 : 
    2321              75 :     if( EQUALN(pszURN,"urn:ogc:def:crs:",16) )
    2322              31 :         pszCur = pszURN + 16;
    2323              44 :     else if( EQUALN(pszURN,"urn:ogc:def:crs,crs:",20) )
    2324               1 :         pszCur = pszURN + 20;
    2325              43 :     else if( EQUALN(pszURN,"urn:x-ogc:def:crs:",18) )
    2326              43 :         pszCur = pszURN + 18;
    2327               0 :     else if( EQUALN(pszURN,"urn:opengis:crs:",16) )
    2328               0 :         pszCur = pszURN + 16;
    2329               0 :     else if( EQUALN(pszURN,"urn:opengis:def:crs:",20) )
    2330               0 :         pszCur = pszURN + 20;
    2331                 :     else
    2332                 :     {
    2333                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2334               0 :                   "URN %s not a supported format.", pszURN );
    2335               0 :         return OGRERR_FAILURE;
    2336                 :     }
    2337                 : 
    2338                 : /* -------------------------------------------------------------------- */
    2339                 : /*      Clear any existing definition.                                  */
    2340                 : /* -------------------------------------------------------------------- */
    2341              75 :     if( GetRoot() != NULL )
    2342                 :     {
    2343               0 :         delete poRoot;
    2344               0 :         poRoot = NULL;
    2345                 :     }
    2346                 : 
    2347                 : /* -------------------------------------------------------------------- */
    2348                 : /*      Find code (ignoring version) out of string like:                */
    2349                 : /*                                                                      */
    2350                 : /*      authority:[version]:code                                        */
    2351                 : /* -------------------------------------------------------------------- */
    2352              75 :     const char *pszAuthority = pszCur;
    2353                 : 
    2354                 :     // skip authority
    2355             448 :     while( *pszCur != ':' && *pszCur )
    2356             298 :         pszCur++;
    2357              75 :     if( *pszCur == ':' )
    2358              75 :         pszCur++;
    2359                 : 
    2360                 :     // skip version
    2361              75 :     const char* pszBeforeVersion = pszCur;
    2362             346 :     while( *pszCur != ':' && *pszCur )
    2363             196 :         pszCur++;
    2364              75 :     if( *pszCur == ':' )
    2365              34 :         pszCur++;
    2366                 :     else
    2367                 :         /* We come here in the case, the content to parse is authority:code (instead of authority::code) */
    2368                 :         /* which is probably illegal according to http://www.opengeospatial.org/ogcUrnPolicy */
    2369                 :         /* but such content is found for example in what is returned by GeoServer */
    2370              41 :         pszCur = pszBeforeVersion;
    2371                 : 
    2372              75 :     const char *pszCode = pszCur;
    2373                 : 
    2374              75 :     const char* pszComma = strchr(pszCur, ',');
    2375              75 :     if (pszComma == NULL)
    2376              74 :         return importFromURNPart(pszAuthority, pszCode, pszURN);
    2377                 : 
    2378                 : 
    2379                 :     /* There's a second part with the vertical SRS */
    2380               1 :     pszCur = pszComma + 1;
    2381               1 :     if (strncmp(pszCur, "crs:", 4) != 0)
    2382                 :     {
    2383                 :         CPLError( CE_Failure, CPLE_AppDefined,
    2384               0 :                   "URN %s not a supported format.", pszURN );
    2385               0 :         return OGRERR_FAILURE;
    2386                 :     }
    2387                 : 
    2388               1 :     pszCur += 4;
    2389                 : 
    2390               1 :     char* pszFirstCode = CPLStrdup(pszCode);
    2391               1 :     pszFirstCode[pszComma - pszCode] = '\0';
    2392               1 :     OGRErr eStatus = importFromURNPart(pszAuthority, pszFirstCode, pszURN);
    2393               1 :     CPLFree(pszFirstCode);
    2394                 : 
    2395                 :     // Do we want to turn this into a compound definition
    2396                 :     // with a vertical datum?
    2397               1 :     if( eStatus == OGRERR_NONE )
    2398                 :     {
    2399               1 :         OGRSpatialReference oVertSRS;
    2400                 : 
    2401                 :     /* -------------------------------------------------------------------- */
    2402                 :     /*      Find code (ignoring version) out of string like:                */
    2403                 :     /*                                                                      */
    2404                 :     /*      authority:[version]:code                                        */
    2405                 :     /* -------------------------------------------------------------------- */
    2406               1 :         pszAuthority = pszCur;
    2407                 : 
    2408                 :         // skip authority
    2409               6 :         while( *pszCur != ':' && *pszCur )
    2410               4 :             pszCur++;
    2411               1 :         if( *pszCur == ':' )
    2412               1 :             pszCur++;
    2413                 : 
    2414                 :         // skip version
    2415               1 :         pszBeforeVersion = pszCur;
    2416               2 :         while( *pszCur != ':' && *pszCur )
    2417               0 :             pszCur++;
    2418               1 :         if( *pszCur == ':' )
    2419               1 :             pszCur++;
    2420                 :         else
    2421               0 :             pszCur = pszBeforeVersion;
    2422                 : 
    2423               1 :         pszCode = pszCur;
    2424                 : 
    2425               1 :         eStatus = oVertSRS.importFromURNPart(pszAuthority, pszCode, pszURN);
    2426               1 :         if( eStatus == OGRERR_NONE )
    2427                 :         {
    2428               1 :             OGR_SRSNode *poHorizSRS = GetRoot()->Clone();
    2429                 : 
    2430               1 :             Clear();
    2431                 : 
    2432               1 :             CPLString osName = poHorizSRS->GetChild(0)->GetValue();
    2433               1 :             osName += " + ";
    2434               1 :             osName += oVertSRS.GetRoot()->GetValue();
    2435                 : 
    2436               1 :             SetNode( "COMPD_CS", osName );
    2437               1 :             GetRoot()->AddChild( poHorizSRS );
    2438               1 :             GetRoot()->AddChild( oVertSRS.GetRoot()->Clone() );
    2439                 :         }
    2440                 : 
    2441               1 :         return eStatus;
    2442                 :     }
    2443                 :     else
    2444               0 :         return eStatus;
    2445                 : }
    2446                 : 
    2447                 : /************************************************************************/
    2448                 : /*                         importFromWMSAUTO()                          */
    2449                 : /************************************************************************/
    2450                 : 
    2451                 : /**
    2452                 :  * \brief Initialize from WMSAUTO string.
    2453                 :  *
    2454                 :  * Note that the WMS 1.3 specification does not include the
    2455                 :  * units code, while apparently earlier specs do.  We try to
    2456                 :  * guess around this.
    2457                 :  *
    2458                 :  * @param pszDefinition the WMSAUTO string
    2459                 :  *
    2460                 :  * @return OGRERR_NONE on success or an error code.
    2461                 :  */
    2462               1 : OGRErr OGRSpatialReference::importFromWMSAUTO( const char * pszDefinition )
    2463                 : 
    2464                 : {
    2465                 :     char **papszTokens;
    2466                 :     int nProjId, nUnitsId;
    2467               1 :     double dfRefLong, dfRefLat = 0.0;
    2468                 :     
    2469                 : /* -------------------------------------------------------------------- */
    2470                 : /*      Tokenize                                                        */
    2471                 : /* -------------------------------------------------------------------- */
    2472               1 :     if( EQUALN(pszDefinition,"AUTO:",5) )
    2473               1 :         pszDefinition += 5;
    2474                 : 
    2475               1 :     papszTokens = CSLTokenizeStringComplex( pszDefinition, ",", FALSE, TRUE );
    2476                 : 
    2477               1 :     if( CSLCount(papszTokens) == 4 )
    2478                 :     {
    2479               0 :         nProjId = atoi(papszTokens[0]);
    2480               0 :         nUnitsId = atoi(papszTokens[1]);
    2481               0 :         dfRefLong = CPLAtof(papszTokens[2]);
    2482               0 :         dfRefLat = CPLAtof(papszTokens[3]);
    2483                 :     }
    2484               1 :     else if( CSLCount(papszTokens) == 3 && atoi(papszTokens[0]) == 42005 )
    2485                 :     {
    2486               0 :         nProjId = atoi(papszTokens[0]);
    2487               0 :         nUnitsId = atoi(papszTokens[1]);
    2488               0 :         dfRefLong = CPLAtof(papszTokens[2]);
    2489               0 :         dfRefLat = 0.0;
    2490                 :     }
    2491               1 :     else if( CSLCount(papszTokens) == 3 )
    2492                 :     {
    2493               1 :         nProjId = atoi(papszTokens[0]);
    2494               1 :         nUnitsId = 9001;
    2495               1 :         dfRefLong = CPLAtof(papszTokens[1]);
    2496               1 :         dfRefLat = CPLAtof(papszTokens[2]);
    2497                 : 
    2498                 :     }
    2499               0 :     else if( CSLCount(papszTokens) == 2 && atoi(papszTokens[0]) == 42005 ) 
    2500                 :     {
    2501               0 :         nProjId = atoi(papszTokens[0]);
    2502               0 :         nUnitsId = 9001;
    2503               0 :         dfRefLong = CPLAtof(papszTokens[1]);
    2504                 :     }
    2505                 :     else
    2506                 :     {
    2507               0 :         CSLDestroy( papszTokens );
    2508                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2509                 :                   "AUTO projection has wrong number of arguments, expected\n"
    2510                 :                   "AUTO:proj_id,units_id,ref_long,ref_lat or"
    2511               0 :                   "AUTO:proj_id,ref_long,ref_lat" );
    2512               0 :         return OGRERR_FAILURE;
    2513                 :     }
    2514                 : 
    2515               1 :     CSLDestroy( papszTokens );
    2516                 : 
    2517                 : /* -------------------------------------------------------------------- */
    2518                 : /*      Build coordsys.                                                 */
    2519                 : /* -------------------------------------------------------------------- */
    2520               1 :     Clear();
    2521                 : 
    2522               1 :     switch( nProjId )
    2523                 :     {
    2524                 :       case 42001: // Auto UTM
    2525                 :         SetUTM( (int) floor( (dfRefLong + 180.0) / 6.0 ) + 1, 
    2526               1 :                 dfRefLat >= 0.0 );
    2527               1 :         break;
    2528                 : 
    2529                 :       case 42002: // Auto TM (strangely very UTM-like).
    2530                 :         SetTM( 0, dfRefLong, 0.9996, 
    2531               0 :                500000.0, (dfRefLat >= 0.0) ? 0.0 : 10000000.0 );
    2532               0 :         break;
    2533                 : 
    2534                 :       case 42003: // Auto Orthographic.
    2535               0 :         SetOrthographic( dfRefLat, dfRefLong, 0.0, 0.0 );
    2536               0 :         break;
    2537                 : 
    2538                 :       case 42004: // Auto Equirectangular
    2539               0 :         SetEquirectangular( dfRefLat, dfRefLong, 0.0, 0.0 );
    2540               0 :         break;
    2541                 : 
    2542                 :       case 42005:
    2543               0 :         SetMollweide( dfRefLong, 0.0, 0.0 );
    2544               0 :         break;
    2545                 : 
    2546                 :       default:
    2547                 :         CPLError( CE_Failure, CPLE_AppDefined,
    2548                 :                   "Unsupported projection id in importFromWMSAUTO(): %d", 
    2549               0 :                   nProjId );
    2550               0 :         return OGRERR_FAILURE;
    2551                 :     }
    2552                 : 
    2553                 : /* -------------------------------------------------------------------- */
    2554                 : /*      Set units.                                                      */
    2555                 : /* -------------------------------------------------------------------- */
    2556                 : 
    2557               1 :     switch( nUnitsId )
    2558                 :     {
    2559                 :       case 9001:
    2560               1 :         SetLinearUnits( SRS_UL_METER, 1.0 );
    2561               1 :         break;
    2562                 : 
    2563                 :       case 9002:
    2564               0 :         SetLinearUnits( "Foot", 0.3048 );
    2565               0 :         break;
    2566                 : 
    2567                 :       case 9003:
    2568               0 :         SetLinearUnits( "US survey foot", CPLAtof(SRS_UL_US_FOOT_CONV) );
    2569               0 :         break;
    2570                 : 
    2571                 :       default:
    2572                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    2573                 :                   "Unsupported units code (%d).", 
    2574               0 :                   nUnitsId );
    2575               0 :         return OGRERR_FAILURE;
    2576                 :         break;
    2577                 :     }
    2578                 :     
    2579               1 :     SetAuthority( "PROJCS|UNIT", "EPSG", nUnitsId );
    2580                 : 
    2581                 : /* -------------------------------------------------------------------- */
    2582                 : /*      Set WGS84.                                                      */
    2583                 : /* -------------------------------------------------------------------- */
    2584               1 :     SetWellKnownGeogCS( "WGS84" );
    2585                 : 
    2586               1 :     return OGRERR_NONE;
    2587                 : }
    2588                 : 
    2589                 : /************************************************************************/
    2590                 : /*                            GetSemiMajor()                            */
    2591                 : /************************************************************************/
    2592                 : 
    2593                 : /**
    2594                 :  * \brief Get spheroid semi major axis.
    2595                 :  *
    2596                 :  * This method does the same thing as the C function OSRGetSemiMajor().
    2597                 :  *
    2598                 :  * @param pnErr if non-NULL set to OGRERR_FAILURE if semi major axis
    2599                 :  * can be found. 
    2600                 :  *
    2601                 :  * @return semi-major axis, or SRS_WGS84_SEMIMAJOR if it can't be found.
    2602                 :  */
    2603                 : 
    2604            2086 : double OGRSpatialReference::GetSemiMajor( OGRErr * pnErr ) const
    2605                 : 
    2606                 : {
    2607            2086 :     const OGR_SRSNode *poSpheroid = GetAttrNode( "SPHEROID" );
    2608                 :     
    2609            2086 :     if( pnErr != NULL )
    2610             927 :         *pnErr = OGRERR_NONE;
    2611                 : 
    2612            2086 :     if( poSpheroid != NULL && poSpheroid->GetChildCount() >= 3 )
    2613                 :     {
    2614            2079 :         return CPLAtof( poSpheroid->GetChild(1)->GetValue() );
    2615                 :     }
    2616                 :     else
    2617                 :     {
    2618               7 :         if( pnErr != NULL )
    2619               2 :             *pnErr = OGRERR_FAILURE;
    2620                 : 
    2621               7 :         return SRS_WGS84_SEMIMAJOR;
    2622                 :     }
    2623                 : }
    2624                 : 
    2625                 : /************************************************************************/
    2626                 : /*                          OSRGetSemiMajor()                           */
    2627                 : /************************************************************************/
    2628                 : 
    2629                 : /**
    2630                 :  * \brief Get spheroid semi major axis.
    2631                 :  *
    2632                 :  * This function is the same as OGRSpatialReference::GetSemiMajor()
    2633                 :  */
    2634               4 : double OSRGetSemiMajor( OGRSpatialReferenceH hSRS, OGRErr *pnErr )
    2635                 : 
    2636                 : {
    2637               4 :     VALIDATE_POINTER1( hSRS, "OSRGetSemiMajor", 0 );
    2638                 : 
    2639               4 :     return ((OGRSpatialReference *) hSRS)->GetSemiMajor( pnErr );
    2640                 : }
    2641                 : 
    2642                 : /************************************************************************/
    2643                 : /*                          GetInvFlattening()                          */
    2644                 : /************************************************************************/
    2645                 : 
    2646                 : /**
    2647                 :  * \brief Get spheroid inverse flattening.
    2648                 :  *
    2649                 :  * This method does the same thing as the C function OSRGetInvFlattening().
    2650                 :  *
    2651                 :  * @param pnErr if non-NULL set to OGRERR_FAILURE if no inverse flattening 
    2652                 :  * can be found. 
    2653                 :  *
    2654                 :  * @return inverse flattening, or SRS_WGS84_INVFLATTENING if it can't be found.
    2655                 :  */
    2656                 : 
    2657            1940 : double OGRSpatialReference::GetInvFlattening( OGRErr * pnErr ) const
    2658                 : 
    2659                 : {
    2660            1940 :     const OGR_SRSNode *poSpheroid = GetAttrNode( "SPHEROID" );
    2661                 :     
    2662            1940 :     if( pnErr != NULL )
    2663             927 :         *pnErr = OGRERR_NONE;
    2664                 : 
    2665            1940 :     if( poSpheroid != NULL && poSpheroid->GetChildCount() >= 3 )
    2666                 :     {
    2667            1933 :         return CPLAtof( poSpheroid->GetChild(2)->GetValue() );
    2668                 :     }
    2669                 :     else
    2670                 :     {
    2671               7 :         if( pnErr != NULL )
    2672               2 :             *pnErr = OGRERR_FAILURE;
    2673                 : 
    2674               7 :         return SRS_WGS84_INVFLATTENING;
    2675                 :     }
    2676                 : }
    2677                 : 
    2678                 : /************************************************************************/
    2679                 : /*                        OSRGetInvFlattening()                         */
    2680                 : /************************************************************************/
    2681                 : 
    2682                 : /**
    2683                 :  * \brief Get spheroid inverse flattening.
    2684                 :  *
    2685                 :  * This function is the same as OGRSpatialReference::GetInvFlattening()
    2686                 :  */
    2687               4 : double OSRGetInvFlattening( OGRSpatialReferenceH hSRS, OGRErr *pnErr )
    2688                 : 
    2689                 : {
    2690               4 :     VALIDATE_POINTER1( hSRS, "OSRGetInvFlattening", 0 );
    2691                 : 
    2692               4 :     return ((OGRSpatialReference *) hSRS)->GetInvFlattening( pnErr );
    2693                 : }
    2694                 : 
    2695                 : /************************************************************************/
    2696                 : /*                            GetSemiMinor()                            */
    2697                 : /************************************************************************/
    2698                 : 
    2699                 : /**
    2700                 :  * \brief Get spheroid semi minor axis.
    2701                 :  *
    2702                 :  * This method does the same thing as the C function OSRGetSemiMinor().
    2703                 :  *
    2704                 :  * @param pnErr if non-NULL set to OGRERR_FAILURE if semi minor axis
    2705                 :  * can be found. 
    2706                 :  *
    2707                 :  * @return semi-minor axis, or WGS84 semi minor if it can't be found.
    2708                 :  */
    2709                 : 
    2710             180 : double OGRSpatialReference::GetSemiMinor( OGRErr * pnErr ) const
    2711                 : 
    2712                 : {
    2713                 :     double      dfInvFlattening, dfSemiMajor;
    2714                 : 
    2715             180 :     dfSemiMajor = GetSemiMajor( pnErr );
    2716             180 :     dfInvFlattening = GetInvFlattening( pnErr );
    2717                 : 
    2718             180 :     if( ABS(dfInvFlattening) < 0.000000000001 )
    2719              20 :         return dfSemiMajor;
    2720                 :     else
    2721             160 :         return dfSemiMajor * (1.0 - 1.0/dfInvFlattening);
    2722                 : }
    2723                 : 
    2724                 : /************************************************************************/
    2725                 : /*                          OSRGetSemiMinor()                           */
    2726                 : /************************************************************************/
    2727                 : 
    2728                 : /**
    2729                 :  * \brief Get spheroid semi minor axis.
    2730                 :  *
    2731                 :  * This function is the same as OGRSpatialReference::GetSemiMinor()
    2732                 :  */
    2733               3 : double OSRGetSemiMinor( OGRSpatialReferenceH hSRS, OGRErr *pnErr )
    2734                 : 
    2735                 : {
    2736               3 :     VALIDATE_POINTER1( hSRS, "OSRGetSemiMinor", 0 );
    2737                 : 
    2738               3 :     return ((OGRSpatialReference *) hSRS)->GetSemiMinor( pnErr );
    2739                 : }
    2740                 : 
    2741                 : /************************************************************************/
    2742                 : /*                             SetLocalCS()                             */
    2743                 : /************************************************************************/
    2744                 : 
    2745                 : /**
    2746                 :  * \brief Set the user visible LOCAL_CS name.
    2747                 :  *
    2748                 :  * This method is the same as the C function OSRSetLocalCS(). 
    2749                 :  *
    2750                 :  * This method will ensure a LOCAL_CS node is created as the root,
    2751                 :  * and set the provided name on it.  It must be used before SetLinearUnits().
    2752                 :  *
    2753                 :  * @param pszName the user visible name to assign.  Not used as a key.
    2754                 :  * 
    2755                 :  * @return OGRERR_NONE on success.
    2756                 :  */
    2757                 : 
    2758              41 : OGRErr OGRSpatialReference::SetLocalCS( const char * pszName )
    2759                 : 
    2760                 : {
    2761              41 :     OGR_SRSNode *poCS = GetAttrNode( "LOCAL_CS" );
    2762                 : 
    2763              41 :     if( poCS == NULL && GetRoot() != NULL )
    2764                 :     {
    2765                 :         CPLDebug( "OGR", 
    2766                 :                   "OGRSpatialReference::SetLocalCS(%s) failed.\n"
    2767                 :                "It appears an incompatible root node (%s) already exists.\n",
    2768               0 :                   pszName, GetRoot()->GetValue() );
    2769               0 :         return OGRERR_FAILURE;
    2770                 :     }
    2771                 :     else
    2772                 :     {
    2773              41 :         SetNode( "LOCAL_CS", pszName );
    2774              41 :         return OGRERR_NONE;
    2775                 :     }
    2776                 : }
    2777                 : 
    2778                 : /************************************************************************/
    2779                 : /*                           OSRSetLocalCS()                            */
    2780                 : /************************************************************************/
    2781                 : 
    2782                 : /**
    2783                 :  * \brief Set the user visible LOCAL_CS name.
    2784                 :  *
    2785                 :  * This function is the same as OGRSpatialReference::SetLocalCS()
    2786                 :  */
    2787               0 : OGRErr OSRSetLocalCS( OGRSpatialReferenceH hSRS, const char * pszName )
    2788                 : 
    2789                 : {
    2790               0 :     VALIDATE_POINTER1( hSRS, "OSRSetLocalCS", CE_Failure );
    2791                 : 
    2792               0 :     return ((OGRSpatialReference *) hSRS)->SetLocalCS( pszName );
    2793                 : }
    2794                 : 
    2795                 : /************************************************************************/
    2796                 : /*                             SetGeocCS()                              */
    2797                 : /************************************************************************/
    2798                 : 
    2799                 : /**
    2800                 :  * \brief Set the user visible GEOCCS name.
    2801                 :  *
    2802                 :  * This method is the same as the C function OSRSetGeocCS(). 
    2803                 : 
    2804                 :  * This method will ensure a GEOCCS node is created as the root,
    2805                 :  * and set the provided name on it.  If used on a GEOGCS coordinate system, 
    2806                 :  * the DATUM and PRIMEM nodes from the GEOGCS will be tarnsferred over to 
    2807                 :  * the GEOGCS. 
    2808                 :  *
    2809                 :  * @param pszName the user visible name to assign.  Not used as a key.
    2810                 :  * 
    2811                 :  * @return OGRERR_NONE on success.
    2812                 :  *
    2813                 :  * @since OGR 1.9.0
    2814                 :  */
    2815                 : 
    2816               9 : OGRErr OGRSpatialReference::SetGeocCS( const char * pszName )
    2817                 : 
    2818                 : {
    2819               9 :     OGR_SRSNode *poGeogCS = NULL;
    2820               9 :     OGR_SRSNode *poGeocCS = GetAttrNode( "GEOCCS" );
    2821                 : 
    2822               9 :     if( poRoot != NULL && EQUAL(poRoot->GetValue(),"GEOGCS") )
    2823                 :     {
    2824               2 :         poGeogCS = poRoot;
    2825               2 :         poRoot = NULL;
    2826                 :     }
    2827                 : 
    2828               9 :     if( poGeocCS == NULL && GetRoot() != NULL )
    2829                 :     {
    2830                 :         CPLDebug( "OGR", 
    2831                 :                   "OGRSpatialReference::SetGeocCS(%s) failed.\n"
    2832                 :                "It appears an incompatible root node (%s) already exists.\n",
    2833               1 :                   pszName, GetRoot()->GetValue() );
    2834               1 :         return OGRERR_FAILURE;
    2835                 :     }
    2836                 : 
    2837               8 :     SetNode( "GEOCCS", pszName );
    2838                 : 
    2839               8 :     if( poGeogCS != NULL )
    2840                 :     {
    2841               2 :         OGR_SRSNode *poDatum = poGeogCS->GetNode( "DATUM" );
    2842               2 :         OGR_SRSNode *poPRIMEM = poGeogCS->GetNode( "PRIMEM" );
    2843               2 :         if ( poDatum != NULL && poPRIMEM != NULL )
    2844                 :         {
    2845               1 :             poRoot->InsertChild( poDatum->Clone(), 1 );
    2846               1 :             poRoot->InsertChild( poPRIMEM->Clone(), 2 );
    2847                 :         }
    2848               2 :         delete poGeogCS;
    2849                 :     }
    2850                 : 
    2851               8 :     return OGRERR_NONE;
    2852                 : }
    2853                 : 
    2854                 : /************************************************************************/
    2855                 : /*                            OSRSetGeocCS()                            */
    2856                 : /************************************************************************/
    2857                 : 
    2858                 : /**
    2859                 :  * \brief Set the user visible PROJCS name.
    2860                 :  *
    2861                 :  * This function is the same as OGRSpatialReference::SetGeocCS()
    2862                 :  *
    2863                 :  * @since OGR 1.9.0
    2864                 :  */
    2865               5 : OGRErr OSRSetGeocCS( OGRSpatialReferenceH hSRS, const char * pszName )
    2866                 : 
    2867                 : {
    2868               5 :     VALIDATE_POINTER1( hSRS, "OSRSetGeocCS", CE_Failure );
    2869                 : 
    2870               5 :     return ((OGRSpatialReference *) hSRS)->SetGeocCS( pszName );
    2871                 : }
    2872                 : 
    2873                 : /************************************************************************/
    2874                 : /*                             SetVertCS()                              */
    2875                 : /************************************************************************/
    2876                 : 
    2877                 : /**
    2878                 :  * \brief Set the user visible VERT_CS name.
    2879                 :  *
    2880                 :  * This method is the same as the C function OSRSetVertCS(). 
    2881                 : 
    2882                 :  * This method will ensure a VERT_CS node is created if needed.  If the
    2883                 :  * existing coordinate system is GEOGCS or PROJCS rooted, then it will be
    2884                 :  * turned into a COMPD_CS.
    2885                 :  *
    2886                 :  * @param pszVertCSName the user visible name of the vertical coordinate
    2887                 :  * system. Not used as a key.
    2888                 :  *  
    2889                 :  * @param pszVertDatumName the user visible name of the vertical datum.  It
    2890                 :  * is helpful if this matches the EPSG name.
    2891                 :  * 
    2892                 :  * @param nVertDatumType the OGC vertical datum type, usually 2005. 
    2893                 :  * 
    2894                 :  * @return OGRERR_NONE on success.
    2895                 :  *
    2896                 :  * @since OGR 1.9.0
    2897                 :  */
    2898                 : 
    2899               8 : OGRErr OGRSpatialReference::SetVertCS( const char * pszVertCSName,
    2900                 :                                        const char * pszVertDatumName,
    2901                 :                                        int nVertDatumType )
    2902                 : 
    2903                 : {
    2904                 : /* -------------------------------------------------------------------- */
    2905                 : /*      Handle the case where we want to make a compound coordinate     */
    2906                 : /*      system.                                                         */
    2907                 : /* -------------------------------------------------------------------- */
    2908               8 :     if( IsProjected() || IsGeographic() )
    2909                 :     {
    2910               0 :         OGR_SRSNode *poNewRoot = new OGR_SRSNode( "COMPD_CS" );
    2911               0 :         poNewRoot->AddChild( poRoot );
    2912               0 :         poRoot = poNewRoot;
    2913                 :     }
    2914                 : 
    2915               8 :     else if( GetAttrNode( "VERT_CS" ) == NULL )
    2916               8 :         Clear();
    2917                 : 
    2918                 : /* -------------------------------------------------------------------- */
    2919                 : /*      If we already have a VERT_CS, wipe and recreate the root        */
    2920                 : /*      otherwise create the VERT_CS now.                               */
    2921                 : /* -------------------------------------------------------------------- */
    2922               8 :     OGR_SRSNode *poVertCS = GetAttrNode( "VERT_CS" );
    2923                 :     
    2924               8 :     if( poVertCS != NULL )
    2925                 :     {
    2926               0 :         poVertCS->ClearChildren();
    2927                 :     }
    2928                 :     else
    2929                 :     {
    2930               8 :         poVertCS = new OGR_SRSNode( "VERT_CS" );
    2931               8 :         if( poRoot != NULL && EQUAL(poRoot->GetValue(),"COMPD_CS") )
    2932                 :         {
    2933               0 :             poRoot->AddChild( poVertCS );
    2934                 :         }
    2935                 :         else
    2936               8 :             SetRoot( poVertCS );
    2937                 :     }
    2938                 : 
    2939                 : /* -------------------------------------------------------------------- */
    2940                 : /*      Set the name, datumname, and type.                              */
    2941                 : /* -------------------------------------------------------------------- */
    2942                 :     OGR_SRSNode *poVertDatum;
    2943                 : 
    2944               8 :     poVertCS->AddChild( new OGR_SRSNode( pszVertCSName ) );
    2945                 :     
    2946              16 :     poVertDatum = new OGR_SRSNode( "VERT_DATUM" );
    2947               8 :     poVertCS->AddChild( poVertDatum );
    2948                 :         
    2949              16 :     poVertDatum->AddChild( new OGR_SRSNode( pszVertDatumName ) );
    2950                 : 
    2951               8 :     CPLString osVertDatumType;
    2952               8 :     osVertDatumType.Printf( "%d", nVertDatumType );
    2953               8 :     poVertDatum->AddChild( new OGR_SRSNode( osVertDatumType ) );
    2954                 : 
    2955                 :     // add default axis node.
    2956               8 :     OGR_SRSNode *poAxis = new OGR_SRSNode( "AXIS" );
    2957                 : 
    2958              16 :     poAxis->AddChild( new OGR_SRSNode( "Up" ) );
    2959               8 :     poAxis->AddChild( new OGR_SRSNode( "UP" ) );
    2960                 : 
    2961               8 :     poVertCS->AddChild( poAxis );
    2962                 : 
    2963               8 :     return OGRERR_NONE;
    2964                 : }
    2965                 : 
    2966                 : /************************************************************************/
    2967                 : /*                            OSRSetVertCS()                            */
    2968                 : /************************************************************************/
    2969                 : 
    2970                 : /**
    2971                 :  * \brief Setup the vertical coordinate system.
    2972                 :  *
    2973                 :  * This function is the same as OGRSpatialReference::SetVertCS()
    2974                 :  *
    2975                 :  * @since OGR 1.9.0
    2976                 :  */
    2977               0 : OGRErr OSRSetVertCS( OGRSpatialReferenceH hSRS,
    2978                 :                      const char * pszVertCSName,
    2979                 :                      const char * pszVertDatumName,
    2980                 :                      int nVertDatumType )
    2981                 : 
    2982                 : {
    2983               0 :     VALIDATE_POINTER1( hSRS, "OSRSetVertCS", CE_Failure );
    2984                 : 
    2985                 :     return ((OGRSpatialReference *) hSRS)->SetVertCS( pszVertCSName,
    2986                 :                                                       pszVertDatumName,
    2987               0 :                                                       nVertDatumType );
    2988                 : }
    2989                 : 
    2990                 : /************************************************************************/
    2991                 : /*                           SetCompoundCS()                            */
    2992                 : /************************************************************************/
    2993                 : 
    2994                 : /**
    2995                 :  * \brief Setup a compound coordinate system.
    2996                 :  *
    2997                 :  * This method is the same as the C function OSRSetCompoundCS(). 
    2998                 : 
    2999                 :  * This method is replace the current SRS with a COMPD_CS coordinate system
    3000                 :  * consisting of the passed in horizontal and vertical coordinate systems.
    3001                 :  *
    3002                 :  * @param pszName the name of the compound coordinate system. 
    3003                 :  * 
    3004                 :  * @param poHorizSRS the horizontal SRS (PROJCS or GEOGCS).
    3005                 :  *  
    3006                 :  * @param poVertSRS the vertical SRS (VERT_CS).
    3007                 :  * 
    3008                 :  * @return OGRERR_NONE on success.
    3009                 :  */
    3010                 : 
    3011                 : OGRErr 
    3012               1 : OGRSpatialReference::SetCompoundCS( const char *pszName,
    3013                 :                                     const OGRSpatialReference *poHorizSRS,
    3014                 :                                     const OGRSpatialReference *poVertSRS )
    3015                 : 
    3016                 : {
    3017                 : /* -------------------------------------------------------------------- */
    3018                 : /*      Verify these are legal horizontal and vertical coordinate       */
    3019                 : /*      systems.                                                        */
    3020                 : /* -------------------------------------------------------------------- */
    3021               1 :     if( !poVertSRS->IsVertical() ) 
    3022                 :     {
    3023                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    3024               0 :                   "SetCompoundCS() fails, vertical component is not VERT_CS." );
    3025               0 :         return OGRERR_FAILURE;
    3026                 :     }
    3027               1 :     if( !poHorizSRS->IsProjected() 
    3028                 :         && !poHorizSRS->IsGeographic() )
    3029                 :     {
    3030                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    3031               0 :                   "SetCompoundCS() fails, horizontal component is not PROJCS or GEOGCS." );
    3032               0 :         return OGRERR_FAILURE;
    3033                 :     }
    3034                 : 
    3035                 : /* -------------------------------------------------------------------- */
    3036                 : /*      Replace with compound srs.                                      */
    3037                 : /* -------------------------------------------------------------------- */
    3038               1 :     Clear();
    3039                 : 
    3040               1 :     poRoot = new OGR_SRSNode( "COMPD_CS" );
    3041               2 :     poRoot->AddChild( new OGR_SRSNode( pszName ) );
    3042               1 :     poRoot->AddChild( poHorizSRS->GetRoot()->Clone() );
    3043               1 :     poRoot->AddChild( poVertSRS->GetRoot()->Clone() );
    3044                 :     
    3045               1 :     return OGRERR_NONE;
    3046                 : }
    3047                 : 
    3048                 : /************************************************************************/
    3049                 : /*                          OSRSetCompoundCS()                          */
    3050                 : /************************************************************************/
    3051                 : 
    3052                 : /**
    3053                 :  * \brief Setup a compound coordinate system.
    3054                 :  *
    3055                 :  * This function is the same as OGRSpatialReference::SetCompoundCS()
    3056                 :  */
    3057               1 : OGRErr OSRSetCompoundCS( OGRSpatialReferenceH hSRS,
    3058                 :                          const char *pszName,
    3059                 :                          OGRSpatialReferenceH hHorizSRS,
    3060                 :                          OGRSpatialReferenceH hVertSRS )
    3061                 : 
    3062                 : {
    3063               1 :     VALIDATE_POINTER1( hSRS, "OSRSetCompoundCS", CE_Failure );
    3064               1 :     VALIDATE_POINTER1( hHorizSRS, "OSRSetCompoundCS", CE_Failure );
    3065               1 :     VALIDATE_POINTER1( hVertSRS, "OSRSetCompoundCS", CE_Failure );
    3066                 : 
    3067                 :     return ((OGRSpatialReference *) hSRS)->
    3068                 :         SetCompoundCS( pszName,
    3069                 :                        (OGRSpatialReference *) hHorizSRS,
    3070               1 :                        (OGRSpatialReference *) hVertSRS );
    3071                 : }
    3072                 : 
    3073                 : /************************************************************************/
    3074                 : /*                             SetProjCS()                              */
    3075                 : /************************************************************************/
    3076                 : 
    3077                 : /**
    3078                 :  * \brief Set the user visible PROJCS name.
    3079                 :  *
    3080                 :  * This method is the same as the C function OSRSetProjCS(). 
    3081                 :  *
    3082                 :  * This method will ensure a PROJCS node is created as the root,
    3083                 :  * and set the provided name on it.  If used on a GEOGCS coordinate system, 
    3084                 :  * the GEOGCS node will be demoted to be a child of the new PROJCS root.
    3085                 :  *
    3086                 :  * @param pszName the user visible name to assign.  Not used as a key.
    3087                 :  * 
    3088                 :  * @return OGRERR_NONE on success.
    3089                 :  */
    3090                 : 
    3091              98 : OGRErr OGRSpatialReference::SetProjCS( const char * pszName )
    3092                 : 
    3093                 : {
    3094              98 :     OGR_SRSNode *poGeogCS = NULL;
    3095              98 :     OGR_SRSNode *poProjCS = GetAttrNode( "PROJCS" );
    3096                 : 
    3097              98 :     if( poRoot != NULL && EQUAL(poRoot->GetValue(),"GEOGCS") )
    3098                 :     {
    3099               6 :         poGeogCS = poRoot;
    3100               6 :         poRoot = NULL;
    3101                 :     }
    3102                 : 
    3103              98 :     if( poProjCS == NULL && GetRoot() != NULL )
    3104                 :     {
    3105                 :         CPLDebug( "OGR", 
    3106                 :                   "OGRSpatialReference::SetProjCS(%s) failed.\n"
    3107                 :                "It appears an incompatible root node (%s) already exists.\n",
    3108               0 :                   pszName, GetRoot()->GetValue() );
    3109               0 :         return OGRERR_FAILURE;
    3110                 :     }
    3111                 : 
    3112              98 :     SetNode( "PROJCS", pszName );
    3113                 : 
    3114              98 :     if( poGeogCS != NULL )
    3115               6 :         poRoot->InsertChild( poGeogCS, 1 );
    3116                 : 
    3117              98 :     return OGRERR_NONE;
    3118                 : }
    3119                 : 
    3120                 : /************************************************************************/
    3121                 : /*                            OSRSetProjCS()                            */
    3122                 : /************************************************************************/
    3123                 : 
    3124                 : /**
    3125                 :  * \brief Set the user visible PROJCS name.
    3126                 :  *
    3127                 :  * This function is the same as OGRSpatialReference::SetProjCS()
    3128                 :  */
    3129               2 : OGRErr OSRSetProjCS( OGRSpatialReferenceH hSRS, const char * pszName )
    3130                 : 
    3131                 : {
    3132               2 :     VALIDATE_POINTER1( hSRS, "OSRSetProjCS", CE_Failure );
    3133                 : 
    3134               2 :     return ((OGRSpatialReference *) hSRS)->SetProjCS( pszName );
    3135                 : }
    3136                 : 
    3137                 : /************************************************************************/
    3138                 : /*                           SetProjection()                            */
    3139                 : /************************************************************************/
    3140                 : 
    3141                 : /**
    3142                 :  * \brief Set a projection name.
    3143                 :  *
    3144                 :  * This method is the same as the C function OSRSetProjection().
    3145                 :  *
    3146                 :  * @param pszProjection the projection name, which should be selected from
    3147                 :  * the macros in ogr_srs_api.h, such as SRS_PT_TRANSVERSE_MERCATOR. 
    3148                 :  *
    3149                 :  * @return OGRERR_NONE on success.
    3150                 :  */
    3151                 : 
    3152           12381 : OGRErr OGRSpatialReference::SetProjection( const char * pszProjection )
    3153                 : 
    3154                 : {
    3155           12381 :     OGR_SRSNode *poGeogCS = NULL;
    3156                 :     OGRErr eErr;
    3157                 : 
    3158           12381 :     if( poRoot != NULL && EQUAL(poRoot->GetValue(),"GEOGCS") )
    3159                 :     {
    3160             113 :         poGeogCS = poRoot;
    3161             113 :         poRoot = NULL;
    3162                 :     }
    3163                 : 
    3164           12381 :     if( !GetAttrNode( "PROJCS" ) )
    3165                 :     {
    3166             386 :         SetNode( "PROJCS", "unnamed" );
    3167                 :     }
    3168                 : 
    3169           12381 :     eErr = SetNode( "PROJCS|PROJECTION", pszProjection );
    3170           12381 :     if( eErr != OGRERR_NONE )
    3171               0 :         return eErr;
    3172                 : 
    3173           12381 :     if( poGeogCS != NULL )
    3174             113 :         poRoot->InsertChild( poGeogCS, 1 );
    3175                 : 
    3176           12381 :     return OGRERR_NONE;
    3177                 : }
    3178                 : 
    3179                 : /************************************************************************/
    3180                 : /*                            OSRSetProjection()                        */
    3181                 : /************************************************************************/
    3182                 : 
    3183                 : /**
    3184                 :  * \brief Set a projection name.
    3185                 :  *
    3186                 :  * This function is the same as OGRSpatialReference::SetProjection()
    3187                 :  */
    3188               0 : OGRErr OSRSetProjection( OGRSpatialReferenceH hSRS,
    3189                 :                          const char * pszProjection )
    3190                 : 
    3191                 : {
    3192               0 :     return ((OGRSpatialReference *) hSRS)->SetProjection( pszProjection );
    3193                 : }
    3194                 : 
    3195                 : /************************************************************************/
    3196                 : /*                            SetProjParm()                             */
    3197                 : /************************************************************************/
    3198                 : 
    3199                 : /**
    3200                 :  * \brief Set a projection parameter value.
    3201                 :  *
    3202                 :  * Adds a new PARAMETER under the PROJCS with the indicated name and value.
    3203                 :  *
    3204                 :  * This method is the same as the C function OSRSetProjParm().
    3205                 :  *
    3206                 :  * Please check http://www.remotesensing.org/geotiff/proj_list pages for
    3207                 :  * legal parameter names for specific projections.
    3208                 :  *
    3209                 :  * 
    3210                 :  * @param pszParmName the parameter name, which should be selected from
    3211                 :  * the macros in ogr_srs_api.h, such as SRS_PP_CENTRAL_MERIDIAN. 
    3212                 :  *
    3213                 :  * @param dfValue value to assign. 
    3214                 :  * 
    3215                 :  * @return OGRERR_NONE on success.
    3216                 :  */
    3217                 : 
    3218           64052 : OGRErr OGRSpatialReference::SetProjParm( const char * pszParmName,
    3219                 :                                          double dfValue )
    3220                 : 
    3221                 : {
    3222           64052 :     OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
    3223                 :     OGR_SRSNode *poParm;
    3224                 :     char        szValue[64];
    3225                 : 
    3226           64052 :     if( poPROJCS == NULL )
    3227               2 :         return OGRERR_FAILURE;
    3228                 : 
    3229           64050 :     OGRPrintDouble( szValue, dfValue );
    3230                 : 
    3231                 : /* -------------------------------------------------------------------- */
    3232                 : /*      Try to find existing parameter with this name.                  */
    3233                 : /* -------------------------------------------------------------------- */
    3234          451581 :     for( int iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
    3235                 :     {
    3236          387572 :         poParm = poPROJCS->GetChild( iChild );
    3237                 : 
    3238          387572 :         if( EQUAL(poParm->GetValue(),"PARAMETER")
    3239                 :             && poParm->GetChildCount() == 2 
    3240                 :             && EQUAL(poParm->GetChild(0)->GetValue(),pszParmName) )
    3241                 :         {
    3242              41 :             poParm->GetChild(1)->SetValue( szValue );
    3243              41 :             return OGRERR_NONE;
    3244                 :         }
    3245                 :     }
    3246                 :     
    3247                 : /* -------------------------------------------------------------------- */
    3248                 : /*      Otherwise create a new parameter and append.                    */
    3249                 : /* -------------------------------------------------------------------- */
    3250           64009 :     poParm = new OGR_SRSNode( "PARAMETER" );
    3251          128018 :     poParm->AddChild( new OGR_SRSNode( pszParmName ) );
    3252          128018 :     poParm->AddChild( new OGR_SRSNode( szValue ) );
    3253                 : 
    3254           64009 :     poPROJCS->AddChild( poParm );
    3255                 : 
    3256           64009 :     return OGRERR_NONE;
    3257                 : }
    3258                 : 
    3259                 : /************************************************************************/
    3260                 : /*                           OSRSetProjParm()                           */
    3261                 : /************************************************************************/
    3262                 : 
    3263                 : /**
    3264                 :  * \brief Set a projection parameter value.
    3265                 :  *
    3266                 :  * This function is the same as OGRSpatialReference::SetProjParm()
    3267                 :  */
    3268             142 : OGRErr OSRSetProjParm( OGRSpatialReferenceH hSRS, 
    3269                 :                        const char * pszParmName, double dfValue )
    3270                 : 
    3271                 : {
    3272             142 :     VALIDATE_POINTER1( hSRS, "OSRSetProjParm", CE_Failure );
    3273                 : 
    3274             142 :     return ((OGRSpatialReference *) hSRS)->SetProjParm( pszParmName, dfValue );
    3275                 : }
    3276                 : 
    3277                 : /************************************************************************/
    3278                 : /*                            FindProjParm()                            */
    3279                 : /************************************************************************/
    3280                 : 
    3281                 : /**
    3282                 :   * \brief Return the child index of the named projection parameter on
    3283                 :   * its parent PROJCS node.
    3284                 :   *
    3285                 :   * @param pszParameter projection parameter to look for
    3286                 :   * @param poPROJCS projection CS node to look in. If NULL is passed,
    3287                 :   *        the PROJCS node of the SpatialReference object will be searched.
    3288                 :   *
    3289                 :   * @return the child index of the named projection parameter. -1 on failure
    3290                 :   */
    3291          169473 : int OGRSpatialReference::FindProjParm( const char *pszParameter,
    3292                 :                                        const OGR_SRSNode *poPROJCS ) const
    3293                 : 
    3294                 : {
    3295          169473 :     const OGR_SRSNode *poParameter = NULL;
    3296                 : 
    3297          169473 :     if( poPROJCS == NULL )
    3298             960 :         poPROJCS = GetAttrNode( "PROJCS" );
    3299                 : 
    3300          169473 :     if( poPROJCS == NULL )
    3301             931 :         return -1;
    3302                 : 
    3303                 : /* -------------------------------------------------------------------- */
    3304                 : /*      Search for requested parameter.                                 */
    3305                 : /* -------------------------------------------------------------------- */
    3306                 :     int iChild;
    3307                 : 
    3308         1083323 :     for( iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
    3309                 :     {
    3310         1075012 :         poParameter = poPROJCS->GetChild(iChild);
    3311                 :         
    3312         1075012 :         if( EQUAL(poParameter->GetValue(),"PARAMETER")
    3313                 :             && poParameter->GetChildCount() == 2 
    3314                 :             && EQUAL(poPROJCS->GetChild(iChild)->GetChild(0)->GetValue(),
    3315                 :                      pszParameter) )
    3316                 :         {
    3317          160231 :             return iChild;
    3318                 :         }
    3319                 :     }
    3320                 : 
    3321                 : /* -------------------------------------------------------------------- */
    3322                 : /*      Try similar names, for selected parameters.                     */
    3323                 : /* -------------------------------------------------------------------- */
    3324            8311 :     iChild = -1;
    3325                 : 
    3326            8311 :     if( EQUAL(pszParameter,SRS_PP_LATITUDE_OF_ORIGIN) )
    3327                 :     {
    3328              97 :         iChild = FindProjParm( SRS_PP_LATITUDE_OF_CENTER, poPROJCS );
    3329                 :     }
    3330            8214 :     else if( EQUAL(pszParameter,SRS_PP_CENTRAL_MERIDIAN) )
    3331                 :     {
    3332              41 :         iChild = FindProjParm(SRS_PP_LONGITUDE_OF_CENTER, poPROJCS );
    3333              41 :         if( iChild == -1 )
    3334               3 :             iChild = FindProjParm(SRS_PP_LONGITUDE_OF_ORIGIN, poPROJCS );
    3335                 :     }
    3336                 : 
    3337            8311 :     return iChild;
    3338                 : }
    3339                 : 
    3340                 : /************************************************************************/
    3341                 : /*                            GetProjParm()                             */
    3342                 : /************************************************************************/
    3343                 : 
    3344                 : /**
    3345                 :  * \brief Fetch a projection parameter value.
    3346                 :  *
    3347                 :  * NOTE: This code should be modified to translate non degree angles into
    3348                 :  * degrees based on the GEOGCS unit.  This has not yet been done.
    3349                 :  *
    3350                 :  * This method is the same as the C function OSRGetProjParm().
    3351                 :  *
    3352                 :  * @param pszName the name of the parameter to fetch, from the set of 
    3353                 :  * SRS_PP codes in ogr_srs_api.h.
    3354                 :  *
    3355                 :  * @param dfDefaultValue the value to return if this parameter doesn't exist.
    3356                 :  *
    3357                 :  * @param pnErr place to put error code on failure.  Ignored if NULL.
    3358                 :  *
    3359                 :  * @return value of parameter.
    3360                 :  */
    3361                 : 
    3362          166000 : double OGRSpatialReference::GetProjParm( const char * pszName,
    3363                 :                                          double dfDefaultValue,
    3364                 :                                          OGRErr *pnErr ) const
    3365                 : 
    3366                 : {
    3367          166000 :     const OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
    3368                 : 
    3369          166000 :     if( pnErr != NULL )
    3370           20249 :         *pnErr = OGRERR_NONE;
    3371                 :     
    3372                 : /* -------------------------------------------------------------------- */
    3373                 : /*      Find the desired parameter.                                     */
    3374                 : /* -------------------------------------------------------------------- */
    3375          166000 :     int iChild = FindProjParm( pszName, poPROJCS );
    3376                 : 
    3377          166000 :     if( iChild != -1 )
    3378                 :     {
    3379          157361 :         const OGR_SRSNode *poParameter = NULL;
    3380          157361 :         poParameter = poPROJCS->GetChild(iChild);
    3381          157361 :         return CPLAtof(poParameter->GetChild(1)->GetValue());
    3382                 :     }
    3383                 : 
    3384                 : /* -------------------------------------------------------------------- */
    3385                 : /*      Return default value on failure.                                */
    3386                 : /* -------------------------------------------------------------------- */
    3387            8639 :     if( pnErr != NULL )
    3388              37 :         *pnErr = OGRERR_FAILURE;
    3389                 : 
    3390            8639 :     return dfDefaultValue;
    3391                 : }
    3392                 : 
    3393                 : /************************************************************************/
    3394                 : /*                           OSRGetProjParm()                           */
    3395                 : /************************************************************************/
    3396                 : 
    3397                 : /**
    3398                 :  * \brief Fetch a projection parameter value.
    3399                 :  *
    3400                 :  * This function is the same as OGRSpatialReference::GetProjParm()
    3401                 :  */
    3402            8638 : double OSRGetProjParm( OGRSpatialReferenceH hSRS, const char *pszName,
    3403                 :                        double dfDefaultValue, OGRErr *pnErr )
    3404                 : 
    3405                 : {
    3406            8638 :     VALIDATE_POINTER1( hSRS, "OSRGetProjParm", 0 );
    3407                 : 
    3408                 :     return ((OGRSpatialReference *) hSRS)->
    3409            8638 :         GetProjParm(pszName, dfDefaultValue, pnErr);
    3410                 : }
    3411                 : 
    3412                 : /************************************************************************/
    3413                 : /*                          GetNormProjParm()                           */
    3414                 : /************************************************************************/
    3415                 : 
    3416                 : /**
    3417                 :  * \brief Fetch a normalized projection parameter value.
    3418                 :  *
    3419                 :  * This method is the same as GetProjParm() except that the value of
    3420                 :  * the parameter is "normalized" into degrees or meters depending on 
    3421                 :  * whether it is linear or angular.
    3422                 :  *
    3423                 :  * This method is the same as the C function OSRGetNormProjParm().
    3424                 :  *
    3425                 :  * @param pszName the name of the parameter to fetch, from the set of 
    3426                 :  * SRS_PP codes in ogr_srs_api.h.
    3427                 :  *
    3428                 :  * @param dfDefaultValue the value to return if this parameter doesn't exist.
    3429                 :  *
    3430                 :  * @param pnErr place to put error code on failure.  Ignored if NULL.
    3431                 :  *
    3432                 :  * @return value of parameter.
    3433                 :  */
    3434                 : 
    3435           20249 : double OGRSpatialReference::GetNormProjParm( const char * pszName,
    3436                 :                                              double dfDefaultValue,
    3437                 :                                              OGRErr *pnErr ) const
    3438                 : 
    3439                 : {
    3440                 :     double dfRawResult;
    3441                 :     OGRErr nError;
    3442                 : 
    3443           20249 :     if( pnErr == NULL )
    3444           20249 :         pnErr = &nError;
    3445                 : 
    3446           20249 :     GetNormInfo();
    3447                 : 
    3448           20249 :     dfRawResult = GetProjParm( pszName, dfDefaultValue, pnErr );
    3449                 : 
    3450                 :     // If we got the default just return it unadjusted.
    3451           20249 :     if( *pnErr != OGRERR_NONE )
    3452              37 :         return dfRawResult;
    3453                 : 
    3454           20212 :     if( dfToDegrees != 1.0 && IsAngularParameter(pszName) )
    3455               6 :         dfRawResult *= dfToDegrees;
    3456                 : 
    3457           20212 :     if( dfToMeter != 1.0 && IsLinearParameter( pszName ) )
    3458             152 :         return dfRawResult * dfToMeter;
    3459                 : #ifdef WKT_LONGITUDE_RELATIVE_TO_PM
    3460                 :     else if( dfFromGreenwich != 0.0 && IsLongitudeParameter( pszName ) )
    3461                 :         return dfRawResult + dfFromGreenwich;
    3462                 : #endif
    3463                 :     else
    3464           20060 :         return dfRawResult;
    3465                 : }
    3466                 : 
    3467                 : /************************************************************************/
    3468                 : /*                         OSRGetNormProjParm()                         */
    3469                 : /************************************************************************/
    3470                 : 
    3471                 : /**
    3472                 :  * \brief This function is the same as OGRSpatialReference::
    3473                 :  *
    3474                 :  * This function is the same as OGRSpatialReference::GetNormProjParm()
    3475                 :  */
    3476               0 : double OSRGetNormProjParm( OGRSpatialReferenceH hSRS, const char *pszName,
    3477                 :                            double dfDefaultValue, OGRErr *pnErr )
    3478                 : 
    3479                 : {
    3480               0 :     VALIDATE_POINTER1( hSRS, "OSRGetNormProjParm", 0 );
    3481                 : 
    3482                 :     return ((OGRSpatialReference *) hSRS)->
    3483               0 :         GetNormProjParm(pszName, dfDefaultValue, pnErr);
    3484                 : }
    3485                 : 
    3486                 : /************************************************************************/
    3487                 : /*                          SetNormProjParm()                           */
    3488                 : /************************************************************************/
    3489                 : 
    3490                 : /**
    3491                 :  * \brief Set a projection parameter with a normalized value.
    3492                 :  *
    3493                 :  * This method is the same as SetProjParm() except that the value of
    3494                 :  * the parameter passed in is assumed to be in "normalized" form (decimal
    3495                 :  * degrees for angular values, meters for linear values.  The values are 
    3496                 :  * converted in a form suitable for the GEOGCS and linear units in effect.
    3497                 :  *
    3498                 :  * This method is the same as the C function OSRSetNormProjParm().
    3499                 :  *
    3500                 :  * @param pszName the parameter name, which should be selected from
    3501                 :  * the macros in ogr_srs_api.h, such as SRS_PP_CENTRAL_MERIDIAN. 
    3502                 :  *
    3503                 :  * @param dfValue value to assign. 
    3504                 :  * 
    3505                 :  * @return OGRERR_NONE on success.
    3506                 :  */
    3507                 : 
    3508           63880 : OGRErr OGRSpatialReference::SetNormProjParm( const char * pszName,
    3509                 :                                              double dfValue )
    3510                 : 
    3511                 : {
    3512           63880 :     GetNormInfo();
    3513                 : 
    3514           63880 :     if( (dfToDegrees != 1.0 || dfFromGreenwich != 0.0) 
    3515                 :         && IsAngularParameter(pszName) )
    3516                 :     {
    3517                 : #ifdef WKT_LONGITUDE_RELATIVE_TO_PM
    3518                 :         if( dfFromGreenwich != 0.0 && IsLongitudeParameter( pszName ) )
    3519                 :             dfValue -= dfFromGreenwich;
    3520                 : #endif
    3521                 : 
    3522             391 :         dfValue /= dfToDegrees;
    3523                 :     }
    3524           63489 :     else if( dfToMeter != 1.0 && IsLinearParameter( pszName ) )
    3525            3314 :         dfValue /= dfToMeter;
    3526                 : 
    3527           63880 :     return SetProjParm( pszName, dfValue );
    3528                 : }
    3529                 : 
    3530                 : /************************************************************************/
    3531                 : /*                         OSRSetNormProjParm()                         */
    3532                 : /************************************************************************/
    3533                 : 
    3534                 : /**
    3535                 :  * \brief Set a projection parameter with a normalized value.
    3536                 :  *
    3537                 :  * This function is the same as OGRSpatialReference::SetNormProjParm()
    3538                 :  */
    3539               0 : OGRErr OSRSetNormProjParm( OGRSpatialReferenceH hSRS, 
    3540                 :                            const char * pszParmName, double dfValue )
    3541                 : 
    3542                 : {
    3543               0 :     VALIDATE_POINTER1( hSRS, "OSRSetNormProjParm", CE_Failure );
    3544                 : 
    3545                 :     return ((OGRSpatialReference *) hSRS)->
    3546               0 :         SetNormProjParm( pszParmName, dfValue );
    3547                 : }
    3548                 : 
    3549                 : /************************************************************************/
    3550                 : /*                               SetTM()                                */
    3551                 : /************************************************************************/
    3552                 : 
    3553            9041 : OGRErr OGRSpatialReference::SetTM( double dfCenterLat, double dfCenterLong,
    3554                 :                                    double dfScale,
    3555                 :                                    double dfFalseEasting,
    3556                 :                                    double dfFalseNorthing )
    3557                 : 
    3558                 : {
    3559            9041 :     SetProjection( SRS_PT_TRANSVERSE_MERCATOR );
    3560            9041 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    3561            9041 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    3562            9041 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    3563            9041 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3564            9041 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3565                 : 
    3566            9041 :     return OGRERR_NONE;
    3567                 : }
    3568                 : 
    3569                 : /************************************************************************/
    3570                 : /*                              OSRSetTM()                              */
    3571                 : /************************************************************************/
    3572                 : 
    3573               0 : OGRErr OSRSetTM( OGRSpatialReferenceH hSRS, 
    3574                 :                  double dfCenterLat, double dfCenterLong,
    3575                 :                  double dfScale,
    3576                 :                  double dfFalseEasting,
    3577                 :                  double dfFalseNorthing )
    3578                 : 
    3579                 : {
    3580               0 :     VALIDATE_POINTER1( hSRS, "OSRSetTM", CE_Failure );
    3581                 : 
    3582                 :     return ((OGRSpatialReference *) hSRS)->SetTM( 
    3583                 :         dfCenterLat, dfCenterLong, 
    3584                 :         dfScale, 
    3585               0 :         dfFalseEasting, dfFalseNorthing );
    3586                 : }
    3587                 : 
    3588                 : /************************************************************************/
    3589                 : /*                            SetTMVariant()                            */
    3590                 : /************************************************************************/
    3591                 : 
    3592               0 : OGRErr OGRSpatialReference::SetTMVariant( 
    3593                 :     const char *pszVariantName,
    3594                 :     double dfCenterLat, double dfCenterLong,
    3595                 :     double dfScale,
    3596                 :     double dfFalseEasting,
    3597                 :     double dfFalseNorthing )
    3598                 : 
    3599                 : {
    3600               0 :     SetProjection( pszVariantName );
    3601               0 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    3602               0 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    3603               0 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    3604               0 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3605               0 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3606                 : 
    3607               0 :     return OGRERR_NONE;
    3608                 : }
    3609                 : 
    3610                 : /************************************************************************/
    3611                 : /*                          OSRSetTMVariant()                           */
    3612                 : /************************************************************************/
    3613                 : 
    3614               0 : OGRErr OSRSetTMVariant( OGRSpatialReferenceH hSRS, 
    3615                 :                         const char *pszVariantName,
    3616                 :                         double dfCenterLat, double dfCenterLong,
    3617                 :                         double dfScale,
    3618                 :                         double dfFalseEasting,
    3619                 :                         double dfFalseNorthing )
    3620                 : 
    3621                 : {
    3622               0 :     VALIDATE_POINTER1( hSRS, "OSRSetTMVariant", CE_Failure );
    3623                 : 
    3624                 :     return ((OGRSpatialReference *) hSRS)->SetTMVariant( 
    3625                 :         pszVariantName,
    3626                 :         dfCenterLat, dfCenterLong, 
    3627                 :         dfScale, 
    3628               0 :         dfFalseEasting, dfFalseNorthing );
    3629                 : }
    3630                 : 
    3631                 : /************************************************************************/
    3632                 : /*                              SetTMSO()                               */
    3633                 : /************************************************************************/
    3634                 : 
    3635              90 : OGRErr OGRSpatialReference::SetTMSO( double dfCenterLat, double dfCenterLong,
    3636                 :                                      double dfScale,
    3637                 :                                      double dfFalseEasting,
    3638                 :                                      double dfFalseNorthing )
    3639                 : 
    3640                 : {
    3641              90 :     SetProjection( SRS_PT_TRANSVERSE_MERCATOR_SOUTH_ORIENTED );
    3642              90 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    3643              90 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    3644              90 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    3645              90 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3646              90 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3647                 : 
    3648              90 :     return OGRERR_NONE;
    3649                 : }
    3650                 : 
    3651                 : /************************************************************************/
    3652                 : /*                              SetTPED()                               */
    3653                 : /************************************************************************/
    3654                 : 
    3655               2 : OGRErr OGRSpatialReference::SetTPED( double dfLat1, double dfLong1, 
    3656                 :                                      double dfLat2, double dfLong2,
    3657                 :                                      double dfFalseEasting,
    3658                 :                                      double dfFalseNorthing )
    3659                 : 
    3660                 : {
    3661               2 :     SetProjection( SRS_PT_TWO_POINT_EQUIDISTANT );
    3662               2 :     SetNormProjParm( SRS_PP_LATITUDE_OF_1ST_POINT, dfLat1 );
    3663               2 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_1ST_POINT, dfLong1 );
    3664               2 :     SetNormProjParm( SRS_PP_LATITUDE_OF_2ND_POINT, dfLat2 );
    3665               2 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_2ND_POINT, dfLong2 );
    3666               2 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3667               2 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3668                 : 
    3669               2 :     return OGRERR_NONE;
    3670                 : }
    3671                 : 
    3672                 : /************************************************************************/
    3673                 : /*                             OSRSetTPED()                             */
    3674                 : /************************************************************************/
    3675                 : 
    3676               0 : OGRErr OSRSetTPED( OGRSpatialReferenceH hSRS,
    3677                 :                    double dfLat1, double dfLong1,
    3678                 :                    double dfLat2, double dfLong2,
    3679                 :                    double dfFalseEasting, double dfFalseNorthing )
    3680                 : 
    3681                 : {
    3682               0 :     VALIDATE_POINTER1( hSRS, "OSRSetTPED", CE_Failure );
    3683                 : 
    3684                 :     return ((OGRSpatialReference *) hSRS)->SetTPED( 
    3685                 :         dfLat1, dfLong1, dfLat2, dfLong2,
    3686               0 :         dfFalseEasting, dfFalseNorthing );
    3687                 : }
    3688                 : 
    3689                 : /************************************************************************/
    3690                 : /*                             OSRSetTMSO()                             */
    3691                 : /************************************************************************/
    3692                 : 
    3693               0 : OGRErr OSRSetTMSO( OGRSpatialReferenceH hSRS, 
    3694                 :                  double dfCenterLat, double dfCenterLong,
    3695                 :                  double dfScale,
    3696                 :                  double dfFalseEasting,
    3697                 :                  double dfFalseNorthing )
    3698                 : 
    3699                 : {
    3700               0 :     VALIDATE_POINTER1( hSRS, "OSRSetTMSO", CE_Failure );
    3701                 : 
    3702                 :     return ((OGRSpatialReference *) hSRS)->SetTMSO( 
    3703                 :         dfCenterLat, dfCenterLong, 
    3704                 :         dfScale, 
    3705               0 :         dfFalseEasting, dfFalseNorthing );
    3706                 : }
    3707                 : 
    3708                 : /************************************************************************/
    3709                 : /*                               SetTMG()                               */
    3710                 : /************************************************************************/
    3711                 : 
    3712                 : OGRErr 
    3713               3 : OGRSpatialReference::SetTMG( double dfCenterLat, double dfCenterLong,
    3714                 :                              double dfFalseEasting, double dfFalseNorthing )
    3715                 :     
    3716                 : {
    3717               3 :     SetProjection( SRS_PT_TUNISIA_MINING_GRID );
    3718               3 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    3719               3 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    3720               3 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3721               3 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3722                 : 
    3723               3 :     return OGRERR_NONE;
    3724                 : }
    3725                 : 
    3726                 : /************************************************************************/
    3727                 : /*                             OSRSetTMG()                              */
    3728                 : /************************************************************************/
    3729                 : 
    3730               0 : OGRErr OSRSetTMG( OGRSpatialReferenceH hSRS, 
    3731                 :                  double dfCenterLat, double dfCenterLong,
    3732                 :                  double dfFalseEasting,
    3733                 :                  double dfFalseNorthing )
    3734                 : 
    3735                 : {
    3736               0 :     VALIDATE_POINTER1( hSRS, "OSRSetTMG", CE_Failure );
    3737                 : 
    3738                 :     return ((OGRSpatialReference *) hSRS)->SetTMG( 
    3739                 :         dfCenterLat, dfCenterLong, 
    3740               0 :         dfFalseEasting, dfFalseNorthing );
    3741                 : }
    3742                 : 
    3743                 : /************************************************************************/
    3744                 : /*                              SetACEA()                               */
    3745                 : /************************************************************************/
    3746                 : 
    3747             105 : OGRErr OGRSpatialReference::SetACEA( double dfStdP1, double dfStdP2,
    3748                 :                                      double dfCenterLat, double dfCenterLong,
    3749                 :                                      double dfFalseEasting,
    3750                 :                                      double dfFalseNorthing )
    3751                 : 
    3752                 : {
    3753             105 :     SetProjection( SRS_PT_ALBERS_CONIC_EQUAL_AREA );
    3754             105 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
    3755             105 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
    3756             105 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    3757             105 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    3758             105 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3759             105 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3760                 : 
    3761             105 :     return OGRERR_NONE;
    3762                 : }
    3763                 : 
    3764                 : /************************************************************************/
    3765                 : /*                             OSRSetACEA()                             */
    3766                 : /************************************************************************/
    3767                 : 
    3768               0 : OGRErr OSRSetACEA( OGRSpatialReferenceH hSRS, 
    3769                 :                    double dfStdP1, double dfStdP2,
    3770                 :                    double dfCenterLat, double dfCenterLong,
    3771                 :                    double dfFalseEasting,
    3772                 :                    double dfFalseNorthing )
    3773                 : 
    3774                 : {
    3775               0 :     VALIDATE_POINTER1( hSRS, "OSRSetACEA", CE_Failure );
    3776                 : 
    3777                 :     return ((OGRSpatialReference *) hSRS)->SetACEA( 
    3778                 :         dfStdP1, dfStdP2, 
    3779                 :         dfCenterLat, dfCenterLong, 
    3780               0 :         dfFalseEasting, dfFalseNorthing );
    3781                 : }
    3782                 : 
    3783                 : /************************************************************************/
    3784                 : /*                               SetAE()                                */
    3785                 : /************************************************************************/
    3786                 : 
    3787              22 : OGRErr OGRSpatialReference::SetAE( double dfCenterLat, double dfCenterLong,
    3788                 :                                    double dfFalseEasting,
    3789                 :                                    double dfFalseNorthing )
    3790                 : 
    3791                 : {
    3792              22 :     SetProjection( SRS_PT_AZIMUTHAL_EQUIDISTANT );
    3793              22 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    3794              22 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    3795              22 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3796              22 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3797                 : 
    3798              22 :     return OGRERR_NONE;
    3799                 : }
    3800                 : 
    3801                 : /************************************************************************/
    3802                 : /*                              OSRSetAE()                              */
    3803                 : /************************************************************************/
    3804                 : 
    3805               0 : OGRErr OSRSetAE( OGRSpatialReferenceH hSRS, 
    3806                 :                  double dfCenterLat, double dfCenterLong,
    3807                 :                  double dfFalseEasting,
    3808                 :                  double dfFalseNorthing )
    3809                 : 
    3810                 : {
    3811               0 :     VALIDATE_POINTER1( hSRS, "OSRSetACEA", CE_Failure );
    3812                 : 
    3813                 :     return ((OGRSpatialReference *) hSRS)->SetAE( 
    3814                 :         dfCenterLat, dfCenterLong, 
    3815               0 :         dfFalseEasting, dfFalseNorthing );
    3816                 : }
    3817                 : 
    3818                 : /************************************************************************/
    3819                 : /*                              SetBonne()                              */
    3820                 : /************************************************************************/
    3821                 : 
    3822               1 : OGRErr OGRSpatialReference::SetBonne( 
    3823                 :     double dfStdP1, double dfCentralMeridian,
    3824                 :     double dfFalseEasting, double dfFalseNorthing )
    3825                 : 
    3826                 : {
    3827               1 :     SetProjection( SRS_PT_BONNE );
    3828               1 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
    3829               1 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    3830               1 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3831               1 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3832                 : 
    3833               1 :     return OGRERR_NONE;
    3834                 : }
    3835                 : 
    3836                 : /************************************************************************/
    3837                 : /*                            OSRSetBonne()                             */
    3838                 : /************************************************************************/
    3839                 : 
    3840               0 : OGRErr OSRSetBonne( OGRSpatialReferenceH hSRS, 
    3841                 :                     double dfStdP1, double dfCentralMeridian,
    3842                 :                     double dfFalseEasting, double dfFalseNorthing )
    3843                 :     
    3844                 : {
    3845               0 :     VALIDATE_POINTER1( hSRS, "OSRSetBonne", CE_Failure );
    3846                 : 
    3847                 :     return ((OGRSpatialReference *) hSRS)->SetBonne( 
    3848                 :         dfStdP1, dfCentralMeridian,
    3849               0 :         dfFalseEasting, dfFalseNorthing );
    3850                 : }
    3851                 : 
    3852                 : /************************************************************************/
    3853                 : /*                               SetCEA()                               */
    3854                 : /************************************************************************/
    3855                 : 
    3856              22 : OGRErr OGRSpatialReference::SetCEA( double dfStdP1, double dfCentralMeridian,
    3857                 :                                     double dfFalseEasting,
    3858                 :                                     double dfFalseNorthing )
    3859                 : 
    3860                 : {
    3861              22 :     SetProjection( SRS_PT_CYLINDRICAL_EQUAL_AREA );
    3862              22 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
    3863              22 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    3864              22 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3865              22 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3866                 : 
    3867              22 :     return OGRERR_NONE;
    3868                 : }
    3869                 : 
    3870                 : /************************************************************************/
    3871                 : /*                             OSRSetCEA()                              */
    3872                 : /************************************************************************/
    3873                 : 
    3874               0 : OGRErr OSRSetCEA( OGRSpatialReferenceH hSRS, 
    3875                 :                   double dfStdP1, double dfCentralMeridian,
    3876                 :                   double dfFalseEasting, double dfFalseNorthing )
    3877                 : 
    3878                 : {
    3879               0 :     VALIDATE_POINTER1( hSRS, "OSRSetCEA", CE_Failure );
    3880                 : 
    3881                 :     return ((OGRSpatialReference *) hSRS)->SetCEA( 
    3882                 :         dfStdP1, dfCentralMeridian,
    3883               0 :         dfFalseEasting, dfFalseNorthing );
    3884                 : }
    3885                 : 
    3886                 : /************************************************************************/
    3887                 : /*                               SetCS()                                */
    3888                 : /************************************************************************/
    3889                 : 
    3890              67 : OGRErr OGRSpatialReference::SetCS( double dfCenterLat, double dfCenterLong,
    3891                 :                                    double dfFalseEasting,
    3892                 :                                    double dfFalseNorthing )
    3893                 : 
    3894                 : {
    3895              67 :     SetProjection( SRS_PT_CASSINI_SOLDNER );
    3896              67 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    3897              67 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    3898              67 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3899              67 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3900                 : 
    3901              67 :     return OGRERR_NONE;
    3902                 : }
    3903                 : 
    3904                 : /************************************************************************/
    3905                 : /*                              OSRSetCS()                              */
    3906                 : /************************************************************************/
    3907                 : 
    3908               0 : OGRErr OSRSetCS( OGRSpatialReferenceH hSRS, 
    3909                 :                  double dfCenterLat, double dfCenterLong,
    3910                 :                  double dfFalseEasting,
    3911                 :                  double dfFalseNorthing )
    3912                 : 
    3913                 : {
    3914               0 :     VALIDATE_POINTER1( hSRS, "OSRSetCS", CE_Failure );
    3915                 : 
    3916                 :     return ((OGRSpatialReference *) hSRS)->SetCS( 
    3917                 :         dfCenterLat, dfCenterLong, 
    3918               0 :         dfFalseEasting, dfFalseNorthing );
    3919                 : }
    3920                 : 
    3921                 : /************************************************************************/
    3922                 : /*                               SetEC()                                */
    3923                 : /************************************************************************/
    3924                 : 
    3925               3 : OGRErr OGRSpatialReference::SetEC( double dfStdP1, double dfStdP2,
    3926                 :                                    double dfCenterLat, double dfCenterLong,
    3927                 :                                    double dfFalseEasting,
    3928                 :                                    double dfFalseNorthing )
    3929                 : 
    3930                 : {
    3931               3 :     SetProjection( SRS_PT_EQUIDISTANT_CONIC );
    3932               3 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
    3933               3 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
    3934               3 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    3935               3 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    3936               3 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3937               3 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3938                 : 
    3939               3 :     return OGRERR_NONE;
    3940                 : }
    3941                 : 
    3942                 : /************************************************************************/
    3943                 : /*                              OSRSetEC()                              */
    3944                 : /************************************************************************/
    3945                 : 
    3946               0 : OGRErr OSRSetEC( OGRSpatialReferenceH hSRS, 
    3947                 :                  double dfStdP1, double dfStdP2,
    3948                 :                  double dfCenterLat, double dfCenterLong,
    3949                 :                  double dfFalseEasting,
    3950                 :                  double dfFalseNorthing )
    3951                 : 
    3952                 : {
    3953               0 :     VALIDATE_POINTER1( hSRS, "OSRSetEC", CE_Failure );
    3954                 : 
    3955                 :     return ((OGRSpatialReference *) hSRS)->SetEC( 
    3956                 :         dfStdP1, dfStdP2, 
    3957                 :         dfCenterLat, dfCenterLong, 
    3958               0 :         dfFalseEasting, dfFalseNorthing );
    3959                 : }
    3960                 : 
    3961                 : /************************************************************************/
    3962                 : /*                             SetEckert()                              */
    3963                 : /************************************************************************/
    3964                 : 
    3965               7 : OGRErr OGRSpatialReference::SetEckert( int nVariation /* 1-6 */,
    3966                 :                                        double dfCentralMeridian,
    3967                 :                                        double dfFalseEasting,
    3968                 :                                        double dfFalseNorthing )
    3969                 : 
    3970                 : {
    3971               7 :     if( nVariation == 1 )
    3972               1 :         SetProjection( SRS_PT_ECKERT_I );
    3973               6 :     else if( nVariation == 2 )
    3974               1 :         SetProjection( SRS_PT_ECKERT_II );
    3975               5 :     else if( nVariation == 3 )
    3976               1 :         SetProjection( SRS_PT_ECKERT_III );
    3977               4 :     else if( nVariation == 4 )
    3978               2 :         SetProjection( SRS_PT_ECKERT_IV );
    3979               2 :     else if( nVariation == 5 )
    3980               1 :         SetProjection( SRS_PT_ECKERT_V );
    3981               1 :     else if( nVariation == 6 )
    3982               1 :         SetProjection( SRS_PT_ECKERT_VI );
    3983                 :     else
    3984                 :     {
    3985                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    3986                 :                   "Unsupported Eckert variation (%d).", 
    3987               0 :                   nVariation );
    3988               0 :         return OGRERR_UNSUPPORTED_SRS;
    3989                 :     }
    3990                 : 
    3991               7 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    3992               7 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    3993               7 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    3994                 : 
    3995               7 :     return OGRERR_NONE;
    3996                 : }
    3997                 : 
    3998                 : /************************************************************************/
    3999                 : /*                            OSRSetEckert()                            */
    4000                 : /************************************************************************/
    4001                 : 
    4002               0 : OGRErr OSRSetEckert( OGRSpatialReferenceH hSRS, 
    4003                 :                      int nVariation,
    4004                 :                      double dfCentralMeridian,
    4005                 :                      double dfFalseEasting,
    4006                 :                      double dfFalseNorthing )
    4007                 : 
    4008                 : {
    4009               0 :     VALIDATE_POINTER1( hSRS, "OSRSetEckert", CE_Failure );
    4010                 : 
    4011                 :     return ((OGRSpatialReference *) hSRS)->SetEckert( 
    4012                 :         nVariation, dfCentralMeridian,
    4013               0 :         dfFalseEasting, dfFalseNorthing );
    4014                 : }
    4015                 : 
    4016                 : /************************************************************************/
    4017                 : /*                            SetEckertIV()                             */
    4018                 : /*                                                                      */
    4019                 : /*      Deprecated                                                      */
    4020                 : /************************************************************************/
    4021                 : 
    4022               0 : OGRErr OGRSpatialReference::SetEckertIV( double dfCentralMeridian,
    4023                 :                                          double dfFalseEasting,
    4024                 :                                          double dfFalseNorthing )
    4025                 : 
    4026                 : {
    4027               0 :     SetProjection( SRS_PT_ECKERT_IV );
    4028               0 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    4029               0 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4030               0 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4031                 : 
    4032               0 :     return OGRERR_NONE;
    4033                 : }
    4034                 : 
    4035                 : /************************************************************************/
    4036                 : /*                           OSRSetEckertIV()                           */
    4037                 : /************************************************************************/
    4038                 : 
    4039               0 : OGRErr OSRSetEckertIV( OGRSpatialReferenceH hSRS, 
    4040                 :                        double dfCentralMeridian,
    4041                 :                        double dfFalseEasting,
    4042                 :                        double dfFalseNorthing )
    4043                 : 
    4044                 : {
    4045               0 :     VALIDATE_POINTER1( hSRS, "OSRSetEckertIV", CE_Failure );
    4046                 : 
    4047                 :     return ((OGRSpatialReference *) hSRS)->SetEckertIV( 
    4048                 :         dfCentralMeridian,
    4049               0 :         dfFalseEasting, dfFalseNorthing );
    4050                 : }
    4051                 : 
    4052                 : /************************************************************************/
    4053                 : /*                            SetEckertVI()                             */
    4054                 : /*                                                                      */
    4055                 : /*      Deprecated                                                      */
    4056                 : /************************************************************************/
    4057                 : 
    4058               0 : OGRErr OGRSpatialReference::SetEckertVI( double dfCentralMeridian,
    4059                 :                                          double dfFalseEasting,
    4060                 :                                          double dfFalseNorthing )
    4061                 : 
    4062                 : {
    4063               0 :     SetProjection( SRS_PT_ECKERT_VI );
    4064               0 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    4065               0 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4066               0 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4067                 : 
    4068               0 :     return OGRERR_NONE;
    4069                 : }
    4070                 : 
    4071                 : /************************************************************************/
    4072                 : /*                           OSRSetEckertVI()                           */
    4073                 : /************************************************************************/
    4074                 : 
    4075               0 : OGRErr OSRSetEckertVI( OGRSpatialReferenceH hSRS, 
    4076                 :                        double dfCentralMeridian,
    4077                 :                        double dfFalseEasting,
    4078                 :                        double dfFalseNorthing )
    4079                 : 
    4080                 : {
    4081               0 :     VALIDATE_POINTER1( hSRS, "OSRSetEckertVI", CE_Failure );
    4082                 : 
    4083                 :     return ((OGRSpatialReference *) hSRS)->SetEckertVI( 
    4084                 :         dfCentralMeridian,
    4085               0 :         dfFalseEasting, dfFalseNorthing );
    4086                 : }
    4087                 : 
    4088                 : /************************************************************************/
    4089                 : /*                         SetEquirectangular()                         */
    4090                 : /************************************************************************/
    4091                 : 
    4092              11 : OGRErr OGRSpatialReference::SetEquirectangular(
    4093                 :                                    double dfCenterLat, double dfCenterLong,
    4094                 :                                    double dfFalseEasting,
    4095                 :                                    double dfFalseNorthing )
    4096                 : 
    4097                 : {
    4098              11 :     SetProjection( SRS_PT_EQUIRECTANGULAR );
    4099              11 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4100              11 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4101              11 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4102              11 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4103                 : 
    4104              11 :     return OGRERR_NONE;
    4105                 : }
    4106                 : 
    4107                 : /************************************************************************/
    4108                 : /*                       OSRSetEquirectangular()                        */
    4109                 : /************************************************************************/
    4110                 : 
    4111               0 : OGRErr OSRSetEquirectangular( OGRSpatialReferenceH hSRS, 
    4112                 :                               double dfCenterLat, double dfCenterLong,
    4113                 :                               double dfFalseEasting,
    4114                 :                               double dfFalseNorthing )
    4115                 :     
    4116                 : {
    4117               0 :     VALIDATE_POINTER1( hSRS, "OSRSetEquirectangular", CE_Failure );
    4118                 : 
    4119                 :     return ((OGRSpatialReference *) hSRS)->SetEquirectangular( 
    4120                 :         dfCenterLat, dfCenterLong, 
    4121               0 :         dfFalseEasting, dfFalseNorthing );
    4122                 : }
    4123                 : 
    4124                 : /************************************************************************/
    4125                 : /*                         SetEquirectangular2()                        */
    4126                 : /* Generalized form                                                     */
    4127                 : /************************************************************************/
    4128                 : 
    4129              14 : OGRErr OGRSpatialReference::SetEquirectangular2(
    4130                 :                                    double dfCenterLat, double dfCenterLong,
    4131                 :                                    double dfStdParallel1,
    4132                 :                                    double dfFalseEasting,
    4133                 :                                    double dfFalseNorthing )
    4134                 : 
    4135                 : {
    4136              14 :     SetProjection( SRS_PT_EQUIRECTANGULAR );
    4137              14 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4138              14 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4139              14 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdParallel1 );
    4140              14 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4141              14 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4142                 : 
    4143              14 :     return OGRERR_NONE;
    4144                 : }
    4145                 : 
    4146                 : /************************************************************************/
    4147                 : /*                       OSRSetEquirectangular2()                       */
    4148                 : /************************************************************************/
    4149                 : 
    4150               0 : OGRErr OSRSetEquirectangular2( OGRSpatialReferenceH hSRS, 
    4151                 :                                double dfCenterLat, double dfCenterLong,
    4152                 :                                double dfStdParallel1,
    4153                 :                                double dfFalseEasting,
    4154                 :                                double dfFalseNorthing )
    4155                 :     
    4156                 : {
    4157               0 :     VALIDATE_POINTER1( hSRS, "OSRSetEquirectangular2", CE_Failure );
    4158                 : 
    4159                 :     return ((OGRSpatialReference *) hSRS)->SetEquirectangular2( 
    4160                 :         dfCenterLat, dfCenterLong, 
    4161                 :         dfStdParallel1,
    4162               0 :         dfFalseEasting, dfFalseNorthing );
    4163                 : }
    4164                 : 
    4165                 : /************************************************************************/
    4166                 : /*                               SetGS()                                */
    4167                 : /************************************************************************/
    4168                 : 
    4169               3 : OGRErr OGRSpatialReference::SetGS( double dfCentralMeridian,
    4170                 :                                    double dfFalseEasting,
    4171                 :                                    double dfFalseNorthing )
    4172                 : 
    4173                 : {
    4174               3 :     SetProjection( SRS_PT_GALL_STEREOGRAPHIC );
    4175               3 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    4176               3 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4177               3 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4178                 : 
    4179               3 :     return OGRERR_NONE;
    4180                 : }
    4181                 : 
    4182                 : /************************************************************************/
    4183                 : /*                              OSRSetGS()                              */
    4184                 : /************************************************************************/
    4185                 : 
    4186               1 : OGRErr OSRSetGS( OGRSpatialReferenceH hSRS, 
    4187                 :                  double dfCentralMeridian,
    4188                 :                  double dfFalseEasting,
    4189                 :                  double dfFalseNorthing )
    4190                 : 
    4191                 : {
    4192               1 :     VALIDATE_POINTER1( hSRS, "OSRSetGS", CE_Failure );
    4193                 : 
    4194                 :     return ((OGRSpatialReference *) hSRS)->SetGS( 
    4195                 :         dfCentralMeridian,
    4196               1 :         dfFalseEasting, dfFalseNorthing );
    4197                 : }
    4198                 : 
    4199                 : /************************************************************************/
    4200                 : /*                               SetGH()                                */
    4201                 : /************************************************************************/
    4202                 : 
    4203               3 : OGRErr OGRSpatialReference::SetGH( double dfCentralMeridian,
    4204                 :                                    double dfFalseEasting,
    4205                 :                                    double dfFalseNorthing )
    4206                 : 
    4207                 : {
    4208               3 :     SetProjection( SRS_PT_GOODE_HOMOLOSINE );
    4209               3 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    4210               3 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4211               3 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4212                 : 
    4213               3 :     return OGRERR_NONE;
    4214                 : }
    4215                 : 
    4216                 : /************************************************************************/
    4217                 : /*                              OSRSetGH()                              */
    4218                 : /************************************************************************/
    4219                 : 
    4220               0 : OGRErr OSRSetGH( OGRSpatialReferenceH hSRS, 
    4221                 :                  double dfCentralMeridian,
    4222                 :                  double dfFalseEasting,
    4223                 :                  double dfFalseNorthing )
    4224                 : 
    4225                 : {
    4226               0 :     VALIDATE_POINTER1( hSRS, "OSRSetGH", CE_Failure );
    4227                 : 
    4228                 :     return ((OGRSpatialReference *) hSRS)->SetGH( 
    4229                 :         dfCentralMeridian,
    4230               0 :         dfFalseEasting, dfFalseNorthing );
    4231                 : }
    4232                 : 
    4233                 : /************************************************************************/
    4234                 : /*                              SetIGH()                                */
    4235                 : /************************************************************************/
    4236                 : 
    4237               1 : OGRErr OGRSpatialReference::SetIGH()
    4238                 : 
    4239                 : {
    4240               1 :     SetProjection( SRS_PT_IGH );
    4241                 : 
    4242               1 :     return OGRERR_NONE;
    4243                 : }
    4244                 : 
    4245                 : /************************************************************************/
    4246                 : /*                              OSRSetIGH()                             */
    4247                 : /************************************************************************/
    4248                 : 
    4249               0 : OGRErr OSRSetIGH( OGRSpatialReferenceH hSRS )
    4250                 : 
    4251                 : {
    4252               0 :     VALIDATE_POINTER1( hSRS, "OSRSetIGH", CE_Failure );
    4253                 : 
    4254               0 :     return ((OGRSpatialReference *) hSRS)->SetIGH();
    4255                 : }
    4256                 : 
    4257                 : /************************************************************************/
    4258                 : /*                              SetGEOS()                               */
    4259                 : /************************************************************************/
    4260                 : 
    4261               1 : OGRErr OGRSpatialReference::SetGEOS( double dfCentralMeridian,
    4262                 :                                      double dfSatelliteHeight,
    4263                 :                                      double dfFalseEasting,
    4264                 :                                      double dfFalseNorthing )
    4265                 : 
    4266                 : {
    4267               1 :     SetProjection( SRS_PT_GEOSTATIONARY_SATELLITE );
    4268               1 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    4269               1 :     SetNormProjParm( SRS_PP_SATELLITE_HEIGHT, dfSatelliteHeight );
    4270               1 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4271               1 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4272                 : 
    4273               1 :     return OGRERR_NONE;
    4274                 : }
    4275                 : 
    4276                 : /************************************************************************/
    4277                 : /*                              OSRSetGEOS()                             */
    4278                 : /************************************************************************/
    4279                 : 
    4280               0 : OGRErr OSRSetGEOS( OGRSpatialReferenceH hSRS, 
    4281                 :                    double dfCentralMeridian,
    4282                 :                    double dfSatelliteHeight,
    4283                 :                    double dfFalseEasting,
    4284                 :                    double dfFalseNorthing )
    4285                 : 
    4286                 : {
    4287               0 :     VALIDATE_POINTER1( hSRS, "OSRSetGEOS", CE_Failure );
    4288                 : 
    4289                 :     return ((OGRSpatialReference *) hSRS)->SetGEOS( 
    4290                 :         dfCentralMeridian, dfSatelliteHeight,
    4291               0 :         dfFalseEasting, dfFalseNorthing );
    4292                 : }
    4293                 : 
    4294                 : /************************************************************************/
    4295                 : /*                       SetGaussSchreiberTMercator()                   */
    4296                 : /************************************************************************/
    4297                 : 
    4298               1 : OGRErr OGRSpatialReference::SetGaussSchreiberTMercator(
    4299                 :                                    double dfCenterLat, double dfCenterLong,
    4300                 :                                    double dfScale,
    4301                 :                                    double dfFalseEasting,
    4302                 :                                    double dfFalseNorthing )
    4303                 : 
    4304                 : {
    4305               1 :     SetProjection( SRS_PT_GAUSSSCHREIBERTMERCATOR );
    4306               1 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4307               1 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4308               1 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    4309               1 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4310               1 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4311                 : 
    4312               1 :     return OGRERR_NONE;
    4313                 : }
    4314                 : 
    4315                 : /************************************************************************/
    4316                 : /*                     OSRSetGaussSchreiberTMercator()                  */
    4317                 : /************************************************************************/
    4318                 : 
    4319               0 : OGRErr OSRSetGaussSchreiberTMercator( OGRSpatialReferenceH hSRS,
    4320                 :                                       double dfCenterLat, double dfCenterLong,
    4321                 :                                       double dfScale,
    4322                 :                                       double dfFalseEasting,
    4323                 :                                       double dfFalseNorthing )
    4324                 : 
    4325                 : {
    4326                 :     return ((OGRSpatialReference *) hSRS)->SetGaussSchreiberTMercator(
    4327                 :         dfCenterLat, dfCenterLong, dfScale,
    4328               0 :         dfFalseEasting, dfFalseNorthing );
    4329                 : }
    4330                 : 
    4331                 : /************************************************************************/
    4332                 : /*                            SetGnomonic()                             */
    4333                 : /************************************************************************/
    4334                 : 
    4335               1 : OGRErr OGRSpatialReference::SetGnomonic(
    4336                 :                                    double dfCenterLat, double dfCenterLong,
    4337                 :                                    double dfFalseEasting,
    4338                 :                                    double dfFalseNorthing )
    4339                 : 
    4340                 : {
    4341               1 :     SetProjection( SRS_PT_GNOMONIC );
    4342               1 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4343               1 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4344               1 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4345               1 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4346                 : 
    4347               1 :     return OGRERR_NONE;
    4348                 : }
    4349                 : 
    4350                 : /************************************************************************/
    4351                 : /*                           OSRSetGnomonic()                           */
    4352                 : /************************************************************************/
    4353                 : 
    4354               0 : OGRErr OSRSetGnomonic( OGRSpatialReferenceH hSRS, 
    4355                 :                        double dfCenterLat, double dfCenterLong,
    4356                 :                        double dfFalseEasting,
    4357                 :                        double dfFalseNorthing )
    4358                 :     
    4359                 : {
    4360               0 :     VALIDATE_POINTER1( hSRS, "OSRSetGnomonic", CE_Failure );
    4361                 : 
    4362                 :     return ((OGRSpatialReference *) hSRS)->SetGnomonic( 
    4363                 :         dfCenterLat, dfCenterLong, 
    4364               0 :         dfFalseEasting, dfFalseNorthing );
    4365                 : }
    4366                 : 
    4367                 : /************************************************************************/
    4368                 : /*                               SetHOM()                               */
    4369                 : /************************************************************************/
    4370                 : 
    4371                 : /**
    4372                 :  * \brief Set a Hotine Oblique Mercator projection using azimuth angle.
    4373                 :  *
    4374                 :  * This method does the same thing as the C function OSRSetHOM().
    4375                 :  *
    4376                 :  * @param dfCenterLat Latitude of the projection origin.
    4377                 :  * @param dfCenterLong Longitude of the projection origin.
    4378                 :  * @param dfAzimuth Azimuth, measured clockwise from North, of the projection
    4379                 :  * centerline.
    4380                 :  * @param dfRectToSkew ?.
    4381                 :  * @param dfScale Scale factor applies to the projection origin.
    4382                 :  * @param dfFalseEasting False easting.
    4383                 :  * @param dfFalseNorthing False northing.
    4384                 :  *
    4385                 :  * @return OGRERR_NONE on success.
    4386                 :  */ 
    4387                 : 
    4388              88 : OGRErr OGRSpatialReference::SetHOM( double dfCenterLat, double dfCenterLong,
    4389                 :                                     double dfAzimuth, double dfRectToSkew,
    4390                 :                                     double dfScale,
    4391                 :                                     double dfFalseEasting,
    4392                 :                                     double dfFalseNorthing )
    4393                 : 
    4394                 : {
    4395              88 :     SetProjection( SRS_PT_HOTINE_OBLIQUE_MERCATOR );
    4396              88 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    4397              88 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    4398              88 :     SetNormProjParm( SRS_PP_AZIMUTH, dfAzimuth );
    4399              88 :     SetNormProjParm( SRS_PP_RECTIFIED_GRID_ANGLE, dfRectToSkew );
    4400              88 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    4401              88 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4402              88 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4403                 : 
    4404              88 :     return OGRERR_NONE;
    4405                 : }
    4406                 : 
    4407                 : /************************************************************************/
    4408                 : /*                             OSRSetHOM()                              */
    4409                 : /************************************************************************/
    4410                 : /**
    4411                 :  * \brief Set a Hotine Oblique Mercator projection using azimuth angle.
    4412                 :  *
    4413                 :  * This is the same as the C++ method OGRSpatialReference::SetHOM()
    4414                 :  */
    4415               0 : OGRErr OSRSetHOM( OGRSpatialReferenceH hSRS, 
    4416                 :                   double dfCenterLat, double dfCenterLong,
    4417                 :                   double dfAzimuth, double dfRectToSkew, 
    4418                 :                   double dfScale,
    4419                 :                   double dfFalseEasting,
    4420                 :                   double dfFalseNorthing )
    4421                 :     
    4422                 : {
    4423               0 :     VALIDATE_POINTER1( hSRS, "OSRSetHOM", CE_Failure );
    4424                 : 
    4425                 :     return ((OGRSpatialReference *) hSRS)->SetHOM( 
    4426                 :         dfCenterLat, dfCenterLong, 
    4427                 :         dfAzimuth, dfRectToSkew, 
    4428                 :         dfScale,
    4429               0 :         dfFalseEasting, dfFalseNorthing );
    4430                 : }
    4431                 : 
    4432                 : /************************************************************************/
    4433                 : /*                             SetHOM2PNO()                             */
    4434                 : /************************************************************************/
    4435                 : 
    4436                 : /**
    4437                 :  * \brief Set a Hotine Oblique Mercator projection using two points on projection
    4438                 :  * centerline.
    4439                 :  *
    4440                 :  * This method does the same thing as the C function OSRSetHOM2PNO().
    4441                 :  *
    4442                 :  * @param dfCenterLat Latitude of the projection origin.
    4443                 :  * @param dfLat1 Latitude of the first point on center line.
    4444                 :  * @param dfLong1 Longitude of the first point on center line.
    4445                 :  * @param dfLat2 Latitude of the second point on center line.
    4446                 :  * @param dfLong2 Longitude of the second point on center line.
    4447                 :  * @param dfScale Scale factor applies to the projection origin.
    4448                 :  * @param dfFalseEasting False easting.
    4449                 :  * @param dfFalseNorthing False northing.
    4450                 :  *
    4451                 :  * @return OGRERR_NONE on success.
    4452                 :  */ 
    4453                 : 
    4454               0 : OGRErr OGRSpatialReference::SetHOM2PNO( double dfCenterLat,
    4455                 :                                         double dfLat1, double dfLong1,
    4456                 :                                         double dfLat2, double dfLong2,
    4457                 :                                         double dfScale,
    4458                 :                                         double dfFalseEasting,
    4459                 :                                         double dfFalseNorthing )
    4460                 : 
    4461                 : {
    4462               0 :     SetProjection( SRS_PT_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN );
    4463               0 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    4464               0 :     SetNormProjParm( SRS_PP_LATITUDE_OF_POINT_1, dfLat1 );
    4465               0 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_POINT_1, dfLong1 );
    4466               0 :     SetNormProjParm( SRS_PP_LATITUDE_OF_POINT_2, dfLat2 );
    4467               0 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_POINT_2, dfLong2 );
    4468               0 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    4469               0 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4470               0 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4471                 : 
    4472               0 :     return OGRERR_NONE;
    4473                 : }
    4474                 : 
    4475                 : /************************************************************************/
    4476                 : /*                           OSRSetHOM2PNO()                            */
    4477                 : /************************************************************************/
    4478                 : /**
    4479                 :  * \brief  Set a Hotine Oblique Mercator projection using two points on projection
    4480                 :  *  centerline.
    4481                 :  *
    4482                 :  * This is the same as the C++ method OGRSpatialReference::SetHOM2PNO()
    4483                 :  */
    4484               0 : OGRErr OSRSetHOM2PNO( OGRSpatialReferenceH hSRS, 
    4485                 :                       double dfCenterLat,
    4486                 :                       double dfLat1, double dfLong1,
    4487                 :                       double dfLat2, double dfLong2,
    4488                 :                       double dfScale,
    4489                 :                       double dfFalseEasting, double dfFalseNorthing )
    4490                 :     
    4491                 : {
    4492               0 :     VALIDATE_POINTER1( hSRS, "OSRSetHOM2PNO", CE_Failure );
    4493                 : 
    4494                 :     return ((OGRSpatialReference *) hSRS)->SetHOM2PNO( 
    4495                 :         dfCenterLat,
    4496                 :         dfLat1, dfLong1,
    4497                 :         dfLat2, dfLong2,
    4498                 :         dfScale,
    4499               0 :         dfFalseEasting, dfFalseNorthing );
    4500                 : }
    4501                 : 
    4502                 : /************************************************************************/
    4503                 : /*                            SetIWMPolyconic()                         */
    4504                 : /************************************************************************/
    4505                 : 
    4506               1 : OGRErr OGRSpatialReference::SetIWMPolyconic(
    4507                 :                                 double dfLat1, double dfLat2,
    4508                 :                                 double dfCenterLong,
    4509                 :                                 double dfFalseEasting, double dfFalseNorthing )
    4510                 : 
    4511                 : {
    4512               1 :     SetProjection( SRS_PT_IMW_POLYCONIC );
    4513               1 :     SetNormProjParm( SRS_PP_LATITUDE_OF_1ST_POINT, dfLat1 );
    4514               1 :     SetNormProjParm( SRS_PP_LATITUDE_OF_2ND_POINT, dfLat2 );
    4515               1 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4516               1 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4517               1 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4518                 : 
    4519               1 :     return OGRERR_NONE;
    4520                 : }
    4521                 : 
    4522                 : /************************************************************************/
    4523                 : /*                          OSRSetIWMPolyconic()                        */
    4524                 : /************************************************************************/
    4525                 : 
    4526               0 : OGRErr OSRSetIWMPolyconic( OGRSpatialReferenceH hSRS, 
    4527                 :                            double dfLat1, double dfLat2,
    4528                 :                            double dfCenterLong,
    4529                 :                            double dfFalseEasting, double dfFalseNorthing )
    4530                 :     
    4531                 : {
    4532               0 :     VALIDATE_POINTER1( hSRS, "OSRSetIWMPolyconic", CE_Failure );
    4533                 : 
    4534                 :     return ((OGRSpatialReference *) hSRS)->SetIWMPolyconic( 
    4535                 :         dfLat1, dfLat2, dfCenterLong, 
    4536               0 :         dfFalseEasting, dfFalseNorthing );
    4537                 : }
    4538                 : 
    4539                 : /************************************************************************/
    4540                 : /*                             SetKrovak()                              */
    4541                 : /************************************************************************/
    4542                 : 
    4543              11 : OGRErr OGRSpatialReference::SetKrovak( double dfCenterLat, double dfCenterLong,
    4544                 :                                        double dfAzimuth, 
    4545                 :                                        double dfPseudoStdParallel1,
    4546                 :                                        double dfScale,
    4547                 :                                        double dfFalseEasting,
    4548                 :                                        double dfFalseNorthing )
    4549                 : 
    4550                 : {
    4551              11 :     SetProjection( SRS_PT_KROVAK );
    4552              11 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    4553              11 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    4554              11 :     SetNormProjParm( SRS_PP_AZIMUTH, dfAzimuth );
    4555              11 :     SetNormProjParm( SRS_PP_PSEUDO_STD_PARALLEL_1, dfPseudoStdParallel1 );
    4556              11 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    4557              11 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4558              11 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4559                 : 
    4560              11 :     return OGRERR_NONE;
    4561                 : }
    4562                 : 
    4563                 : /************************************************************************/
    4564                 : /*                            OSRSetKrovak()                            */
    4565                 : /************************************************************************/
    4566                 : 
    4567               0 : OGRErr OSRSetKrovak( OGRSpatialReferenceH hSRS, 
    4568                 :                      double dfCenterLat, double dfCenterLong,
    4569                 :                      double dfAzimuth, double dfPseudoStdParallel1,
    4570                 :                      double dfScale,
    4571                 :                      double dfFalseEasting,
    4572                 :                      double dfFalseNorthing )
    4573                 :     
    4574                 : {
    4575               0 :     VALIDATE_POINTER1( hSRS, "OSRSetKrovak", CE_Failure );
    4576                 : 
    4577                 :     return ((OGRSpatialReference *) hSRS)->SetKrovak( 
    4578                 :         dfCenterLat, dfCenterLong, 
    4579                 :         dfAzimuth, dfPseudoStdParallel1,
    4580                 :         dfScale,
    4581               0 :         dfFalseEasting, dfFalseNorthing );
    4582                 : }
    4583                 : 
    4584                 : /************************************************************************/
    4585                 : /*                              SetLAEA()                               */
    4586                 : /************************************************************************/
    4587                 : 
    4588              54 : OGRErr OGRSpatialReference::SetLAEA( double dfCenterLat, double dfCenterLong,
    4589                 :                                    double dfFalseEasting,
    4590                 :                                    double dfFalseNorthing )
    4591                 : 
    4592                 : {
    4593              54 :     SetProjection( SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA );
    4594              54 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    4595              54 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    4596              54 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4597              54 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4598                 : 
    4599              54 :     return OGRERR_NONE;
    4600                 : }
    4601                 : 
    4602                 : /************************************************************************/
    4603                 : /*                             OSRSetLAEA()                             */
    4604                 : /************************************************************************/
    4605                 : 
    4606               0 : OGRErr OSRSetLAEA( OGRSpatialReferenceH hSRS, 
    4607                 :                    double dfCenterLat, double dfCenterLong,
    4608                 :                    double dfFalseEasting, double dfFalseNorthing )
    4609                 :     
    4610                 : {
    4611               0 :     VALIDATE_POINTER1( hSRS, "OSRSetLAEA", CE_Failure );
    4612                 : 
    4613                 :     return ((OGRSpatialReference *) hSRS)->SetLAEA( 
    4614                 :         dfCenterLat, dfCenterLong, 
    4615               0 :         dfFalseEasting, dfFalseNorthing );
    4616                 : }
    4617                 : 
    4618                 : /************************************************************************/
    4619                 : /*                               SetLCC()                               */
    4620                 : /************************************************************************/
    4621                 : 
    4622            2048 : OGRErr OGRSpatialReference::SetLCC( double dfStdP1, double dfStdP2,
    4623                 :                                     double dfCenterLat, double dfCenterLong,
    4624                 :                                     double dfFalseEasting,
    4625                 :                                     double dfFalseNorthing )
    4626                 : 
    4627                 : {
    4628            2048 :     SetProjection( SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP );
    4629            2048 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
    4630            2048 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
    4631            2048 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4632            2048 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4633            2048 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4634            2048 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4635                 : 
    4636            2048 :     return OGRERR_NONE;
    4637                 : }
    4638                 : 
    4639                 : /************************************************************************/
    4640                 : /*                             OSRSetLCC()                              */
    4641                 : /************************************************************************/
    4642                 : 
    4643               2 : OGRErr OSRSetLCC( OGRSpatialReferenceH hSRS, 
    4644                 :                   double dfStdP1, double dfStdP2, 
    4645                 :                   double dfCenterLat, double dfCenterLong,
    4646                 :                   double dfFalseEasting, double dfFalseNorthing )
    4647                 :     
    4648                 : {
    4649               2 :     VALIDATE_POINTER1( hSRS, "OSRSetLCC", CE_Failure );
    4650                 : 
    4651                 :     return ((OGRSpatialReference *) hSRS)->SetLCC( 
    4652                 :         dfStdP1, dfStdP2, 
    4653                 :         dfCenterLat, dfCenterLong, 
    4654               2 :         dfFalseEasting, dfFalseNorthing );
    4655                 : }
    4656                 : 
    4657                 : /************************************************************************/
    4658                 : /*                             SetLCC1SP()                              */
    4659                 : /************************************************************************/
    4660                 : 
    4661             245 : OGRErr OGRSpatialReference::SetLCC1SP( double dfCenterLat, double dfCenterLong,
    4662                 :                                        double dfScale,
    4663                 :                                        double dfFalseEasting,
    4664                 :                                        double dfFalseNorthing )
    4665                 : 
    4666                 : {
    4667             245 :     SetProjection( SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP );
    4668             245 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4669             245 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4670             245 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    4671             245 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4672             245 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4673                 : 
    4674             245 :     return OGRERR_NONE;
    4675                 : }
    4676                 : 
    4677                 : /************************************************************************/
    4678                 : /*                            OSRSetLCC1SP()                            */
    4679                 : /************************************************************************/
    4680                 : 
    4681               0 : OGRErr OSRSetLCC1SP( OGRSpatialReferenceH hSRS, 
    4682                 :                      double dfCenterLat, double dfCenterLong,
    4683                 :                      double dfScale,
    4684                 :                      double dfFalseEasting, double dfFalseNorthing )
    4685                 :     
    4686                 : {
    4687               0 :     VALIDATE_POINTER1( hSRS, "OSRSetLCC1SP", CE_Failure );
    4688                 : 
    4689                 :     return ((OGRSpatialReference *) hSRS)->SetLCC1SP( 
    4690                 :         dfCenterLat, dfCenterLong, 
    4691                 :         dfScale,
    4692               0 :         dfFalseEasting, dfFalseNorthing );
    4693                 : }
    4694                 : 
    4695                 : /************************************************************************/
    4696                 : /*                              SetLCCB()                               */
    4697                 : /************************************************************************/
    4698                 : 
    4699               3 : OGRErr OGRSpatialReference::SetLCCB( double dfStdP1, double dfStdP2,
    4700                 :                                      double dfCenterLat, double dfCenterLong,
    4701                 :                                      double dfFalseEasting,
    4702                 :                                      double dfFalseNorthing )
    4703                 : 
    4704                 : {
    4705               3 :     SetProjection( SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM );
    4706               3 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
    4707               3 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
    4708               3 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4709               3 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4710               3 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4711               3 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4712                 : 
    4713               3 :     return OGRERR_NONE;
    4714                 : }
    4715                 : 
    4716                 : /************************************************************************/
    4717                 : /*                             OSRSetLCCB()                             */
    4718                 : /************************************************************************/
    4719                 : 
    4720               0 : OGRErr OSRSetLCCB( OGRSpatialReferenceH hSRS, 
    4721                 :                    double dfStdP1, double dfStdP2, 
    4722                 :                    double dfCenterLat, double dfCenterLong,
    4723                 :                    double dfFalseEasting, double dfFalseNorthing )
    4724                 :     
    4725                 : {
    4726               0 :     VALIDATE_POINTER1( hSRS, "OSRSetLCCB", CE_Failure );
    4727                 : 
    4728                 :     return ((OGRSpatialReference *) hSRS)->SetLCCB( 
    4729                 :         dfStdP1, dfStdP2, 
    4730                 :         dfCenterLat, dfCenterLong, 
    4731               0 :         dfFalseEasting, dfFalseNorthing );
    4732                 : }
    4733                 : 
    4734                 : /************************************************************************/
    4735                 : /*                               SetMC()                                */
    4736                 : /************************************************************************/
    4737                 : 
    4738               2 : OGRErr OGRSpatialReference::SetMC( double dfCenterLat, double dfCenterLong,
    4739                 :                                    double dfFalseEasting,
    4740                 :                                    double dfFalseNorthing )
    4741                 : 
    4742                 : {
    4743               2 :     SetProjection( SRS_PT_MILLER_CYLINDRICAL );
    4744               2 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
    4745               2 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    4746               2 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4747               2 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4748                 : 
    4749               2 :     return OGRERR_NONE;
    4750                 : }
    4751                 : 
    4752                 : /************************************************************************/
    4753                 : /*                              OSRSetMC()                              */
    4754                 : /************************************************************************/
    4755                 : 
    4756               0 : OGRErr OSRSetMC( OGRSpatialReferenceH hSRS, 
    4757                 :                  double dfCenterLat, double dfCenterLong,
    4758                 :                  double dfFalseEasting, double dfFalseNorthing )
    4759                 :     
    4760                 : {
    4761               0 :     VALIDATE_POINTER1( hSRS, "OSRSetMC", CE_Failure );
    4762                 : 
    4763                 :     return ((OGRSpatialReference *) hSRS)->SetMC( 
    4764                 :         dfCenterLat, dfCenterLong, 
    4765               0 :         dfFalseEasting, dfFalseNorthing );
    4766                 : }
    4767                 : 
    4768                 : /************************************************************************/
    4769                 : /*                            SetMercator()                             */
    4770                 : /************************************************************************/
    4771                 : 
    4772              79 : OGRErr OGRSpatialReference::SetMercator( double dfCenterLat, double dfCenterLong,
    4773                 :                                          double dfScale,
    4774                 :                                          double dfFalseEasting,
    4775                 :                                          double dfFalseNorthing )
    4776                 : 
    4777                 : {
    4778              79 :     SetProjection( SRS_PT_MERCATOR_1SP );
    4779                 : 
    4780              79 :     if( dfCenterLat != 0.0 )
    4781               4 :         SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4782                 : 
    4783              79 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4784              79 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    4785              79 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4786              79 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4787                 : 
    4788              79 :     return OGRERR_NONE;
    4789                 : }
    4790                 : 
    4791                 : /************************************************************************/
    4792                 : /*                           OSRSetMercator()                           */
    4793                 : /************************************************************************/
    4794                 : 
    4795               0 : OGRErr OSRSetMercator( OGRSpatialReferenceH hSRS, 
    4796                 :                        double dfCenterLat, double dfCenterLong,
    4797                 :                        double dfScale,
    4798                 :                        double dfFalseEasting, double dfFalseNorthing )
    4799                 :     
    4800                 : {
    4801               0 :     VALIDATE_POINTER1( hSRS, "OSRSetMercator", CE_Failure );
    4802                 : 
    4803                 :     return ((OGRSpatialReference *) hSRS)->SetMercator( 
    4804                 :         dfCenterLat, dfCenterLong, 
    4805                 :         dfScale,
    4806               0 :         dfFalseEasting, dfFalseNorthing );
    4807                 : }
    4808                 : 
    4809                 : /************************************************************************/
    4810                 : /*                           SetMercator2SP()                           */
    4811                 : /************************************************************************/
    4812                 : 
    4813              15 : OGRErr OGRSpatialReference::SetMercator2SP( 
    4814                 :     double dfStdP1, 
    4815                 :     double dfCenterLat, double dfCenterLong,
    4816                 :     double dfFalseEasting,
    4817                 :     double dfFalseNorthing )
    4818                 : 
    4819                 : {
    4820              15 :     SetProjection( SRS_PT_MERCATOR_2SP );
    4821                 : 
    4822              15 :     SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
    4823              15 :     if( dfCenterLat != 0.0 )
    4824               0 :         SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4825                 : 
    4826              15 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4827              15 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4828              15 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4829                 : 
    4830              15 :     return OGRERR_NONE;
    4831                 : }
    4832                 : 
    4833                 : /************************************************************************/
    4834                 : /*                         OSRSetMercator2SP()                          */
    4835                 : /************************************************************************/
    4836                 : 
    4837               0 : OGRErr OSRSetMercator2SP( OGRSpatialReferenceH hSRS, 
    4838                 :                           double dfStdP1,
    4839                 :                           double dfCenterLat, double dfCenterLong,
    4840                 :                           double dfFalseEasting, double dfFalseNorthing )
    4841                 :     
    4842                 : {
    4843               0 :     VALIDATE_POINTER1( hSRS, "OSRSetMercator2SP", CE_Failure );
    4844                 : 
    4845                 :     return ((OGRSpatialReference *) hSRS)->SetMercator2SP( 
    4846                 :         dfStdP1, 
    4847                 :         dfCenterLat, dfCenterLong, 
    4848               0 :         dfFalseEasting, dfFalseNorthing );
    4849                 : }
    4850                 : 
    4851                 : /************************************************************************/
    4852                 : /*                            SetMollweide()                            */
    4853                 : /************************************************************************/
    4854                 : 
    4855               1 : OGRErr OGRSpatialReference::SetMollweide( double dfCentralMeridian,
    4856                 :                                           double dfFalseEasting,
    4857                 :                                           double dfFalseNorthing )
    4858                 : 
    4859                 : {
    4860               1 :     SetProjection( SRS_PT_MOLLWEIDE );
    4861               1 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    4862               1 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4863               1 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4864                 : 
    4865               1 :     return OGRERR_NONE;
    4866                 : }
    4867                 : 
    4868                 : /************************************************************************/
    4869                 : /*                          OSRSetMollweide()                           */
    4870                 : /************************************************************************/
    4871                 : 
    4872               0 : OGRErr OSRSetMollweide( OGRSpatialReferenceH hSRS, 
    4873                 :                         double dfCentralMeridian,
    4874                 :                         double dfFalseEasting, double dfFalseNorthing )
    4875                 :     
    4876                 : {
    4877               0 :     VALIDATE_POINTER1( hSRS, "OSRSetMollweide", CE_Failure );
    4878                 : 
    4879                 :     return ((OGRSpatialReference *) hSRS)->SetMollweide( 
    4880                 :         dfCentralMeridian,
    4881               0 :         dfFalseEasting, dfFalseNorthing );
    4882                 : }
    4883                 : 
    4884                 : /************************************************************************/
    4885                 : /*                              SetNZMG()                               */
    4886                 : /************************************************************************/
    4887                 : 
    4888              10 : OGRErr OGRSpatialReference::SetNZMG( double dfCenterLat, double dfCenterLong,
    4889                 :                                      double dfFalseEasting,
    4890                 :                                      double dfFalseNorthing )
    4891                 : 
    4892                 : {
    4893              10 :     SetProjection( SRS_PT_NEW_ZEALAND_MAP_GRID );
    4894              10 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4895              10 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4896              10 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4897              10 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4898                 : 
    4899              10 :     return OGRERR_NONE;
    4900                 : }
    4901                 : 
    4902                 : /************************************************************************/
    4903                 : /*                             OSRSetNZMG()                             */
    4904                 : /************************************************************************/
    4905                 : 
    4906               0 : OGRErr OSRSetNZMG( OGRSpatialReferenceH hSRS, 
    4907                 :                    double dfCenterLat, double dfCenterLong,
    4908                 :                    double dfFalseEasting, double dfFalseNorthing )
    4909                 :     
    4910                 : {
    4911               0 :     VALIDATE_POINTER1( hSRS, "OSRSetNZMG", CE_Failure );
    4912                 : 
    4913                 :     return ((OGRSpatialReference *) hSRS)->SetNZMG( 
    4914                 :         dfCenterLat, dfCenterLong, 
    4915               0 :         dfFalseEasting, dfFalseNorthing );
    4916                 : }
    4917                 : 
    4918                 : /************************************************************************/
    4919                 : /*                               SetOS()                                */
    4920                 : /************************************************************************/
    4921                 : 
    4922              76 : OGRErr OGRSpatialReference::SetOS( double dfOriginLat, double dfCMeridian,
    4923                 :                                    double dfScale,
    4924                 :                                    double dfFalseEasting,
    4925                 :                                    double dfFalseNorthing )
    4926                 : 
    4927                 : {
    4928              76 :     SetProjection( SRS_PT_OBLIQUE_STEREOGRAPHIC );
    4929              76 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfOriginLat );
    4930              76 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCMeridian );
    4931              76 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    4932              76 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4933              76 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4934                 : 
    4935              76 :     return OGRERR_NONE;
    4936                 : }
    4937                 : 
    4938                 : /************************************************************************/
    4939                 : /*                              OSRSetOS()                              */
    4940                 : /************************************************************************/
    4941                 : 
    4942               0 : OGRErr OSRSetOS( OGRSpatialReferenceH hSRS, 
    4943                 :                  double dfOriginLat, double dfCMeridian,
    4944                 :                  double dfScale,
    4945                 :                  double dfFalseEasting, double dfFalseNorthing )
    4946                 :     
    4947                 : {
    4948               0 :     VALIDATE_POINTER1( hSRS, "OSRSetOS", CE_Failure );
    4949                 : 
    4950                 :     return ((OGRSpatialReference *) hSRS)->SetOS( 
    4951                 :         dfOriginLat, dfCMeridian,
    4952                 :         dfScale,
    4953               0 :         dfFalseEasting, dfFalseNorthing );
    4954                 : }
    4955                 : 
    4956                 : /************************************************************************/
    4957                 : /*                          SetOrthographic()                           */
    4958                 : /************************************************************************/
    4959                 : 
    4960              12 : OGRErr OGRSpatialReference::SetOrthographic(
    4961                 :                                 double dfCenterLat, double dfCenterLong,
    4962                 :                                 double dfFalseEasting, double dfFalseNorthing )
    4963                 : 
    4964                 : {
    4965              12 :     SetProjection( SRS_PT_ORTHOGRAPHIC );
    4966              12 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    4967              12 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    4968              12 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    4969              12 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    4970                 : 
    4971              12 :     return OGRERR_NONE;
    4972                 : }
    4973                 : 
    4974                 : /************************************************************************/
    4975                 : /*                         OSRSetOrthographic()                         */
    4976                 : /************************************************************************/
    4977                 : 
    4978               0 : OGRErr OSRSetOrthographic( OGRSpatialReferenceH hSRS, 
    4979                 :                            double dfCenterLat, double dfCenterLong,
    4980                 :                            double dfFalseEasting, double dfFalseNorthing )
    4981                 :     
    4982                 : {
    4983               0 :     VALIDATE_POINTER1( hSRS, "OSRSetOrthographic", CE_Failure );
    4984                 : 
    4985                 :     return ((OGRSpatialReference *) hSRS)->SetOrthographic( 
    4986                 :         dfCenterLat, dfCenterLong, 
    4987               0 :         dfFalseEasting, dfFalseNorthing );
    4988                 : }
    4989                 : 
    4990                 : /************************************************************************/
    4991                 : /*                            SetPolyconic()                            */
    4992                 : /************************************************************************/
    4993                 : 
    4994              18 : OGRErr OGRSpatialReference::SetPolyconic(
    4995                 :                                 double dfCenterLat, double dfCenterLong,
    4996                 :                                 double dfFalseEasting, double dfFalseNorthing )
    4997                 : 
    4998                 : {
    4999                 :     // note: it seems that by some definitions this should include a
    5000                 :     //       scale_factor parameter.
    5001                 :     
    5002              18 :     SetProjection( SRS_PT_POLYCONIC );
    5003              18 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    5004              18 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    5005              18 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5006              18 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5007                 : 
    5008              18 :     return OGRERR_NONE;
    5009                 : }
    5010                 : 
    5011                 : /************************************************************************/
    5012                 : /*                          OSRSetPolyconic()                           */
    5013                 : /************************************************************************/
    5014                 : 
    5015               0 : OGRErr OSRSetPolyconic( OGRSpatialReferenceH hSRS, 
    5016                 :                         double dfCenterLat, double dfCenterLong,
    5017                 :                         double dfFalseEasting, double dfFalseNorthing )
    5018                 :     
    5019                 : {
    5020               0 :     VALIDATE_POINTER1( hSRS, "OSRSetPolyconic", CE_Failure );
    5021                 : 
    5022                 :     return ((OGRSpatialReference *) hSRS)->SetPolyconic( 
    5023                 :         dfCenterLat, dfCenterLong, 
    5024               0 :         dfFalseEasting, dfFalseNorthing );
    5025                 : }
    5026                 : 
    5027                 : /************************************************************************/
    5028                 : /*                               SetPS()                                */
    5029                 : /************************************************************************/
    5030                 : 
    5031             120 : OGRErr OGRSpatialReference::SetPS(
    5032                 :                                 double dfCenterLat, double dfCenterLong,
    5033                 :                                 double dfScale,
    5034                 :                                 double dfFalseEasting, double dfFalseNorthing )
    5035                 : 
    5036                 : {
    5037             120 :     SetProjection( SRS_PT_POLAR_STEREOGRAPHIC );
    5038             120 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    5039             120 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
    5040             120 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    5041             120 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5042             120 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5043                 : 
    5044             120 :     return OGRERR_NONE;
    5045                 : }
    5046                 : 
    5047                 : /************************************************************************/
    5048                 : /*                              OSRSetPS()                              */
    5049                 : /************************************************************************/
    5050                 : 
    5051               0 : OGRErr OSRSetPS( OGRSpatialReferenceH hSRS, 
    5052                 :                  double dfCenterLat, double dfCenterLong,
    5053                 :                  double dfScale,
    5054                 :                  double dfFalseEasting, double dfFalseNorthing )
    5055                 :     
    5056                 : {
    5057               0 :     VALIDATE_POINTER1( hSRS, "OSRSetPS", CE_Failure );
    5058                 : 
    5059                 :     return ((OGRSpatialReference *) hSRS)->SetPS( 
    5060                 :         dfCenterLat, dfCenterLong, 
    5061                 :         dfScale,
    5062               0 :         dfFalseEasting, dfFalseNorthing );
    5063                 : }
    5064                 : 
    5065                 : /************************************************************************/
    5066                 : /*                            SetRobinson()                             */
    5067                 : /************************************************************************/
    5068                 : 
    5069               1 : OGRErr OGRSpatialReference::SetRobinson( double dfCenterLong,
    5070                 :                                          double dfFalseEasting,
    5071                 :                                          double dfFalseNorthing )
    5072                 : 
    5073                 : {
    5074               1 :     SetProjection( SRS_PT_ROBINSON );
    5075               1 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    5076               1 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5077               1 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5078                 : 
    5079               1 :     return OGRERR_NONE;
    5080                 : }
    5081                 : 
    5082                 : /************************************************************************/
    5083                 : /*                           OSRSetRobinson()                           */
    5084                 : /************************************************************************/
    5085                 : 
    5086               0 : OGRErr OSRSetRobinson( OGRSpatialReferenceH hSRS, 
    5087                 :                         double dfCenterLong,
    5088                 :                         double dfFalseEasting, double dfFalseNorthing )
    5089                 :     
    5090                 : {
    5091               0 :     VALIDATE_POINTER1( hSRS, "OSRSetRobinson", CE_Failure );
    5092                 : 
    5093                 :     return ((OGRSpatialReference *) hSRS)->SetRobinson( 
    5094                 :         dfCenterLong, 
    5095               0 :         dfFalseEasting, dfFalseNorthing );
    5096                 : }
    5097                 : 
    5098                 : /************************************************************************/
    5099                 : /*                           SetSinusoidal()                            */
    5100                 : /************************************************************************/
    5101                 : 
    5102              11 : OGRErr OGRSpatialReference::SetSinusoidal( double dfCenterLong,
    5103                 :                                            double dfFalseEasting,
    5104                 :                                            double dfFalseNorthing )
    5105                 : 
    5106                 : {
    5107              11 :     SetProjection( SRS_PT_SINUSOIDAL );
    5108              11 :     SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
    5109              11 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5110              11 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5111                 : 
    5112              11 :     return OGRERR_NONE;
    5113                 : }
    5114                 : 
    5115                 : /************************************************************************/
    5116                 : /*                          OSRSetSinusoidal()                          */
    5117                 : /************************************************************************/
    5118                 : 
    5119               0 : OGRErr OSRSetSinusoidal( OGRSpatialReferenceH hSRS, 
    5120                 :                          double dfCenterLong,
    5121                 :                          double dfFalseEasting, double dfFalseNorthing )
    5122                 :     
    5123                 : {
    5124               0 :     VALIDATE_POINTER1( hSRS, "OSRSetSinusoidal", CE_Failure );
    5125                 : 
    5126                 :     return ((OGRSpatialReference *) hSRS)->SetSinusoidal( 
    5127                 :         dfCenterLong, 
    5128               0 :         dfFalseEasting, dfFalseNorthing );
    5129                 : }
    5130                 : 
    5131                 : /************************************************************************/
    5132                 : /*                          SetStereographic()                          */
    5133                 : /************************************************************************/
    5134                 : 
    5135              11 : OGRErr OGRSpatialReference::SetStereographic(
    5136                 :                             double dfOriginLat, double dfCMeridian,
    5137                 :                             double dfScale,
    5138                 :                             double dfFalseEasting,
    5139                 :                             double dfFalseNorthing )
    5140                 : 
    5141                 : {
    5142              11 :     SetProjection( SRS_PT_STEREOGRAPHIC );
    5143              11 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfOriginLat );
    5144              11 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCMeridian );
    5145              11 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
    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                 : /*                        OSRSetStereographic()                         */
    5154                 : /************************************************************************/
    5155                 : 
    5156               0 : OGRErr OSRSetStereographic( OGRSpatialReferenceH hSRS, 
    5157                 :                             double dfOriginLat, double dfCMeridian,
    5158                 :                             double dfScale,
    5159                 :                             double dfFalseEasting, double dfFalseNorthing )
    5160                 :     
    5161                 : {
    5162               0 :     VALIDATE_POINTER1( hSRS, "OSRSetStereographic", CE_Failure );
    5163                 : 
    5164                 :     return ((OGRSpatialReference *) hSRS)->SetStereographic( 
    5165                 :         dfOriginLat, dfCMeridian,
    5166                 :         dfScale,
    5167               0 :         dfFalseEasting, dfFalseNorthing );
    5168                 : }
    5169                 : 
    5170                 : /************************************************************************/
    5171                 : /*                               SetSOC()                               */
    5172                 : /*                                                                      */
    5173                 : /*      NOTE: This definition isn't really used in practice any more    */
    5174                 : /*      and should be considered deprecated.  It seems that swiss       */
    5175                 : /*      oblique mercator is now define as Hotine_Oblique_Mercator       */
    5176                 : /*      with an azimuth of 90 and a rectified_grid_angle of 90.  See    */
    5177                 : /*      EPSG:2056 and Bug 423.                                          */
    5178                 : /************************************************************************/
    5179                 : 
    5180               0 : OGRErr OGRSpatialReference::SetSOC( double dfLatitudeOfOrigin, 
    5181                 :                                     double dfCentralMeridian,
    5182                 :                                     double dfFalseEasting,
    5183                 :                                     double dfFalseNorthing )
    5184                 : 
    5185                 : {
    5186               0 :     SetProjection( SRS_PT_SWISS_OBLIQUE_CYLINDRICAL );
    5187               0 :     SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfLatitudeOfOrigin );
    5188               0 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
    5189               0 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5190               0 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5191                 : 
    5192               0 :     return OGRERR_NONE;
    5193                 : }
    5194                 : 
    5195                 : /************************************************************************/
    5196                 : /*                             OSRSetSOC()                              */
    5197                 : /************************************************************************/
    5198                 : 
    5199               0 : OGRErr OSRSetSOC( OGRSpatialReferenceH hSRS, 
    5200                 :                   double dfLatitudeOfOrigin, double dfCentralMeridian,
    5201                 :                   double dfFalseEasting, double dfFalseNorthing )
    5202                 :     
    5203                 : {
    5204               0 :     VALIDATE_POINTER1( hSRS, "OSRSetSOC", CE_Failure );
    5205                 : 
    5206                 :     return ((OGRSpatialReference *) hSRS)->SetSOC( 
    5207                 :         dfLatitudeOfOrigin, dfCentralMeridian,
    5208               0 :         dfFalseEasting, dfFalseNorthing );
    5209                 : }
    5210                 : 
    5211                 : /************************************************************************/
    5212                 : /*                               SetVDG()                               */
    5213                 : /************************************************************************/
    5214                 : 
    5215               4 : OGRErr OGRSpatialReference::SetVDG( double dfCMeridian,
    5216                 :                                     double dfFalseEasting,
    5217                 :                                     double dfFalseNorthing )
    5218                 : 
    5219                 : {
    5220               4 :     SetProjection( SRS_PT_VANDERGRINTEN );
    5221               4 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCMeridian );
    5222               4 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5223               4 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5224                 : 
    5225               4 :     return OGRERR_NONE;
    5226                 : }
    5227                 : 
    5228                 : /************************************************************************/
    5229                 : /*                             OSRSetVDG()                              */
    5230                 : /************************************************************************/
    5231                 : 
    5232               0 : OGRErr OSRSetVDG( OGRSpatialReferenceH hSRS, 
    5233                 :                   double dfCentralMeridian,
    5234                 :                   double dfFalseEasting, double dfFalseNorthing )
    5235                 :     
    5236                 : {
    5237               0 :     VALIDATE_POINTER1( hSRS, "OSRSetVDG", CE_Failure );
    5238                 : 
    5239                 :     return ((OGRSpatialReference *) hSRS)->SetVDG( 
    5240                 :         dfCentralMeridian,
    5241               0 :         dfFalseEasting, dfFalseNorthing );
    5242                 : }
    5243                 : 
    5244                 : /************************************************************************/
    5245                 : /*                               SetUTM()                               */
    5246                 : /************************************************************************/
    5247                 : 
    5248                 : /**
    5249                 :  * \brief Set UTM projection definition.
    5250                 :  *
    5251                 :  * This will generate a projection definition with the full set of 
    5252                 :  * transverse mercator projection parameters for the given UTM zone.
    5253                 :  * If no PROJCS[] description is set yet, one will be set to look
    5254                 :  * like "UTM Zone %d, {Northern, Southern} Hemisphere". 
    5255                 :  *
    5256                 :  * This method is the same as the C function OSRSetUTM().
    5257                 :  *
    5258                 :  * @param nZone UTM zone.
    5259                 :  *
    5260                 :  * @param bNorth TRUE for northern hemisphere, or FALSE for southern 
    5261                 :  * hemisphere. 
    5262                 :  * 
    5263                 :  * @return OGRERR_NONE on success. 
    5264                 :  */
    5265                 : 
    5266             166 : OGRErr OGRSpatialReference::SetUTM( int nZone, int bNorth )
    5267                 : 
    5268                 : {
    5269             166 :     SetProjection( SRS_PT_TRANSVERSE_MERCATOR );
    5270             166 :     SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0 );
    5271             166 :     SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, nZone * 6 - 183 );
    5272             166 :     SetNormProjParm( SRS_PP_SCALE_FACTOR, 0.9996 );
    5273             166 :     SetNormProjParm( SRS_PP_FALSE_EASTING, 500000.0 );
    5274                 : 
    5275             166 :     if( bNorth )
    5276             134 :         SetNormProjParm( SRS_PP_FALSE_NORTHING, 0 );
    5277                 :     else
    5278              32 :         SetNormProjParm( SRS_PP_FALSE_NORTHING, 10000000 );
    5279                 : 
    5280             166 :     if( EQUAL(GetAttrValue("PROJCS"),"unnamed") )
    5281                 :     {
    5282                 :         char    szUTMName[128];
    5283                 : 
    5284             160 :         if( bNorth )
    5285             129 :             sprintf( szUTMName, "UTM Zone %d, Northern Hemisphere", nZone );
    5286                 :         else
    5287              31 :             sprintf( szUTMName, "UTM Zone %d, Southern Hemisphere", nZone );
    5288                 : 
    5289             160 :         SetNode( "PROJCS", szUTMName );
    5290                 :     }
    5291                 : 
    5292             166 :     SetLinearUnits( SRS_UL_METER, 1.0 );
    5293                 : 
    5294             166 :     return OGRERR_NONE;
    5295                 : }
    5296                 : 
    5297                 : /************************************************************************/
    5298                 : /*                             OSRSetUTM()                              */
    5299                 : /************************************************************************/
    5300                 : 
    5301                 : /**
    5302                 :  * \brief Set UTM projection definition.
    5303                 :  *
    5304                 :  * This is the same as the C++ method OGRSpatialReference::SetUTM()
    5305                 :  */
    5306              10 : OGRErr OSRSetUTM( OGRSpatialReferenceH hSRS, int nZone, int bNorth )
    5307                 : 
    5308                 : {
    5309              10 :     VALIDATE_POINTER1( hSRS, "OSRSetUTM", CE_Failure );
    5310                 : 
    5311              10 :     return ((OGRSpatialReference *) hSRS)->SetUTM( nZone, bNorth );
    5312                 : }
    5313                 : 
    5314                 : /************************************************************************/
    5315                 : /*                             GetUTMZone()                             */
    5316                 : /*                                                                      */
    5317                 : /*      Returns zero if it isn't UTM.                                   */
    5318                 : /************************************************************************/
    5319                 : 
    5320                 : /**
    5321                 :  * \brief Get utm zone information.
    5322                 :  *
    5323                 :  * This is the same as the C function OSRGetUTMZone().
    5324                 :  *
    5325                 :  * In SWIG bindings (Python, Java, etc) the GetUTMZone() method returns a 
    5326                 :  * zone which is negative in the southern hemisphere instead of having the 
    5327                 :  * pbNorth flag used in the C and C++ interface.
    5328                 :  *
    5329                 :  * @param pbNorth pointer to in to set to TRUE if northern hemisphere, or
    5330                 :  * FALSE if southern. 
    5331                 :  * 
    5332                 :  * @return UTM zone number or zero if this isn't a UTM definition. 
    5333                 :  */
    5334                 : 
    5335           15089 : int OGRSpatialReference::GetUTMZone( int * pbNorth ) const
    5336                 : 
    5337                 : {
    5338           15089 :     const char  *pszProjection = GetAttrValue( "PROJECTION" );
    5339                 : 
    5340           15089 :     if( pszProjection == NULL
    5341                 :         || !EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR) )
    5342            6202 :         return 0;
    5343                 : 
    5344            8887 :     if( GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) != 0.0 )
    5345            2239 :         return 0;
    5346                 : 
    5347            6648 :     if( GetProjParm( SRS_PP_SCALE_FACTOR, 1.0 ) != 0.9996 )
    5348            3137 :         return 0;
    5349                 :           
    5350            3511 :     if( fabs(GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 )-500000.0) > 0.001 )
    5351             146 :         return 0;
    5352                 : 
    5353            3365 :     double      dfFalseNorthing = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0);
    5354                 : 
    5355            3365 :     if( dfFalseNorthing != 0.0 
    5356                 :         && fabs(dfFalseNorthing-10000000.0) > 0.001 )
    5357               8 :         return 0;
    5358                 : 
    5359            3357 :     if( pbNorth != NULL )
    5360            3316 :         *pbNorth = (dfFalseNorthing == 0);
    5361                 : 
    5362                 :     double      dfCentralMeridian = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, 
    5363            3357 :                                                      0.0);
    5364            3357 :     double      dfZone = ( dfCentralMeridian + 186.0 ) / 6.0;
    5365                 : 
    5366            3357 :     if( ABS(dfZone - (int) dfZone - 0.5 ) > 0.00001
    5367                 :         || dfCentralMeridian < -177.00001
    5368                 :         || dfCentralMeridian > 177.000001 )
    5369              74 :         return 0;
    5370                 :     else
    5371            3283 :         return (int) dfZone;
    5372                 : }
    5373                 : 
    5374                 : /************************************************************************/
    5375                 : /*                           OSRGetUTMZone()                            */
    5376                 : /************************************************************************/
    5377                 : 
    5378                 : /**
    5379                 :  * \brief Get utm zone information.
    5380                 :  *
    5381                 :  * This is the same as the C++ method OGRSpatialReference::GetUTMZone()
    5382                 :  */
    5383               2 : int OSRGetUTMZone( OGRSpatialReferenceH hSRS, int *pbNorth )
    5384                 : 
    5385                 : {
    5386               2 :     VALIDATE_POINTER1( hSRS, "OSRGetUTMZone", 0 );
    5387                 : 
    5388               2 :     return ((OGRSpatialReference *) hSRS)->GetUTMZone( pbNorth );
    5389                 : }
    5390                 : 
    5391                 : /************************************************************************/
    5392                 : /*                             SetWagner()                              */
    5393                 : /************************************************************************/
    5394                 : 
    5395               7 : OGRErr OGRSpatialReference::SetWagner( int nVariation /* 1 -- 7 */,
    5396                 :                                        double dfCenterLat,
    5397                 :                                        double dfFalseEasting,
    5398                 :                                        double dfFalseNorthing )
    5399                 : 
    5400                 : {
    5401               7 :     if( nVariation == 1 )
    5402               1 :         SetProjection( SRS_PT_WAGNER_I );
    5403               6 :     else if( nVariation == 2 )
    5404               1 :         SetProjection( SRS_PT_WAGNER_II );
    5405               5 :     else if( nVariation == 3 )
    5406                 :     {
    5407               1 :         SetProjection( SRS_PT_WAGNER_III );
    5408               1 :         SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
    5409                 :     }
    5410               4 :     else if( nVariation == 4 )
    5411               1 :         SetProjection( SRS_PT_WAGNER_IV );
    5412               3 :     else if( nVariation == 5 )
    5413               1 :         SetProjection( SRS_PT_WAGNER_V );
    5414               2 :     else if( nVariation == 6 )
    5415               1 :         SetProjection( SRS_PT_WAGNER_VI );
    5416               1 :     else if( nVariation == 7 )
    5417               1 :         SetProjection( SRS_PT_WAGNER_VII );
    5418                 :     else
    5419                 :     {
    5420                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    5421               0 :                   "Unsupported Wagner variation (%d).", nVariation );
    5422               0 :         return OGRERR_UNSUPPORTED_SRS;
    5423                 :     }
    5424                 : 
    5425               7 :     SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
    5426               7 :     SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
    5427                 : 
    5428               7 :     return OGRERR_NONE;
    5429                 : }
    5430                 : 
    5431                 : /************************************************************************/
    5432                 : /*                            OSRSetWagner()                            */
    5433                 : /************************************************************************/
    5434                 : 
    5435               0 : OGRErr OSRSetWagner( OGRSpatialReferenceH hSRS, 
    5436                 :                      int nVariation, double dfCenterLat,
    5437                 :                      double dfFalseEasting,
    5438                 :                      double dfFalseNorthing )
    5439                 : 
    5440                 : {
    5441               0 :     VALIDATE_POINTER1( hSRS, "OSRSetWagner", CE_Failure );
    5442                 : 
    5443                 :     return ((OGRSpatialReference *) hSRS)->SetWagner( 
    5444               0 :         nVariation, dfCenterLat, dfFalseEasting, dfFalseNorthing );
    5445                 : }
    5446                 : 
    5447                 : /************************************************************************/
    5448                 : /*                            SetAuthority()                            */
    5449                 : /************************************************************************/
    5450                 : 
    5451                 : /**
    5452                 :  * \brief Set the authority for a node.
    5453                 :  *
    5454                 :  * This method is the same as the C function OSRSetAuthority().
    5455                 :  *
    5456                 :  * @param pszTargetKey the partial or complete path to the node to 
    5457                 :  * set an authority on.  ie. "PROJCS", "GEOGCS" or "GEOGCS|UNIT".
    5458                 :  *
    5459                 :  * @param pszAuthority authority name, such as "EPSG".
    5460                 :  *
    5461                 :  * @param nCode code for value with this authority.
    5462                 :  *
    5463                 :  * @return OGRERR_NONE on success.
    5464                 :  */
    5465                 : 
    5466          114671 : OGRErr OGRSpatialReference::SetAuthority( const char *pszTargetKey,
    5467                 :                                           const char * pszAuthority, 
    5468                 :                                           int nCode )
    5469                 : 
    5470                 : {
    5471                 : /* -------------------------------------------------------------------- */
    5472                 : /*      Find the node below which the authority should be put.          */
    5473                 : /* -------------------------------------------------------------------- */
    5474          114671 :     OGR_SRSNode  *poNode = GetAttrNode( pszTargetKey );
    5475                 : 
    5476          114671 :     if( poNode == NULL )
    5477               4 :         return OGRERR_FAILURE;
    5478                 : 
    5479                 : /* -------------------------------------------------------------------- */
    5480                 : /*      If there is an existing AUTHORITY child blow it away before     */
    5481                 : /*      trying to set a new one.                                        */
    5482                 : /* -------------------------------------------------------------------- */
    5483          114667 :     int iOldChild = poNode->FindChild( "AUTHORITY" );
    5484          114667 :     if( iOldChild != -1 )
    5485               0 :         poNode->DestroyChild( iOldChild );
    5486                 : 
    5487                 : /* -------------------------------------------------------------------- */
    5488                 : /*      Create a new authority node.                                    */
    5489                 : /* -------------------------------------------------------------------- */
    5490                 :     char   szCode[32];
    5491                 :     OGR_SRSNode *poAuthNode;
    5492                 : 
    5493          114667 :     sprintf( szCode, "%d", nCode );
    5494                 : 
    5495          114667 :     poAuthNode = new OGR_SRSNode( "AUTHORITY" );
    5496          229334 :     poAuthNode->AddChild( new OGR_SRSNode( pszAuthority ) );
    5497          229334 :     poAuthNode->AddChild( new OGR_SRSNode( szCode ) );
    5498                 :     
    5499          114667 :     poNode->AddChild( poAuthNode );
    5500                 : 
    5501          114667 :     return OGRERR_NONE;
    5502                 : }
    5503                 : 
    5504                 : /************************************************************************/
    5505                 : /*                          OSRSetAuthority()                           */
    5506                 : /************************************************************************/
    5507                 : 
    5508                 : /**
    5509                 :  * \brief Set the authority for a node.
    5510                 :  *
    5511                 :  * This function is the same as OGRSpatialReference::SetAuthority().
    5512                 :  */
    5513               0 : OGRErr OSRSetAuthority( OGRSpatialReferenceH hSRS, 
    5514                 :                         const char *pszTargetKey,
    5515                 :                         const char * pszAuthority, 
    5516                 :                         int nCode )
    5517                 : 
    5518                 : {
    5519               0 :     VALIDATE_POINTER1( hSRS, "OSRSetAuthority", CE_Failure );
    5520                 : 
    5521                 :     return ((OGRSpatialReference *) hSRS)->SetAuthority( pszTargetKey, 
    5522                 :                                                          pszAuthority,
    5523               0 :                                                          nCode );
    5524                 : }
    5525                 : 
    5526                 : /************************************************************************/
    5527                 : /*                          GetAuthorityCode()                          */
    5528                 : /************************************************************************/
    5529                 : 
    5530                 : /**
    5531                 :  * \brief Get the authority code for a node.
    5532                 :  *
    5533                 :  * This method is used to query an AUTHORITY[] node from within the 
    5534                 :  * WKT tree, and fetch the code value.  
    5535                 :  *
    5536                 :  * While in theory values may be non-numeric, for the EPSG authority all
    5537                 :  * code values should be integral.
    5538                 :  *
    5539                 :  * This method is the same as the C function OSRGetAuthorityCode().
    5540                 :  *
    5541                 :  * @param pszTargetKey the partial or complete path to the node to 
    5542                 :  * get an authority from.  ie. "PROJCS", "GEOGCS", "GEOGCS|UNIT" or NULL to 
    5543                 :  * search for an authority node on the root element.
    5544                 :  *
    5545                 :  * @return value code from authority node, or NULL on failure.  The value
    5546                 :  * returned is internal and should not be freed or modified.
    5547                 :  */
    5548                 : 
    5549                 : const char *
    5550            4711 : OGRSpatialReference::GetAuthorityCode( const char *pszTargetKey ) const
    5551                 : 
    5552                 : {
    5553                 : /* -------------------------------------------------------------------- */
    5554                 : /*      Find the node below which the authority should be put.          */
    5555                 : /* -------------------------------------------------------------------- */
    5556                 :     const OGR_SRSNode  *poNode;
    5557                 : 
    5558            4711 :     if( pszTargetKey == NULL )
    5559             165 :         poNode = poRoot;
    5560                 :     else
    5561            4546 :         poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
    5562                 : 
    5563            4711 :     if( poNode == NULL )
    5564               0 :         return NULL;
    5565                 : 
    5566                 : /* -------------------------------------------------------------------- */
    5567                 : /*      Fetch AUTHORITY child if there is one.                          */
    5568                 : /* -------------------------------------------------------------------- */
    5569            4711 :     if( poNode->FindChild("AUTHORITY") == -1 )
    5570             566 :         return NULL;
    5571                 :         
    5572            4145 :     poNode = poNode->GetChild(poNode->FindChild("AUTHORITY"));
    5573                 : 
    5574                 : /* -------------------------------------------------------------------- */
    5575                 : /*      Create a new authority node.                                    */
    5576                 : /* -------------------------------------------------------------------- */
    5577            4145 :     if( poNode->GetChildCount() < 2 )
    5578               0 :         return NULL;
    5579                 : 
    5580            4145 :     return poNode->GetChild(1)->GetValue();
    5581                 : }
    5582                 : 
    5583                 : /************************************************************************/
    5584                 : /*                          OSRGetAuthorityCode()                       */
    5585                 : /************************************************************************/
    5586                 : 
    5587                 : /**
    5588                 :  * \brief Get the authority code for a node.
    5589                 :  *
    5590                 :  * This function is the same as OGRSpatialReference::GetAuthorityCode().
    5591                 :  */
    5592            1274 : const char *OSRGetAuthorityCode( OGRSpatialReferenceH hSRS, 
    5593                 :                                  const char *pszTargetKey )
    5594                 : 
    5595                 : {
    5596            1274 :     VALIDATE_POINTER1( hSRS, "OSRGetAuthorityCode", NULL );
    5597                 : 
    5598            1274 :     return ((OGRSpatialReference *) hSRS)->GetAuthorityCode( pszTargetKey );
    5599                 : }
    5600                 : 
    5601                 : /************************************************************************/
    5602                 : /*                          GetAuthorityName()                          */
    5603                 : /************************************************************************/
    5604                 : 
    5605                 : /**
    5606                 :  * \brief Get the authority name for a node.
    5607                 :  *
    5608                 :  * This method is used to query an AUTHORITY[] node from within the 
    5609                 :  * WKT tree, and fetch the authority name value.  
    5610                 :  *
    5611                 :  * The most common authority is "EPSG".
    5612                 :  *
    5613                 :  * This method is the same as the C function OSRGetAuthorityName().
    5614                 :  *
    5615                 :  * @param pszTargetKey the partial or complete path to the node to 
    5616                 :  * get an authority from.  ie. "PROJCS", "GEOGCS", "GEOGCS|UNIT" or NULL to 
    5617                 :  * search for an authority node on the root element.
    5618                 :  *
    5619                 :  * @return value code from authority node, or NULL on failure. The value
    5620                 :  * returned is internal and should not be freed or modified.
    5621                 :  */
    5622                 : 
    5623                 : const char *
    5624           41939 : OGRSpatialReference::GetAuthorityName( const char *pszTargetKey ) const
    5625                 : 
    5626                 : {
    5627                 : /* -------------------------------------------------------------------- */
    5628                 : /*      Find the node below which the authority should be put.          */
    5629                 : /* -------------------------------------------------------------------- */
    5630                 :     const OGR_SRSNode  *poNode;
    5631                 : 
    5632           41939 :     if( pszTargetKey == NULL )
    5633             114 :         poNode = poRoot;
    5634                 :     else
    5635           41825 :         poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
    5636                 : 
    5637           41939 :     if( poNode == NULL )
    5638            2935 :         return NULL;
    5639                 : 
    5640                 : /* -------------------------------------------------------------------- */
    5641                 : /*      Fetch AUTHORITY child if there is one.                          */
    5642                 : /* -------------------------------------------------------------------- */
    5643           39004 :     if( poNode->FindChild("AUTHORITY") == -1 )
    5644           16395 :         return NULL;
    5645                 :         
    5646           22609 :     poNode = poNode->GetChild(poNode->FindChild("AUTHORITY"));
    5647                 : 
    5648                 : /* -------------------------------------------------------------------- */
    5649                 : /*      Create a new authority node.                                    */
    5650                 : /* -------------------------------------------------------------------- */
    5651           22609 :     if( poNode->GetChildCount() < 2 )
    5652               0 :         return NULL;
    5653                 : 
    5654           22609 :     return poNode->GetChild(0)->GetValue();
    5655                 : }
    5656                 : 
    5657                 : /************************************************************************/
    5658                 : /*                        OSRGetAuthorityName()                         */
    5659                 : /************************************************************************/
    5660                 : 
    5661                 : /**
    5662                 :  * \brief Get the authority name for a node.
    5663                 :  *
    5664                 :  * This function is the same as OGRSpatialReference::GetAuthorityName().
    5665                 :  */
    5666              27 : const char *OSRGetAuthorityName( OGRSpatialReferenceH hSRS, 
    5667                 :                                  const char *pszTargetKey )
    5668                 : 
    5669                 : {
    5670              27 :     VALIDATE_POINTER1( hSRS, "OSRGetAuthorityName", NULL );
    5671                 : 
    5672              27 :     return ((OGRSpatialReference *) hSRS)->GetAuthorityName( pszTargetKey );
    5673                 : }
    5674                 : 
    5675                 : /************************************************************************/
    5676                 : /*                           StripVertical()                            */
    5677                 : /************************************************************************/
    5678                 : 
    5679                 : /**
    5680                 :  * \brief Convert a compound cs into a horizontal CS.
    5681                 :  *
    5682                 :  * If this SRS is of type COMPD_CS[] then the vertical CS and the root COMPD_CS 
    5683                 :  * nodes are stripped resulting and only the horizontal coordinate system
    5684                 :  * portion remains (normally PROJCS, GEOGCS or LOCAL_CS). 
    5685                 :  *
    5686                 :  * If this is not a compound coordinate system then nothing is changed.
    5687                 :  *
    5688                 :  * @since OGR 1.8.0
    5689                 :  */
    5690                 : 
    5691           35455 : OGRErr OGRSpatialReference::StripVertical()
    5692                 : 
    5693                 : {
    5694           35455 :     if( GetRoot() == NULL 
    5695                 :         || !EQUAL(GetRoot()->GetValue(),"COMPD_CS") )
    5696           35454 :         return OGRERR_NONE;
    5697                 : 
    5698               1 :     OGR_SRSNode *poHorizontalCS = GetRoot()->GetChild( 1 );
    5699               1 :     if( poHorizontalCS != NULL )
    5700               1 :         poHorizontalCS = poHorizontalCS->Clone();
    5701               1 :     SetRoot( poHorizontalCS );
    5702                 : 
    5703               1 :     return OGRERR_NONE;
    5704                 : }
    5705                 : 
    5706                 : /************************************************************************/
    5707                 : /*                            StripCTParms()                            */
    5708                 : /************************************************************************/
    5709                 : 
    5710                 : /** 
    5711                 :  * \brief Strip OGC CT Parameters.
    5712                 :  *
    5713                 :  * This method will remove all components of the coordinate system
    5714                 :  * that are specific to the OGC CT Specification.  That is it will attempt
    5715                 :  * to strip it down to being compatible with the Simple Features 1.0 
    5716                 :  * specification.
    5717                 :  *
    5718                 :  * This method is the same as the C function OSRStripCTParms().
    5719                 :  *
    5720                 :  * @param poCurrent node to operate on.  NULL to operate on whole tree.
    5721                 :  *
    5722                 :  * @return OGRERR_NONE on success or an error code.
    5723                 :  */
    5724                 : 
    5725           35454 : OGRErr OGRSpatialReference::StripCTParms( OGR_SRSNode * poCurrent )
    5726                 : 
    5727                 : {
    5728           35454 :     if( poCurrent == NULL )
    5729                 :     {
    5730           35454 :         StripVertical();
    5731           35454 :         poCurrent = GetRoot();
    5732                 :     }
    5733                 : 
    5734           35454 :     if( poCurrent == NULL )
    5735               0 :         return OGRERR_NONE;
    5736                 : 
    5737           35454 :     if( poCurrent == GetRoot() && EQUAL(poCurrent->GetValue(),"LOCAL_CS") )
    5738                 :     {
    5739               0 :         delete poCurrent;
    5740               0 :         poRoot = NULL;
    5741                 : 
    5742               0 :         return OGRERR_NONE;
    5743                 :     }
    5744                 :     
    5745           35454 :     if( poCurrent == NULL )
    5746               0 :         return OGRERR_NONE;
    5747                 : 
    5748           35454 :     poCurrent->StripNodes( "AUTHORITY" );
    5749           35454 :     poCurrent->StripNodes( "TOWGS84" );
    5750           35454 :     poCurrent->StripNodes( "AXIS" );
    5751           35454 :     poCurrent->StripNodes( "EXTENSION" );
    5752                 : 
    5753           35454 :     return OGRERR_NONE;
    5754                 : }
    5755                 : 
    5756                 : /************************************************************************/
    5757                 : /*                          OSRStripCTParms()                           */
    5758                 : /************************************************************************/
    5759                 : 
    5760                 : /** 
    5761                 :  * \brief Strip OGC CT Parameters.
    5762                 :  *
    5763                 :  * This function is the same as OGRSpatialReference::StripCTParms().
    5764                 :  */
    5765           16685 : OGRErr OSRStripCTParms( OGRSpatialReferenceH hSRS )
    5766                 : 
    5767                 : {
    5768           16685 :     VALIDATE_POINTER1( hSRS, "OSRStripCTParms", CE_Failure );
    5769                 : 
    5770           16685 :     return ((OGRSpatialReference *) hSRS)->StripCTParms( NULL );
    5771                 : }
    5772                 : 
    5773                 : /************************************************************************/
    5774                 : /*                             IsCompound()                             */
    5775                 : /************************************************************************/
    5776                 : 
    5777                 : /**
    5778                 :  * \brief Check if coordinate system is compound.
    5779                 :  *
    5780                 :  * This method is the same as the C function OSRIsCompound().
    5781                 :  *
    5782                 :  * @return TRUE if this is rooted with a COMPD_CS node.
    5783                 :  */
    5784                 : 
    5785               1 : int OGRSpatialReference::IsCompound() const
    5786                 : 
    5787                 : {
    5788               1 :     if( poRoot == NULL )
    5789               0 :         return FALSE;
    5790                 : 
    5791               1 :     return EQUAL(poRoot->GetValue(),"COMPD_CS");
    5792                 : }
    5793                 : 
    5794                 : /************************************************************************/
    5795                 : /*                           OSRIsCompound()                            */
    5796                 : /************************************************************************/
    5797                 : 
    5798                 : /** 
    5799                 :  * \brief Check if the coordinate system is compound.
    5800                 :  *
    5801                 :  * This function is the same as OGRSpatialReference::IsCompound().
    5802                 :  */
    5803               1 : int OSRIsCompound( OGRSpatialReferenceH hSRS ) 
    5804                 : 
    5805                 : {
    5806               1 :     VALIDATE_POINTER1( hSRS, "OSRIsCompound", 0 );
    5807                 : 
    5808               1 :     return ((OGRSpatialReference *) hSRS)->IsCompound();
    5809                 : }
    5810                 : 
    5811                 : /************************************************************************/
    5812                 : /*                            IsProjected()                             */
    5813                 : /************************************************************************/
    5814                 : 
    5815                 : /**
    5816                 :  * \brief Check if projected coordinate system.
    5817                 :  *
    5818                 :  * This method is the same as the C function OSRIsProjected().
    5819                 :  *
    5820                 :  * @return TRUE if this contains a PROJCS node indicating a it is a 
    5821                 :  * projected coordinate system. 
    5822                 :  */
    5823                 : 
    5824           48832 : int OGRSpatialReference::IsProjected() const
    5825                 : 
    5826                 : {
    5827           48832 :     if( poRoot == NULL )
    5828             314 :         return FALSE;
    5829                 : 
    5830           48518 :     if( EQUAL(poRoot->GetValue(),"PROJCS") )
    5831           36250 :         return TRUE;
    5832           12268 :     else if( EQUAL(poRoot->GetValue(),"COMPD_CS") )
    5833              18 :         return GetAttrNode( "PROJCS" ) != NULL;
    5834                 :     else 
    5835           12250 :         return FALSE;
    5836                 : }
    5837                 : 
    5838                 : /************************************************************************/
    5839                 : /*                           OSRIsProjected()                           */
    5840                 : /************************************************************************/
    5841                 : /** 
    5842                 :  * \brief Check if projected coordinate system.
    5843                 :  *
    5844                 :  * This function is the same as OGRSpatialReference::IsProjected().
    5845                 :  */
    5846               6 : int OSRIsProjected( OGRSpatialReferenceH hSRS ) 
    5847                 : 
    5848                 : {
    5849               6 :     VALIDATE_POINTER1( hSRS, "OSRIsProjected", 0 );
    5850                 : 
    5851               6 :     return ((OGRSpatialReference *) hSRS)->IsProjected();
    5852                 : }
    5853                 : 
    5854                 : /************************************************************************/
    5855                 : /*                            IsGeocentric()                            */
    5856                 : /************************************************************************/
    5857                 : 
    5858                 : /**
    5859                 :  * \brief Check if geocentric coordinate system.
    5860                 :  *
    5861                 :  * This method is the same as the C function OSRIsGeocentric().
    5862                 :  *
    5863                 :  * @return TRUE if this contains a GEOCCS node indicating a it is a 
    5864                 :  * geocentric coordinate system.
    5865                 :  *
    5866                 :  * @since OGR 1.9.0
    5867                 :  */
    5868                 : 
    5869           28127 : int OGRSpatialReference::IsGeocentric() const
    5870                 : 
    5871                 : {
    5872           28127 :     if( poRoot == NULL )
    5873            7823 :         return FALSE;
    5874                 : 
    5875           20304 :     if( EQUAL(poRoot->GetValue(),"GEOCCS") )
    5876              12 :         return TRUE;
    5877                 :     else 
    5878           20292 :         return FALSE;
    5879                 : }
    5880                 : 
    5881                 : /************************************************************************/
    5882                 : /*                           OSRIsGeocentric()                          */
    5883                 : /************************************************************************/
    5884                 : /** 
    5885                 :  * \brief Check if geocentric coordinate system.
    5886                 :  *
    5887                 :  * This function is the same as OGRSpatialReference::IsGeocentric().
    5888                 :  *
    5889                 :  * @since OGR 1.9.0
    5890                 :  */
    5891               2 : int OSRIsGeocentric( OGRSpatialReferenceH hSRS ) 
    5892                 : 
    5893                 : {
    5894               2 :     VALIDATE_POINTER1( hSRS, "OSRIsGeocentric", 0 );
    5895                 : 
    5896               2 :     return ((OGRSpatialReference *) hSRS)->IsGeocentric();
    5897                 : }
    5898                 : 
    5899                 : /************************************************************************/
    5900                 : /*                            IsGeographic()                            */
    5901                 : /************************************************************************/
    5902                 : 
    5903                 : /**
    5904                 :  * \brief Check if geographic coordinate system.
    5905                 :  *
    5906                 :  * This method is the same as the C function OSRIsGeographic().
    5907                 :  *
    5908                 :  * @return TRUE if this spatial reference is geographic ... that is the 
    5909                 :  * root is a GEOGCS node. 
    5910                 :  */
    5911                 : 
    5912            3056 : int OGRSpatialReference::IsGeographic() const
    5913                 : 
    5914                 : {
    5915            3056 :     if( GetRoot() == NULL )
    5916               9 :         return FALSE;
    5917                 : 
    5918            3047 :     if( EQUAL(poRoot->GetValue(),"GEOGCS") )
    5919            2334 :         return TRUE;
    5920             713 :     else if( EQUAL(poRoot->GetValue(),"COMPD_CS") )
    5921                 :         return GetAttrNode( "GEOGCS" ) != NULL 
    5922               2 :             && GetAttrNode( "PROJCS" ) == NULL;
    5923                 :     else 
    5924             711 :         return FALSE;
    5925                 : }
    5926                 : 
    5927                 : /************************************************************************/
    5928                 : /*                          OSRIsGeographic()                           */
    5929                 : /************************************************************************/
    5930                 : /** 
    5931                 :  * \brief Check if geographic coordinate system.
    5932                 :  *
    5933                 :  * This function is the same as OGRSpatialReference::IsGeographic().
    5934                 :  */
    5935               3 : int OSRIsGeographic( OGRSpatialReferenceH hSRS )
    5936                 : 
    5937                 : {
    5938               3 :     VALIDATE_POINTER1( hSRS, "OSRIsGeographic", 0 );
    5939                 : 
    5940               3 :     return ((OGRSpatialReference *) hSRS)->IsGeographic();
    5941                 : }
    5942                 : 
    5943                 : /************************************************************************/
    5944                 : /*                              IsLocal()                               */
    5945                 : /************************************************************************/
    5946                 : 
    5947                 : /**
    5948                 :  * \brief Check if local coordinate system.
    5949                 :  *
    5950                 :  * This method is the same as the C function OSRIsLocal().
    5951                 :  *
    5952                 :  * @return TRUE if this spatial reference is local ... that is the 
    5953                 :  * root is a LOCAL_CS node. 
    5954                 :  */
    5955                 : 
    5956           15497 : int OGRSpatialReference::IsLocal() const
    5957                 : 
    5958                 : {
    5959           15497 :     if( GetRoot() == NULL )
    5960              12 :         return FALSE;
    5961                 : 
    5962           15485 :     return EQUAL(GetRoot()->GetValue(),"LOCAL_CS");
    5963                 : }
    5964                 : 
    5965                 : /************************************************************************/
    5966                 : /*                          OSRIsLocal()                                */
    5967                 : /************************************************************************/
    5968                 : /** 
    5969                 :  * \brief Check if local coordinate system.
    5970                 :  *
    5971                 :  * This function is the same as OGRSpatialReference::IsLocal().
    5972                 :  */
    5973               1 : int OSRIsLocal( OGRSpatialReferenceH hSRS )
    5974                 : 
    5975                 : {
    5976               1 :     VALIDATE_POINTER1( hSRS, "OSRIsLocal", 0 );
    5977                 : 
    5978               1 :     return ((OGRSpatialReference *) hSRS)->IsLocal();
    5979                 : }
    5980                 : 
    5981                 : /************************************************************************/
    5982                 : /*                            IsVertical()                              */
    5983                 : /************************************************************************/
    5984                 : 
    5985                 : /**
    5986                 :  * \brief Check if vertical coordinate system.
    5987                 :  *
    5988                 :  * This method is the same as the C function OSRIsVertical().
    5989                 :  *
    5990                 :  * @return TRUE if this contains a VERT_CS node indicating a it is a 
    5991                 :  * vertical coordinate system.
    5992                 :  *
    5993                 :  * @since OGR 1.8.0
    5994                 :  */
    5995                 : 
    5996           15559 : int OGRSpatialReference::IsVertical() const
    5997                 : 
    5998                 : {
    5999           15559 :     if( poRoot == NULL )
    6000              51 :         return FALSE;
    6001                 : 
    6002           15508 :     if( EQUAL(poRoot->GetValue(),"VERT_CS") )
    6003               1 :         return TRUE;
    6004           15507 :     else if( EQUAL(poRoot->GetValue(),"COMPD_CS") )
    6005               5 :         return GetAttrNode( "VERT_CS" ) != NULL;
    6006                 :     else 
    6007           15502 :         return FALSE;
    6008                 : }
    6009                 : 
    6010                 : /************************************************************************/
    6011                 : /*                           OSRIsVertical()                            */
    6012                 : /************************************************************************/
    6013                 : /** 
    6014                 :  * \brief Check if vertical coordinate system.
    6015                 :  *
    6016                 :  * This function is the same as OGRSpatialReference::IsVertical().
    6017                 :  *
    6018                 :  * @since OGR 1.8.0
    6019                 :  */
    6020               0 : int OSRIsVertical( OGRSpatialReferenceH hSRS ) 
    6021                 : 
    6022                 : {
    6023               0 :     VALIDATE_POINTER1( hSRS, "OSRIsVertical", 0 );
    6024                 : 
    6025               0 :     return ((OGRSpatialReference *) hSRS)->IsVertical();
    6026                 : }
    6027                 : 
    6028                 : /************************************************************************/
    6029                 : /*                            CloneGeogCS()                             */
    6030                 : /************************************************************************/
    6031                 : 
    6032                 : /**
    6033                 :  * \brief Make a duplicate of the GEOGCS node of this OGRSpatialReference object.
    6034                 :  *
    6035                 :  * @return a new SRS, which becomes the responsibility of the caller. 
    6036                 :  */
    6037            4364 : OGRSpatialReference *OGRSpatialReference::CloneGeogCS() const
    6038                 : 
    6039                 : {
    6040                 :     const OGR_SRSNode *poGeogCS;
    6041                 :     OGRSpatialReference * poNewSRS;
    6042                 : 
    6043                 : /* -------------------------------------------------------------------- */
    6044                 : /*      We have to reconstruct the GEOGCS node for geocentric           */
    6045                 : /*      coordinate systems.                                             */
    6046                 : /* -------------------------------------------------------------------- */
    6047            4364 :     if( IsGeocentric() )
    6048                 :     {
    6049               0 :         const OGR_SRSNode *poDatum = GetAttrNode( "DATUM" );
    6050               0 :         const OGR_SRSNode *poPRIMEM = GetAttrNode( "PRIMEM" );
    6051                 :         OGR_SRSNode *poGeogCS;
    6052                 :         
    6053               0 :         if( poDatum == NULL || poPRIMEM == NULL )
    6054               0 :             return NULL;
    6055                 :         
    6056               0 :         poGeogCS = new OGR_SRSNode( "GEOGCS" );
    6057               0 :         poGeogCS->AddChild( new OGR_SRSNode( "unnamed" ) );
    6058               0 :         poGeogCS->AddChild( poDatum->Clone() );
    6059               0 :         poGeogCS->AddChild( poPRIMEM->Clone() );
    6060                 : 
    6061               0 :         poNewSRS = new OGRSpatialReference();
    6062               0 :         poNewSRS->SetRoot( poGeogCS );
    6063                 : 
    6064               0 :         poNewSRS->SetAngularUnits( "degree", CPLAtof(SRS_UA_DEGREE_CONV) );
    6065                 : 
    6066               0 :         return poNewSRS;
    6067                 :     }
    6068                 : 
    6069                 : /* -------------------------------------------------------------------- */
    6070                 : /*      For all others we just search the tree, and duplicate.          */
    6071                 : /* -------------------------------------------------------------------- */
    6072            4364 :     poGeogCS = GetAttrNode( "GEOGCS" );
    6073            4364 :     if( poGeogCS == NULL )
    6074               1 :         return NULL;
    6075                 : 
    6076            4363 :     poNewSRS = new OGRSpatialReference();
    6077            4363 :     poNewSRS->SetRoot( poGeogCS->Clone() );
    6078                 : 
    6079            4363 :     return poNewSRS;
    6080                 : }
    6081                 : 
    6082                 : /************************************************************************/
    6083                 : /*                           OSRCloneGeogCS()                           */
    6084                 : /************************************************************************/
    6085                 : /**
    6086                 :  * \brief Make a duplicate of the GEOGCS node of this OGRSpatialReference object.
    6087                 :  *
    6088                 :  * This function is the same as OGRSpatialReference::CloneGeogCS().
    6089                 :  */
    6090              28 : OGRSpatialReferenceH CPL_STDCALL OSRCloneGeogCS( OGRSpatialReferenceH hSource )
    6091                 : 
    6092                 : {
    6093              28 :     VALIDATE_POINTER1( hSource, "OSRCloneGeogCS", NULL );
    6094                 : 
    6095                 :     return (OGRSpatialReferenceH) 
    6096              28 :         ((OGRSpatialReference *) hSource)->CloneGeogCS();
    6097                 : }
    6098                 : 
    6099                 : /************************************************************************/
    6100                 : /*                            IsSameGeogCS()                            */
    6101                 : /************************************************************************/
    6102                 : 
    6103                 : /**
    6104                 :  * \brief Do the GeogCS'es match?
    6105                 :  *
    6106                 :  * This method is the same as the C function OSRIsSameGeogCS().
    6107                 :  *
    6108                 :  * @param poOther the SRS being compared against. 
    6109                 :  *
    6110                 :  * @return TRUE if they are the same or FALSE otherwise. 
    6111                 :  */
    6112                 : 
    6113           18989 : int OGRSpatialReference::IsSameGeogCS( const OGRSpatialReference *poOther ) const
    6114                 : 
    6115                 : {
    6116                 :     const char *pszThisValue, *pszOtherValue;
    6117                 : 
    6118                 : /* -------------------------------------------------------------------- */
    6119                 : /*      Does the datum name match?  Note that we assume                 */
    6120                 : /*      compatibility if either is missing a datum.                     */
    6121                 : /* -------------------------------------------------------------------- */
    6122           18989 :     pszThisValue = this->GetAttrValue( "DATUM" );
    6123           18989 :     pszOtherValue = poOther->GetAttrValue( "DATUM" );
    6124                 : 
    6125           18989 :     if( pszThisValue != NULL && pszOtherValue != NULL 
    6126                 :         && !EQUAL(pszThisValue,pszOtherValue) )
    6127             213 :         return FALSE;
    6128                 : 
    6129                 : /* -------------------------------------------------------------------- */
    6130                 : /*      Do the datum TOWGS84 values match if present?                   */
    6131                 : /* -------------------------------------------------------------------- */
    6132                 :     double adfTOWGS84[7], adfOtherTOWGS84[7];
    6133                 :     int i;
    6134                 : 
    6135           18776 :     this->GetTOWGS84( adfTOWGS84, 7 );
    6136           18776 :     poOther->GetTOWGS84( adfOtherTOWGS84, 7 );
    6137                 : 
    6138          150208 :     for( i = 0; i < 7; i++ )
    6139                 :     {
    6140          131432 :         if( fabs(adfTOWGS84[i] - adfOtherTOWGS84[i]) > 0.00001 )
    6141               0 :             return FALSE;
    6142                 :     }
    6143                 : 
    6144                 : /* -------------------------------------------------------------------- */
    6145                 : /*      Do the prime meridians match?  If missing assume a value of zero.*/
    6146                 : /* -------------------------------------------------------------------- */
    6147           18776 :     pszThisValue = this->GetAttrValue( "PRIMEM", 1 );
    6148           18776 :     if( pszThisValue == NULL )
    6149               1 :         pszThisValue = "0.0";
    6150                 : 
    6151           18776 :     pszOtherValue = poOther->GetAttrValue( "PRIMEM", 1 );
    6152           18776 :     if( pszOtherValue == NULL )
    6153               1 :         pszOtherValue = "0.0";
    6154                 : 
    6155           18776 :     if( CPLAtof(pszOtherValue) != CPLAtof(pszThisValue) )
    6156              95 :         return FALSE;
    6157                 :     
    6158                 : /* -------------------------------------------------------------------- */
    6159                 : /*      Do the units match?                                             */
    6160                 : /* -------------------------------------------------------------------- */
    6161           18681 :     pszThisValue = this->GetAttrValue( "GEOGCS|UNIT", 1 );
    6162           18681 :     if( pszThisValue == NULL )
    6163               3 :         pszThisValue = SRS_UA_DEGREE_CONV;
    6164                 : 
    6165           18681 :     pszOtherValue = poOther->GetAttrValue( "GEOGCS|UNIT", 1 );
    6166           18681 :     if( pszOtherValue == NULL )
    6167             115 :         pszOtherValue = SRS_UA_DEGREE_CONV;
    6168                 : 
    6169           18681 :     if( ABS(CPLAtof(pszOtherValue) - CPLAtof(pszThisValue)) > 0.00000001 )
    6170               4 :         return FALSE;
    6171                 : 
    6172                 : /* -------------------------------------------------------------------- */
    6173                 : /*      Does the spheroid match.  Check semi major, and inverse         */
    6174                 : /*      flattening.                                                     */
    6175                 : /* -------------------------------------------------------------------- */
    6176           18677 :     pszThisValue = this->GetAttrValue( "SPHEROID", 1 );
    6177           18677 :     pszOtherValue = poOther->GetAttrValue( "SPHEROID", 1 );
    6178           18677 :     if( pszThisValue != NULL && pszOtherValue != NULL 
    6179                 :         && ABS(CPLAtof(pszThisValue) - CPLAtof(pszOtherValue)) > 0.01 )
    6180              12 :         return FALSE;
    6181                 : 
    6182           18665 :     pszThisValue = this->GetAttrValue( "SPHEROID", 2 );
    6183           18665 :     pszOtherValue = poOther->GetAttrValue( "SPHEROID", 2 );
    6184           18665 :     if( pszThisValue != NULL && pszOtherValue != NULL 
    6185                 :         && ABS(CPLAtof(pszThisValue) - CPLAtof(pszOtherValue)) > 0.0001 )
    6186              20 :         return FALSE;
    6187                 :     
    6188           18645 :     return TRUE;
    6189                 : }
    6190                 : 
    6191                 : /************************************************************************/
    6192                 : /*                          OSRIsSameGeogCS()                           */
    6193                 : /************************************************************************/
    6194                 : 
    6195                 : /** 
    6196                 :  * \brief Do the GeogCS'es match?
    6197                 :  *
    6198                 :  * This function is the same as OGRSpatialReference::IsSameGeogCS().
    6199                 :  */
    6200               0 : int OSRIsSameGeogCS( OGRSpatialReferenceH hSRS1, OGRSpatialReferenceH hSRS2 )
    6201                 : 
    6202                 : {
    6203               0 :     VALIDATE_POINTER1( hSRS1, "OSRIsSameGeogCS", 0 );
    6204               0 :     VALIDATE_POINTER1( hSRS2, "OSRIsSameGeogCS", 0 );
    6205                 : 
    6206                 :     return ((OGRSpatialReference *) hSRS1)->IsSameGeogCS( 
    6207               0 :         (OGRSpatialReference *) hSRS2 );
    6208                 : }
    6209                 : 
    6210                 : /************************************************************************/
    6211                 : /*                            IsSameVertCS()                            */
    6212                 : /************************************************************************/
    6213                 : 
    6214                 : /**
    6215                 :  * \brief Do the VertCS'es match?
    6216                 :  *
    6217                 :  * This method is the same as the C function OSRIsSameVertCS().
    6218                 :  *
    6219                 :  * @param poOther the SRS being compared against. 
    6220                 :  *
    6221                 :  * @return TRUE if they are the same or FALSE otherwise. 
    6222                 :  */
    6223                 : 
    6224               5 : int OGRSpatialReference::IsSameVertCS( const OGRSpatialReference *poOther ) const
    6225                 : 
    6226                 : {
    6227                 :     const char *pszThisValue, *pszOtherValue;
    6228                 : 
    6229                 : /* -------------------------------------------------------------------- */
    6230                 : /*      Does the datum name match?                                      */
    6231                 : /* -------------------------------------------------------------------- */
    6232               5 :     pszThisValue = this->GetAttrValue( "VERT_DATUM" );
    6233               5 :     pszOtherValue = poOther->GetAttrValue( "VERT_DATUM" );
    6234                 : 
    6235               5 :     if( pszThisValue == NULL || pszOtherValue == NULL 
    6236                 :         || !EQUAL(pszThisValue, pszOtherValue) )
    6237               0 :         return FALSE;
    6238                 : 
    6239                 : /* -------------------------------------------------------------------- */
    6240                 : /*      Do the units match?                                             */
    6241                 : /* -------------------------------------------------------------------- */
    6242               5 :     pszThisValue = this->GetAttrValue( "VERT_CS|UNIT", 1 );
    6243               5 :     if( pszThisValue == NULL )
    6244               0 :         pszThisValue = "1.0";
    6245                 : 
    6246               5 :     pszOtherValue = poOther->GetAttrValue( "VERT_CS|UNIT", 1 );
    6247               5 :     if( pszOtherValue == NULL )
    6248               0 :         pszOtherValue = "1.0";
    6249                 : 
    6250               5 :     if( ABS(CPLAtof(pszOtherValue) - CPLAtof(pszThisValue)) > 0.00000001 )
    6251               0 :         return FALSE;
    6252                 : 
    6253               5 :     return TRUE;
    6254                 : }
    6255                 : 
    6256                 : /************************************************************************/
    6257                 : /*                          OSRIsSameVertCS()                           */
    6258                 : /************************************************************************/
    6259                 : 
    6260                 : /** 
    6261                 :  * \brief Do the VertCS'es match?
    6262                 :  *
    6263                 :  * This function is the same as OGRSpatialReference::IsSameVertCS().
    6264                 :  */
    6265               0 : int OSRIsSameVertCS( OGRSpatialReferenceH hSRS1, OGRSpatialReferenceH hSRS2 )
    6266                 : 
    6267                 : {
    6268               0 :     VALIDATE_POINTER1( hSRS1, "OSRIsSameVertCS", 0 );
    6269               0 :     VALIDATE_POINTER1( hSRS2, "OSRIsSameVertCS", 0 );
    6270                 : 
    6271                 :     return ((OGRSpatialReference *) hSRS1)->IsSameVertCS( 
    6272               0 :         (OGRSpatialReference *) hSRS2 );
    6273                 : }
    6274                 : 
    6275                 : /************************************************************************/
    6276                 : /*                               IsSame()                               */
    6277                 : /************************************************************************/
    6278                 : 
    6279                 : /**
    6280                 :  * \brief Do these two spatial references describe the same system ?
    6281                 :  *
    6282                 :  * @param poOtherSRS the SRS being compared to.
    6283                 :  *
    6284                 :  * @return TRUE if equivalent or FALSE otherwise. 
    6285                 :  */
    6286                 : 
    6287           14631 : int OGRSpatialReference::IsSame( const OGRSpatialReference * poOtherSRS ) const
    6288                 : 
    6289                 : {
    6290           14631 :     if( GetRoot() == NULL && poOtherSRS->GetRoot() == NULL )
    6291               4 :         return TRUE;
    6292           14627 :     else if( GetRoot() == NULL || poOtherSRS->GetRoot() == NULL )
    6293               0 :         return FALSE;
    6294                 : 
    6295                 : /* -------------------------------------------------------------------- */
    6296                 : /*      Compare geographic coordinate system.                           */
    6297                 : /* -------------------------------------------------------------------- */
    6298           14627 :     if( !IsSameGeogCS( poOtherSRS ) )
    6299              76 :         return FALSE;
    6300                 : 
    6301                 : /* -------------------------------------------------------------------- */
    6302                 : /*      Do the have the same root types?  Ie. is one PROJCS and one     */
    6303                 : /*      GEOGCS or perhaps LOCALCS?                                      */
    6304                 : /* -------------------------------------------------------------------- */
    6305           14551 :     if( !EQUAL(GetRoot()->GetValue(),poOtherSRS->GetRoot()->GetValue()) )
    6306               6 :         return FALSE;
    6307                 : 
    6308                 : /* -------------------------------------------------------------------- */
    6309                 : /*      Compare projected coordinate system.                            */
    6310                 : /* -------------------------------------------------------------------- */
    6311           14545 :     if( IsProjected() )
    6312                 :     {
    6313                 :         const char *pszValue1, *pszValue2;
    6314           11964 :         const OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
    6315                 : 
    6316           11964 :         pszValue1 = this->GetAttrValue( "PROJECTION" );
    6317           11964 :         pszValue2 = poOtherSRS->GetAttrValue( "PROJECTION" );
    6318           11964 :         if( pszValue1 == NULL || pszValue2 == NULL
    6319                 :             || !EQUAL(pszValue1,pszValue2) )
    6320               0 :             return FALSE;
    6321                 : 
    6322          122269 :         for( int iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
    6323                 :         {
    6324                 :             const OGR_SRSNode    *poNode;
    6325                 : 
    6326          110309 :             poNode = poPROJCS->GetChild( iChild );
    6327          110309 :             if( !EQUAL(poNode->GetValue(),"PARAMETER") 
    6328                 :                 || poNode->GetChildCount() != 2 )
    6329           47983 :                 continue;
    6330                 : 
    6331                 :             /* this this eventually test within some epsilon? */
    6332           62326 :             if( this->GetProjParm( poNode->GetChild(0)->GetValue() )
    6333                 :                 != poOtherSRS->GetProjParm( poNode->GetChild(0)->GetValue() ) )
    6334               4 :                 return FALSE;
    6335                 :         }
    6336                 :     }
    6337                 : 
    6338                 : /* -------------------------------------------------------------------- */
    6339                 : /*      If they are LOCALCS/PROJCS, do they have the same units?        */
    6340                 : /* -------------------------------------------------------------------- */
    6341           14541 :     if( IsLocal() || IsProjected() )
    6342                 :     {
    6343           11961 :         if( GetLinearUnits() != 0.0 )
    6344                 :         {
    6345                 :             double      dfRatio;
    6346                 : 
    6347           11961 :             dfRatio = poOtherSRS->GetLinearUnits() / GetLinearUnits();
    6348           11961 :             if( dfRatio < 0.9999999999 || dfRatio > 1.000000001 )
    6349               0 :                 return FALSE;
    6350                 :         }
    6351                 :     }
    6352                 : 
    6353                 : /* -------------------------------------------------------------------- */
    6354                 : /*      Compare vertical coordinate system.                             */
    6355                 : /* -------------------------------------------------------------------- */
    6356           14541 :     if( IsVertical() && !IsSameVertCS( poOtherSRS ) )
    6357               0 :         return FALSE;
    6358                 : 
    6359           14541 :     return TRUE;
    6360                 : }
    6361                 : 
    6362                 : /************************************************************************/
    6363                 : /*                             OSRIsSame()                              */
    6364                 : /************************************************************************/
    6365                 : 
    6366                 : /** 
    6367                 :  * \brief Do these two spatial references describe the same system ?
    6368                 :  *
    6369                 :  * This function is the same as OGRSpatialReference::IsSame().
    6370                 :  */
    6371           14480 : int OSRIsSame( OGRSpatialReferenceH hSRS1, OGRSpatialReferenceH hSRS2 )
    6372                 : 
    6373                 : {
    6374           14480 :     VALIDATE_POINTER1( hSRS1, "OSRIsSame", 0 );
    6375           14480 :     VALIDATE_POINTER1( hSRS2, "OSRIsSame", 0 );
    6376                 : 
    6377                 :     return ((OGRSpatialReference *) hSRS1)->IsSame( 
    6378           14480 :         (OGRSpatialReference *) hSRS2 );
    6379                 : }
    6380                 : 
    6381                 : /************************************************************************/
    6382                 : /*                             SetTOWGS84()                             */
    6383                 : /************************************************************************/
    6384                 : 
    6385                 : /**
    6386                 :  * \brief Set the Bursa-Wolf conversion to WGS84. 
    6387                 :  * 
    6388                 :  * This will create the TOWGS84 node as a child of the DATUM.  It will fail
    6389                 :  * if there is no existing DATUM node.  Unlike most OGRSpatialReference
    6390                 :  * methods it will insert itself in the appropriate order, and will replace
    6391                 :  * an existing TOWGS84 node if there is one. 
    6392                 :  *
    6393                 :  * The parameters have the same meaning as EPSG transformation 9606
    6394                 :  * (Position Vector 7-param. transformation). 
    6395                 :  * 
    6396                 :  * This method is the same as the C function OSRSetTOWGS84().
    6397                 :  * 
    6398                 :  * @param dfDX X child in meters.
    6399                 :  * @param dfDY Y child in meters.
    6400                 :  * @param dfDZ Z child in meters.
    6401                 :  * @param dfEX X rotation in arc seconds (optional, defaults to zero).
    6402                 :  * @param dfEY Y rotation in arc seconds (optional, defaults to zero).
    6403                 :  * @param dfEZ Z rotation in arc seconds (optional, defaults to zero).
    6404                 :  * @param dfPPM scaling factor (parts per million).
    6405                 :  * 
    6406                 :  * @return OGRERR_NONE on success. 
    6407                 :  */ 
    6408                 : 
    6409             109 : OGRErr OGRSpatialReference::SetTOWGS84( double dfDX, double dfDY, double dfDZ,
    6410                 :                                         double dfEX, double dfEY, double dfEZ, 
    6411                 :                                         double dfPPM )
    6412                 : 
    6413                 : {
    6414                 :     OGR_SRSNode     *poDatum, *poTOWGS84;
    6415                 :     int             iPosition;
    6416                 :     char            szValue[64];
    6417                 : 
    6418             109 :     poDatum = GetAttrNode( "DATUM" );
    6419             109 :     if( poDatum == NULL )
    6420               0 :         return OGRERR_FAILURE;
    6421                 :     
    6422             109 :     if( poDatum->FindChild( "TOWGS84" ) != -1 )
    6423              31 :         poDatum->DestroyChild( poDatum->FindChild( "TOWGS84" ) );
    6424                 : 
    6425             109 :     iPosition = poDatum->GetChildCount();
    6426             109 :     if( poDatum->FindChild("AUTHORITY") != -1 )
    6427                 :     {
    6428              58 :         iPosition = poDatum->FindChild("AUTHORITY");
    6429                 :     }
    6430                 : 
    6431             109 :     poTOWGS84 = new OGR_SRSNode("TOWGS84");
    6432                 : 
    6433             109 :     OGRPrintDouble( szValue, dfDX );
    6434             218 :     poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
    6435                 : 
    6436             109 :     OGRPrintDouble( szValue, dfDY );
    6437             218 :     poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
    6438                 : 
    6439             109 :     OGRPrintDouble( szValue, dfDZ );
    6440             218 :     poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
    6441                 : 
    6442             109 :     OGRPrintDouble( szValue, dfEX );
    6443             218 :     poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
    6444                 : 
    6445             109 :     OGRPrintDouble( szValue, dfEY );
    6446             218 :     poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
    6447                 : 
    6448             109 :     OGRPrintDouble( szValue, dfEZ );
    6449             218 :     poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
    6450                 : 
    6451             109 :     OGRPrintDouble( szValue, dfPPM );
    6452             218 :     poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
    6453                 : 
    6454             109 :     poDatum->InsertChild( poTOWGS84, iPosition );
    6455                 : 
    6456             109 :     return OGRERR_NONE;
    6457                 : }
    6458                 : 
    6459                 : /************************************************************************/
    6460                 : /*                           OSRSetTOWGS84()                            */
    6461                 : /************************************************************************/
    6462                 : 
    6463                 : /** 
    6464                 :  * \brief Set the Bursa-Wolf conversion to WGS84. 
    6465                 :  *
    6466                 :  * This function is the same as OGRSpatialReference::SetTOWGS84().
    6467                 :  */
    6468              22 : OGRErr OSRSetTOWGS84( OGRSpatialReferenceH hSRS, 
    6469                 :                       double dfDX, double dfDY, double dfDZ, 
    6470                 :                       double dfEX, double dfEY, double dfEZ, 
    6471                 :                       double dfPPM )
    6472                 : 
    6473                 : {
    6474              22 :     VALIDATE_POINTER1( hSRS, "OSRSetTOWGS84", CE_Failure );
    6475                 : 
    6476                 :     return ((OGRSpatialReference *) hSRS)->SetTOWGS84( dfDX, dfDY, dfDZ, 
    6477                 :                                                        dfEX, dfEY, dfEZ, 
    6478              22 :                                                        dfPPM );
    6479                 : }
    6480                 : 
    6481                 : /************************************************************************/
    6482                 : /*                             GetTOWGS84()                             */
    6483                 : /************************************************************************/
    6484                 : 
    6485                 : /**
    6486                 :  * \brief Fetch TOWGS84 parameters, if available. 
    6487                 :  * 
    6488                 :  * @param padfCoeff array into which up to 7 coefficients are placed.
    6489                 :  * @param nCoeffCount size of padfCoeff - defaults to 7.
    6490                 :  * 
    6491                 :  * @return OGRERR_NONE on success, or OGRERR_FAILURE if there is no
    6492                 :  * TOWGS84 node available. 
    6493                 :  */
    6494                 : 
    6495           38533 : OGRErr OGRSpatialReference::GetTOWGS84( double * padfCoeff, 
    6496                 :                                         int nCoeffCount ) const
    6497                 : 
    6498                 : {
    6499           38533 :     const OGR_SRSNode   *poNode = GetAttrNode( "TOWGS84" );
    6500                 : 
    6501           38533 :     memset( padfCoeff, 0, sizeof(double) * nCoeffCount );
    6502                 : 
    6503           38533 :     if( poNode == NULL )
    6504           38134 :         return OGRERR_FAILURE;
    6505                 : 
    6506            3192 :     for( int i = 0; i < nCoeffCount && i < poNode->GetChildCount(); i++ )
    6507                 :     {
    6508            2793 :         padfCoeff[i] = CPLAtof(poNode->GetChild(i)->GetValue());
    6509                 :     }
    6510                 : 
    6511             399 :     return OGRERR_NONE;
    6512                 : }
    6513                 : 
    6514                 : /************************************************************************/
    6515                 : /*                           OSRGetTOWGS84()                            */
    6516                 : /************************************************************************/
    6517                 : 
    6518                 : /** 
    6519                 :  * \brief Fetch TOWGS84 parameters, if available. 
    6520                 :  *
    6521                 :  * This function is the same as OGRSpatialReference::GetTOWGS84().
    6522                 :  */
    6523               3 : OGRErr OSRGetTOWGS84( OGRSpatialReferenceH hSRS, 
    6524                 :                       double * padfCoeff, int nCoeffCount )
    6525                 : 
    6526                 : {
    6527               3 :     VALIDATE_POINTER1( hSRS, "OSRGetTOWGS84", CE_Failure );
    6528                 : 
    6529               3 :     return ((OGRSpatialReference *) hSRS)->GetTOWGS84( padfCoeff, nCoeffCount);
    6530                 : }
    6531                 : 
    6532                 : /************************************************************************/
    6533                 : /*                         IsAngularParameter()                         */
    6534                 : /*                                                                      */
    6535                 : /*      Is the passed projection parameter an angular one?              */
    6536                 : /************************************************************************/
    6537                 : 
    6538             970 : int OGRSpatialReference::IsAngularParameter( const char *pszParameterName )
    6539                 : 
    6540                 : {
    6541             970 :     if( EQUALN(pszParameterName,"long",4)
    6542                 :         || EQUALN(pszParameterName,"lati",4)
    6543                 :         || EQUAL(pszParameterName,SRS_PP_CENTRAL_MERIDIAN)
    6544                 :         || EQUALN(pszParameterName,"standard_parallel",17)
    6545                 :         || EQUAL(pszParameterName,SRS_PP_AZIMUTH)
    6546                 :         || EQUAL(pszParameterName,SRS_PP_RECTIFIED_GRID_ANGLE) )
    6547             397 :         return TRUE;
    6548                 :     else
    6549             573 :         return FALSE;
    6550                 : }
    6551                 : 
    6552                 : /************************************************************************/
    6553                 : /*                        IsLongitudeParameter()                        */
    6554                 : /*                                                                      */
    6555                 : /*      Is the passed projection parameter an angular longitude         */
    6556                 : /*      (relative to a prime meridian)?                                 */
    6557                 : /************************************************************************/
    6558                 : 
    6559               0 : int OGRSpatialReference::IsLongitudeParameter( const char *pszParameterName )
    6560                 : 
    6561                 : {
    6562               0 :     if( EQUALN(pszParameterName,"long",4)
    6563                 :         || EQUAL(pszParameterName,SRS_PP_CENTRAL_MERIDIAN) )
    6564               0 :         return TRUE;
    6565                 :     else
    6566               0 :         return FALSE;
    6567                 : }
    6568                 : 
    6569                 : /************************************************************************/
    6570                 : /*                         IsLinearParameter()                          */
    6571                 : /*                                                                      */
    6572                 : /*      Is the passed projection parameter an linear one measured in    */
    6573                 : /*      meters or some similar linear measure.                          */
    6574                 : /************************************************************************/
    6575                 : 
    6576           10239 : int OGRSpatialReference::IsLinearParameter( const char *pszParameterName )
    6577                 : 
    6578                 : {
    6579           10239 :     if( EQUALN(pszParameterName,"false_",6) 
    6580                 :         || EQUAL(pszParameterName,SRS_PP_SATELLITE_HEIGHT) )
    6581            3486 :         return TRUE;
    6582                 :     else
    6583            6753 :         return FALSE;
    6584                 : }
    6585                 : 
    6586                 : /************************************************************************/
    6587                 : /*                            GetNormInfo()                             */
    6588                 : /************************************************************************/
    6589                 : 
    6590                 : /**
    6591                 :  * \brief Set the internal information for normalizing linear, and angular values.
    6592                 :  */
    6593           84129 : void OGRSpatialReference::GetNormInfo(void) const
    6594                 : 
    6595                 : {
    6596           84129 :     if( bNormInfoSet )
    6597           62685 :         return;
    6598                 : 
    6599                 : /* -------------------------------------------------------------------- */
    6600                 : /*      Initialize values.                                              */
    6601                 : /* -------------------------------------------------------------------- */
    6602           21444 :     OGRSpatialReference *poThis = (OGRSpatialReference *) this;
    6603                 : 
    6604           21444 :     poThis->bNormInfoSet = TRUE;
    6605                 : 
    6606           21444 :     poThis->dfFromGreenwich = GetPrimeMeridian(NULL);
    6607           21444 :     poThis->dfToMeter = GetLinearUnits(NULL);
    6608           21444 :     poThis->dfToDegrees = GetAngularUnits(NULL) / CPLAtof(SRS_UA_DEGREE_CONV);
    6609           21444 :     if( fabs(poThis->dfToDegrees-1.0) < 0.000000001 )
    6610           21371 :         poThis->dfToDegrees = 1.0;
    6611                 : }
    6612                 : 
    6613                 : /************************************************************************/
    6614                 : /*                           FixupOrdering()                            */
    6615                 : /************************************************************************/
    6616                 : 
    6617                 : /**
    6618                 :  * \brief Correct parameter ordering to match CT Specification.
    6619                 :  *
    6620                 :  * Some mechanisms to create WKT using OGRSpatialReference, and some
    6621                 :  * imported WKT fail to maintain the order of parameters required according
    6622                 :  * to the BNF definitions in the OpenGIS SF-SQL and CT Specifications.  This
    6623                 :  * method attempts to massage things back into the required order.
    6624                 :  *
    6625                 :  * This method is the same as the C function OSRFixupOrdering().
    6626                 :  *
    6627                 :  * @return OGRERR_NONE on success or an error code if something goes 
    6628                 :  * wrong.  
    6629                 :  */
    6630                 : 
    6631           33319 : OGRErr OGRSpatialReference::FixupOrdering()
    6632                 : 
    6633                 : {
    6634           33319 :     if( GetRoot() != NULL )
    6635           33319 :         return GetRoot()->FixupOrdering();
    6636                 :     else
    6637               0 :         return OGRERR_NONE;
    6638                 : }
    6639                 : 
    6640                 : /************************************************************************/
    6641                 : /*                          OSRFixupOrdering()                          */
    6642                 : /************************************************************************/
    6643                 : 
    6644                 : /** 
    6645                 :  * \brief Correct parameter ordering to match CT Specification.
    6646                 :  *
    6647                 :  * This function is the same as OGRSpatialReference::FixupOrdering().
    6648                 :  */
    6649               0 : OGRErr OSRFixupOrdering( OGRSpatialReferenceH hSRS )
    6650                 : 
    6651                 : {
    6652               0 :     VALIDATE_POINTER1( hSRS, "OSRFixupOrdering", CE_Failure );
    6653                 : 
    6654               0 :     return ((OGRSpatialReference *) hSRS)->FixupOrdering();
    6655                 : }
    6656                 : 
    6657                 : /************************************************************************/
    6658                 : /*                               Fixup()                                */
    6659                 : /************************************************************************/
    6660                 : 
    6661                 : /**
    6662                 :  * \brief Fixup as needed.
    6663                 :  *
    6664                 :  * Some mechanisms to create WKT using OGRSpatialReference, and some
    6665                 :  * imported WKT, are not valid according to the OGC CT specification.  This
    6666                 :  * method attempts to fill in any missing defaults that are required, and
    6667                 :  * fixup ordering problems (using OSRFixupOrdering()) so that the resulting
    6668                 :  * WKT is valid. 
    6669                 :  *
    6670                 :  * This method should be expected to evolve over time to as problems are
    6671                 :  * discovered.  The following are amoung the fixup actions this method will
    6672                 :  * take:
    6673                 :  *
    6674                 :  * - Fixup the ordering of nodes to match the BNF WKT ordering, using
    6675                 :  * the FixupOrdering() method. 
    6676                 :  *
    6677                 :  * - Add missing linear or angular units nodes.  
    6678                 :  *
    6679                 :  * This method is the same as the C function OSRFixup().
    6680                 :  *
    6681                 :  * @return OGRERR_NONE on success or an error code if something goes 
    6682                 :  * wrong.  
    6683                 :  */
    6684                 : 
    6685           14746 : OGRErr OGRSpatialReference::Fixup()
    6686                 : 
    6687                 : {
    6688                 : /* -------------------------------------------------------------------- */
    6689                 : /*      Ensure linear units defaulted to METER if missing for PROJCS,   */
    6690                 : /*      GEOCCS or LOCAL_CS.                                             */
    6691                 : /* -------------------------------------------------------------------- */
    6692           14746 :     const OGR_SRSNode *poCS = GetAttrNode( "PROJCS" );
    6693                 : 
    6694           14746 :     if( poCS == NULL )
    6695            2701 :         poCS = GetAttrNode( "LOCAL_CS" );
    6696                 : 
    6697           14746 :     if( poCS == NULL )
    6698            2700 :         poCS = GetAttrNode( "GEOCCS" );
    6699                 : 
    6700           14746 :     if( poCS != NULL && poCS->FindChild( "UNIT" ) == -1 )
    6701              15 :         SetLinearUnits( SRS_UL_METER, 1.0 );
    6702                 : 
    6703                 : /* -------------------------------------------------------------------- */
    6704                 : /*      Ensure angular units defaulted to degrees on the GEOGCS.        */
    6705                 : /* -------------------------------------------------------------------- */
    6706           14746 :     poCS = GetAttrNode( "GEOGCS" );
    6707           14746 :     if( poCS != NULL && poCS->FindChild( "UNIT" ) == -1 )
    6708               0 :         SetAngularUnits( SRS_UA_DEGREE, CPLAtof(SRS_UA_DEGREE_CONV) );
    6709                 : 
    6710           14746 :     return FixupOrdering();
    6711                 : }
    6712                 : 
    6713                 : /************************************************************************/
    6714                 : /*                              OSRFixup()                              */
    6715                 : /************************************************************************/
    6716                 : 
    6717                 : /** 
    6718                 :  * \brief Fixup as needed.
    6719                 :  *
    6720                 :  * This function is the same as OGRSpatialReference::Fixup().
    6721                 :  */
    6722               1 : OGRErr OSRFixup( OGRSpatialReferenceH hSRS )
    6723                 : 
    6724                 : {
    6725               1 :     VALIDATE_POINTER1( hSRS, "OSRFixup", CE_Failure );
    6726                 : 
    6727               1 :     return ((OGRSpatialReference *) hSRS)->Fixup();
    6728                 : }
    6729                 : 
    6730                 : /************************************************************************/
    6731                 : /*                            GetExtension()                            */
    6732                 : /************************************************************************/
    6733                 : 
    6734                 : /**
    6735                 :  * \brief Fetch extension value.
    6736                 :  *
    6737                 :  * Fetch the value of the named EXTENSION item for the identified
    6738                 :  * target node.
    6739                 :  *
    6740                 :  * @param pszTargetKey the name or path to the parent node of the EXTENSION.
    6741                 :  * @param pszName the name of the extension being fetched.
    6742                 :  * @param pszDefault the value to return if the extension is not found.
    6743                 :  *
    6744                 :  * @return node value if successful or pszDefault on failure.
    6745                 :  */
    6746                 : 
    6747            2610 : const char *OGRSpatialReference::GetExtension( const char *pszTargetKey, 
    6748                 :                                                const char *pszName, 
    6749                 :                                                const char *pszDefault ) const
    6750                 : 
    6751                 : {
    6752                 : /* -------------------------------------------------------------------- */
    6753                 : /*      Find the target node.                                           */
    6754                 : /* -------------------------------------------------------------------- */
    6755                 :     const OGR_SRSNode  *poNode;
    6756                 : 
    6757            2610 :     if( pszTargetKey == NULL )
    6758               0 :         poNode = poRoot;
    6759                 :     else
    6760            2610 :         poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
    6761                 : 
    6762            2610 :     if( poNode == NULL )
    6763             706 :         return NULL;
    6764                 : 
    6765                 : /* -------------------------------------------------------------------- */
    6766                 : /*      Fetch matching EXTENSION if there is one.                       */
    6767                 : /* -------------------------------------------------------------------- */
    6768           11798 :     for( int i = poNode->GetChildCount()-1; i >= 0; i-- )
    6769                 :     {
    6770            9984 :         const OGR_SRSNode *poChild = poNode->GetChild(i);
    6771                 : 
    6772            9984 :         if( EQUAL(poChild->GetValue(),"EXTENSION") 
    6773                 :             && poChild->GetChildCount() >= 2 )
    6774                 :         {
    6775             162 :             if( EQUAL(poChild->GetChild(0)->GetValue(),pszName) )
    6776              90 :                 return poChild->GetChild(1)->GetValue();
    6777                 :         }
    6778                 :     }
    6779                 : 
    6780            1814 :     return pszDefault;
    6781                 : }
    6782                 : 
    6783                 : /************************************************************************/
    6784                 : /*                            SetExtension()                            */
    6785                 : /************************************************************************/
    6786                 : /**
    6787                 :  * \brief Set extension value.
    6788                 :  *
    6789                 :  * Set the value of the named EXTENSION item for the identified
    6790                 :  * target node.
    6791                 :  *
    6792                 :  * @param pszTargetKey the name or path to the parent node of the EXTENSION.
    6793                 :  * @param pszName the name of the extension being fetched.
    6794                 :  * @param pszValue the value to set
    6795                 :  *
    6796                 :  * @return OGRERR_NONE on success
    6797                 :  */
    6798                 : 
    6799              20 : OGRErr OGRSpatialReference::SetExtension( const char *pszTargetKey, 
    6800                 :                                           const char *pszName, 
    6801                 :                                           const char *pszValue )
    6802                 : 
    6803                 : {
    6804                 : /* -------------------------------------------------------------------- */
    6805                 : /*      Find the target node.                                           */
    6806                 : /* -------------------------------------------------------------------- */
    6807                 :     OGR_SRSNode  *poNode;
    6808                 : 
    6809              20 :     if( pszTargetKey == NULL )
    6810               0 :         poNode = poRoot;
    6811                 :     else
    6812              20 :         poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
    6813                 : 
    6814              20 :     if( poNode == NULL )
    6815               0 :         return OGRERR_FAILURE;
    6816                 : 
    6817                 : /* -------------------------------------------------------------------- */
    6818                 : /*      Fetch matching EXTENSION if there is one.                       */
    6819                 : /* -------------------------------------------------------------------- */
    6820             147 :     for( int i = poNode->GetChildCount()-1; i >= 0; i-- )
    6821                 :     {
    6822             127 :         OGR_SRSNode *poChild = poNode->GetChild(i);
    6823                 :         
    6824             127 :         if( EQUAL(poChild->GetValue(),"EXTENSION") 
    6825                 :             && poChild->GetChildCount() >= 2 )
    6826                 :         {
    6827               0 :             if( EQUAL(poChild->GetChild(0)->GetValue(),pszName) )
    6828                 :             {
    6829               0 :                 poChild->GetChild(1)->SetValue( pszValue );
    6830               0 :                 return OGRERR_NONE;
    6831                 :             }
    6832                 :         }
    6833                 :     }
    6834                 : 
    6835                 : /* -------------------------------------------------------------------- */
    6836                 : /*      Create a new EXTENSION node.                                    */
    6837                 : /* -------------------------------------------------------------------- */
    6838                 :     OGR_SRSNode *poAuthNode;
    6839                 : 
    6840              20 :     poAuthNode = new OGR_SRSNode( "EXTENSION" );
    6841              40 :     poAuthNode->AddChild( new OGR_SRSNode( pszName ) );
    6842              40 :     poAuthNode->AddChild( new OGR_SRSNode( pszValue ) );
    6843                 :     
    6844              20 :     poNode->AddChild( poAuthNode );
    6845                 : 
    6846              20 :     return OGRERR_NONE;
    6847                 : }
    6848                 : 
    6849                 : /************************************************************************/
    6850                 : /*                             OSRCleanup()                             */
    6851                 : /************************************************************************/
    6852                 : 
    6853                 : CPL_C_START 
    6854                 : void CleanupESRIDatumMappingTable();
    6855                 : CPL_C_END
    6856                 : 
    6857                 : /**
    6858                 :  * \brief Cleanup cached SRS related memory.
    6859                 :  *
    6860                 :  * This function will attempt to cleanup any cache spatial reference
    6861                 :  * related information, such as cached tables of coordinate systems. 
    6862                 :  */
    6863             965 : void OSRCleanup( void )
    6864                 : 
    6865                 : {
    6866             965 :     CleanupESRIDatumMappingTable();
    6867             965 :     CSVDeaccess( NULL );
    6868             965 : }
    6869                 : 
    6870                 : /************************************************************************/
    6871                 : /*                              GetAxis()                               */
    6872                 : /************************************************************************/
    6873                 : 
    6874                 : /**
    6875                 :  * \brief Fetch the orientation of one axis.
    6876                 :  *
    6877                 :  * Fetches the the request axis (iAxis - zero based) from the
    6878                 :  * indicated portion of the coordinate system (pszTargetKey) which
    6879                 :  * should be either "GEOGCS" or "PROJCS". 
    6880                 :  *
    6881                 :  * No CPLError is issued on routine failures (such as not finding the AXIS).
    6882                 :  *
    6883                 :  * This method is equivalent to the C function OSRGetAxis().
    6884                 :  *
    6885                 :  * @param pszTargetKey the coordinate system part to query ("PROJCS" or "GEOGCS").
    6886                 :  * @param iAxis the axis to query (0 for first, 1 for second). 
    6887                 :  * @param peOrientation location into which to place the fetch orientation, may be NULL.
    6888                 :  *
    6889                 :  * @return the name of the axis or NULL on failure.
    6890                 :  */
    6891                 : 
    6892                 : const char *
    6893               1 : OGRSpatialReference::GetAxis( const char *pszTargetKey, int iAxis, 
    6894                 :                               OGRAxisOrientation *peOrientation ) const
    6895                 : 
    6896                 : {
    6897               1 :     if( peOrientation != NULL )
    6898               0 :         *peOrientation = OAO_Other;
    6899                 : 
    6900                 : /* -------------------------------------------------------------------- */
    6901                 : /*      Find the target node.                                           */
    6902                 : /* -------------------------------------------------------------------- */
    6903                 :     OGR_SRSNode  *poNode;
    6904                 : 
    6905               1 :     if( pszTargetKey == NULL )
    6906               1 :         poNode = poRoot;
    6907                 :     else
    6908               0 :         poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
    6909                 : 
    6910               1 :     if( poNode == NULL )
    6911               0 :         return NULL;
    6912                 : 
    6913                 : /* -------------------------------------------------------------------- */
    6914                 : /*      Find desired child AXIS.                                        */
    6915                 : /* -------------------------------------------------------------------- */
    6916               1 :     OGR_SRSNode *poAxis = NULL;
    6917               1 :     int iChild, nChildCount = poNode->GetChildCount();
    6918                 : 
    6919              10 :     for( iChild = 0; iChild < nChildCount; iChild++ )
    6920                 :     {
    6921              10 :         OGR_SRSNode *poChild = poNode->GetChild( iChild );
    6922                 : 
    6923              10 :         if( !EQUAL(poChild->GetValue(),"AXIS") )
    6924               9 :             continue;
    6925                 : 
    6926               1 :         if( iAxis == 0 )
    6927                 :         {
    6928               1 :             poAxis = poChild;
    6929               1 :             break;
    6930                 :         }
    6931               0 :         iAxis--;
    6932                 :     }
    6933                 : 
    6934               1 :     if( poAxis == NULL )
    6935               0 :         return NULL;
    6936                 : 
    6937               1 :     if( poAxis->GetChildCount() < 2 )
    6938               0 :         return NULL;
    6939                 : 
    6940                 : /* -------------------------------------------------------------------- */
    6941                 : /*      Extract name and orientation if possible.                       */
    6942                 : /* -------------------------------------------------------------------- */
    6943               1 :     if( peOrientation != NULL )
    6944                 :     {
    6945               0 :         const char *pszOrientation = poAxis->GetChild(1)->GetValue();
    6946                 : 
    6947               0 :         if( EQUAL(pszOrientation,"NORTH") )
    6948               0 :             *peOrientation = OAO_North;
    6949               0 :         else if( EQUAL(pszOrientation,"EAST") )
    6950               0 :             *peOrientation = OAO_East;
    6951               0 :         else if( EQUAL(pszOrientation,"SOUTH") )
    6952               0 :             *peOrientation = OAO_South;
    6953               0 :         else if( EQUAL(pszOrientation,"WEST") )
    6954               0 :             *peOrientation = OAO_West;
    6955               0 :         else if( EQUAL(pszOrientation,"UP") )
    6956               0 :             *peOrientation = OAO_Up;
    6957               0 :         else if( EQUAL(pszOrientation,"DOWN") )
    6958               0 :             *peOrientation = OAO_Down;
    6959               0 :         else if( EQUAL(pszOrientation,"OTHER") )
    6960               0 :             *peOrientation = OAO_Other;
    6961                 :         else
    6962                 :         {
    6963                 :             CPLDebug( "OSR", "Unrecognised orientation value '%s'.",
    6964               0 :                       pszOrientation );
    6965                 :         }
    6966                 :     }
    6967                 : 
    6968               1 :     return poAxis->GetChild(0)->GetValue();
    6969                 : }
    6970                 : 
    6971                 : /************************************************************************/
    6972                 : /*                             OSRGetAxis()                             */
    6973                 : /************************************************************************/
    6974                 : 
    6975                 : /**
    6976                 :  * \brief Fetch the orientation of one axis.
    6977                 :  *
    6978                 :  * This method is the equivalent of the C++ method OGRSpatialReference::GetAxis
    6979                 :  */
    6980               0 : const char *OSRGetAxis( OGRSpatialReferenceH hSRS,
    6981                 :                         const char *pszTargetKey, int iAxis, 
    6982                 :                         OGRAxisOrientation *peOrientation )
    6983                 : 
    6984                 : {
    6985               0 :     VALIDATE_POINTER1( hSRS, "OSRGetAxis", NULL );
    6986                 : 
    6987                 :     return ((OGRSpatialReference *) hSRS)->GetAxis( pszTargetKey, iAxis,
    6988               0 :                                                     peOrientation );
    6989                 : }
    6990                 : 
    6991                 : /************************************************************************/
    6992                 : /*                         OSRAxisEnumToName()                          */
    6993                 : /************************************************************************/
    6994                 : 
    6995                 : /**
    6996                 :  * \brief Return the string representation for the OGRAxisOrientation enumeration.
    6997                 :  *
    6998                 :  * For example "NORTH" for OAO_North.
    6999                 :  *
    7000                 :  * @return an internal string
    7001                 :  */
    7002          162076 : const char *OSRAxisEnumToName( OGRAxisOrientation eOrientation )
    7003                 : 
    7004                 : {
    7005          162076 :     if( eOrientation == OAO_North )
    7006           43736 :         return "NORTH";
    7007          118340 :     if( eOrientation == OAO_East )
    7008           43734 :         return "EAST";
    7009           74606 :     if( eOrientation == OAO_South )
    7010           14978 :         return "SOUTH";
    7011           59628 :     if( eOrientation == OAO_West )
    7012           14978 :         return "WEST";
    7013           44650 :     if( eOrientation == OAO_Up )
    7014           14882 :         return "UP";
    7015           29768 :     if( eOrientation == OAO_Down )
    7016           14882 :         return "DOWN";
    7017           14886 :     if( eOrientation == OAO_Other )
    7018           14886 :         return "OTHER";
    7019                 : 
    7020               0 :     return "UNKNOWN";
    7021                 : }
    7022                 : 
    7023                 : /************************************************************************/
    7024                 : /*                              SetAxes()                               */
    7025                 : /************************************************************************/
    7026                 : 
    7027                 : /**
    7028                 :  * \brief Set the axes for a coordinate system.
    7029                 :  *
    7030                 :  * Set the names, and orientations of the axes for either a projected 
    7031                 :  * (PROJCS) or geographic (GEOGCS) coordinate system.  
    7032                 :  *
    7033                 :  * This method is equivalent to the C function OSRSetAxes().
    7034                 :  *
    7035                 :  * @param pszTargetKey either "PROJCS" or "GEOGCS", must already exist in SRS.
    7036                 :  * @param pszXAxisName name of first axis, normally "Long" or "Easting". 
    7037                 :  * @param eXAxisOrientation normally OAO_East.
    7038                 :  * @param pszYAxisName name of second axis, normally "Lat" or "Northing". 
    7039                 :  * @param eYAxisOrientation normally OAO_North. 
    7040                 :  * 
    7041                 :  * @return OGRERR_NONE on success or an error code.
    7042                 :  */
    7043                 : 
    7044                 : OGRErr 
    7045           28948 : OGRSpatialReference::SetAxes( const char *pszTargetKey, 
    7046                 :                               const char *pszXAxisName, 
    7047                 :                               OGRAxisOrientation eXAxisOrientation,
    7048                 :                               const char *pszYAxisName, 
    7049                 :                               OGRAxisOrientation eYAxisOrientation )
    7050                 : 
    7051                 : {
    7052                 : /* -------------------------------------------------------------------- */
    7053                 : /*      Find the target node.                                           */
    7054                 : /* -------------------------------------------------------------------- */
    7055                 :     OGR_SRSNode  *poNode;
    7056                 : 
    7057           28948 :     if( pszTargetKey == NULL )
    7058               0 :         poNode = poRoot;
    7059                 :     else
    7060           28948 :         poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
    7061                 : 
    7062           28948 :     if( poNode == NULL )
    7063               0 :         return OGRERR_FAILURE;
    7064                 : 
    7065                 : /* -------------------------------------------------------------------- */
    7066                 : /*      Strip any existing AXIS children.                               */
    7067                 : /* -------------------------------------------------------------------- */
    7068           57896 :     while( poNode->FindChild( "AXIS" ) >= 0 )
    7069               0 :         poNode->DestroyChild( poNode->FindChild( "AXIS" ) );
    7070                 : 
    7071                 : /* -------------------------------------------------------------------- */
    7072                 : /*      Insert desired axes                                             */
    7073                 : /* -------------------------------------------------------------------- */
    7074           28948 :     OGR_SRSNode *poAxis = new OGR_SRSNode( "AXIS" );
    7075                 : 
    7076           57896 :     poAxis->AddChild( new OGR_SRSNode( pszXAxisName ) );
    7077           57896 :     poAxis->AddChild( new OGR_SRSNode( OSRAxisEnumToName(eXAxisOrientation) ));
    7078                 : 
    7079           28948 :     poNode->AddChild( poAxis );
    7080                 :     
    7081           57896 :     poAxis = new OGR_SRSNode( "AXIS" );
    7082                 : 
    7083           57896 :     poAxis->AddChild( new OGR_SRSNode( pszYAxisName ) );
    7084           57896 :     poAxis->AddChild( new OGR_SRSNode( OSRAxisEnumToName(eYAxisOrientation) ));
    7085                 : 
    7086           28948 :     poNode->AddChild( poAxis );
    7087                 : 
    7088           28948 :     return OGRERR_NONE;
    7089                 : }
    7090                 : 
    7091                 : /************************************************************************/
    7092                 : /*                             OSRSetAxes()                             */
    7093                 : /************************************************************************/
    7094                 : /**
    7095                 :  * \brief Set the axes for a coordinate system.
    7096                 :  *
    7097                 :  * This method is the equivalent of the C++ method OGRSpatialReference::SetAxes
    7098                 :  */
    7099               0 : OGRErr OSRSetAxes( OGRSpatialReferenceH hSRS,
    7100                 :                    const char *pszTargetKey, 
    7101                 :                    const char *pszXAxisName, 
    7102                 :                    OGRAxisOrientation eXAxisOrientation,
    7103                 :                    const char *pszYAxisName, 
    7104                 :                    OGRAxisOrientation eYAxisOrientation )
    7105                 : {
    7106               0 :     VALIDATE_POINTER1( hSRS, "OSRSetAxes", OGRERR_FAILURE );
    7107                 : 
    7108                 :     return ((OGRSpatialReference *) hSRS)->SetAxes( pszTargetKey,
    7109                 :                                                     pszXAxisName, 
    7110                 :                                                     eXAxisOrientation,
    7111                 :                                                     pszYAxisName, 
    7112               0 :                                                     eYAxisOrientation );
    7113                 : }
    7114                 : 
    7115                 : #ifdef HAVE_MITAB
    7116                 : char CPL_DLL *MITABSpatialRef2CoordSys( OGRSpatialReference * );
    7117                 : OGRSpatialReference CPL_DLL * MITABCoordSys2SpatialRef( const char * );
    7118                 : #endif
    7119                 : 
    7120                 : /************************************************************************/
    7121                 : /*                       OSRExportToMICoordSys()                        */
    7122                 : /************************************************************************/
    7123                 : /**
    7124                 :  * \brief Export coordinate system in Mapinfo style CoordSys format.
    7125                 :  *
    7126                 :  * This method is the equivalent of the C++ method OGRSpatialReference::exportToMICoordSys
    7127                 :  */
    7128               1 : OGRErr OSRExportToMICoordSys( OGRSpatialReferenceH hSRS, char ** ppszReturn )
    7129                 : 
    7130                 : {
    7131               1 :     VALIDATE_POINTER1( hSRS, "OSRExportToMICoordSys", CE_Failure );
    7132                 : 
    7133               1 :     *ppszReturn = NULL;
    7134                 : 
    7135               1 :     return ((OGRSpatialReference *) hSRS)->exportToMICoordSys( ppszReturn );
    7136                 : }
    7137                 : 
    7138                 : /************************************************************************/
    7139                 : /*                         exportToMICoordSys()                         */
    7140                 : /************************************************************************/
    7141                 : 
    7142                 : /**
    7143                 :  * \brief Export coordinate system in Mapinfo style CoordSys format.
    7144                 :  *
    7145                 :  * Note that the returned WKT string should be freed with OGRFree() or
    7146                 :  * CPLFree() when no longer needed.  It is the responsibility of the caller.
    7147                 :  *
    7148                 :  * This method is the same as the C function OSRExportToMICoordSys().
    7149                 :  *
    7150                 :  * @param ppszResult pointer to which dynamically allocated Mapinfo CoordSys
    7151                 :  * definition will be assigned.
    7152                 :  *
    7153                 :  * @return  OGRERR_NONE on success, OGRERR_FAILURE on failure,
    7154                 :  * OGRERR_UNSUPPORTED_OPERATION if MITAB library was not linked in.
    7155                 :  */
    7156                 :  
    7157               2 : OGRErr OGRSpatialReference::exportToMICoordSys( char **ppszResult ) const
    7158                 : 
    7159                 : {
    7160                 : #ifdef HAVE_MITAB
    7161               2 :     *ppszResult = MITABSpatialRef2CoordSys( (OGRSpatialReference *) this );
    7162               2 :     if( *ppszResult != NULL && strlen(*ppszResult) > 0 )
    7163               2 :         return OGRERR_NONE;
    7164                 :     else
    7165               0 :         return OGRERR_FAILURE;
    7166                 : #else
    7167                 :     CPLError( CE_Failure, CPLE_NotSupported,
    7168                 :               "MITAB not available, CoordSys support disabled." );
    7169                 : 
    7170                 :     return OGRERR_UNSUPPORTED_OPERATION;
    7171                 : #endif    
    7172                 : }
    7173                 : 
    7174                 : /************************************************************************/
    7175                 : /*                       OSRImportFromMICoordSys()                      */
    7176                 : /************************************************************************/
    7177                 : /**
    7178                 :  * \brief Import Mapinfo style CoordSys definition.
    7179                 :  *
    7180                 :  * This method is the equivalent of the C++ method OGRSpatialReference::importFromMICoordSys
    7181                 :  */
    7182                 : 
    7183               1 : OGRErr OSRImportFromMICoordSys( OGRSpatialReferenceH hSRS,
    7184                 :                                 const char *pszCoordSys )
    7185                 : 
    7186                 : {
    7187               1 :     VALIDATE_POINTER1( hSRS, "OSRImportFromMICoordSys", CE_Failure );
    7188                 : 
    7189               1 :     return ((OGRSpatialReference *)hSRS)->importFromMICoordSys( pszCoordSys );
    7190                 : }
    7191                 : 
    7192                 : /************************************************************************/
    7193                 : /*                        importFromMICoordSys()                        */
    7194                 : /************************************************************************/
    7195                 : 
    7196                 : /**
    7197                 :  * \brief Import Mapinfo style CoordSys definition.
    7198                 :  *
    7199                 :  * The OGRSpatialReference is initialized from the passed Mapinfo style CoordSys definition string.
    7200                 :  *
    7201                 :  * This method is the equivalent of the C function OSRImportFromMICoordSys().
    7202                 :  *
    7203                 :  * @param pszCoordSys Mapinfo style CoordSys definition string.
    7204                 :  *
    7205                 :  * @return OGRERR_NONE on success, OGRERR_FAILURE on failure,
    7206                 :  * OGRERR_UNSUPPORTED_OPERATION if MITAB library was not linked in.
    7207                 :  */
    7208                 : 
    7209               3 : OGRErr OGRSpatialReference::importFromMICoordSys( const char *pszCoordSys )
    7210                 : 
    7211                 : {
    7212                 : #ifdef HAVE_MITAB
    7213               3 :     OGRSpatialReference *poResult = MITABCoordSys2SpatialRef( pszCoordSys );
    7214                 : 
    7215               3 :     if( poResult == NULL )
    7216               0 :         return OGRERR_FAILURE;
    7217                 :     
    7218               3 :     *this = *poResult;
    7219               3 :     delete poResult;
    7220                 : 
    7221               3 :     return OGRERR_NONE;
    7222                 : #else
    7223                 :     CPLError( CE_Failure, CPLE_NotSupported,
    7224                 :               "MITAB not available, CoordSys support disabled." );
    7225                 : 
    7226                 :     return OGRERR_UNSUPPORTED_OPERATION;
    7227                 : #endif    
    7228                 : }

Generated by: LCOV version 1.7