LTP GCOV extension - code coverage report
Current view: directory - ogr - ogrspatialreference.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 1648
Code covered: 68.3 % Executed lines: 1125

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

Generated by: LTP GCOV extension version 1.5