LCOV - code coverage report
Current view: directory - ogr - ogrspatialreference.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 1641 1010 61.5 %
Date: 2010-01-09 Functions: 214 119 55.6 %

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

Generated by: LCOV version 1.7