LCOV - code coverage report
Current view: directory - ogr - ogrspatialreference.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 1939 1478 76.2 %
Date: 2012-04-28 Functions: 241 169 70.1 %

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

Generated by: LCOV version 1.7