mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-06-02 06:12:41 -06:00
7605 lines
262 KiB
C++
7605 lines
262 KiB
C++
/******************************************************************************
|
|
* $Id: ogrspatialreference.cpp 29104 2015-05-02 01:44:39Z rouault $
|
|
*
|
|
* Project: OpenGIS Simple Features Reference Implementation
|
|
* Purpose: The OGRSpatialReference class.
|
|
* Author: Frank Warmerdam, warmerdam@pobox.com
|
|
*
|
|
******************************************************************************
|
|
* Copyright (c) 1999, Les Technologies SoftMap Inc.
|
|
* Copyright (c) 2008-2013, Even Rouault <even dot rouault at mines-paris dot org>
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included
|
|
* in all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
****************************************************************************/
|
|
|
|
#include "ogr_spatialref.h"
|
|
#include "ogr_p.h"
|
|
#include "cpl_csv.h"
|
|
#include "cpl_http.h"
|
|
#include "cpl_atomic_ops.h"
|
|
#include "cpl_multiproc.h"
|
|
|
|
CPL_CVSID("$Id: ogrspatialreference.cpp 29104 2015-05-02 01:44:39Z rouault $");
|
|
|
|
// The current opinion is that WKT longitudes like central meridian
|
|
// should be relative to greenwich, not the prime meridian in use.
|
|
// Define the following if they should be relative to the prime meridian
|
|
// of then geogcs.
|
|
#undef WKT_LONGITUDE_RELATIVE_TO_PM
|
|
|
|
/************************************************************************/
|
|
/* OGRPrintDouble() */
|
|
/************************************************************************/
|
|
|
|
void OGRPrintDouble( char * pszStrBuf, double dfValue )
|
|
|
|
{
|
|
CPLsprintf( pszStrBuf, "%.16g", dfValue );
|
|
|
|
int nLen = strlen(pszStrBuf);
|
|
|
|
// The following hack is intended to truncate some "precision" in cases
|
|
// that appear to be roundoff error.
|
|
if( nLen > 15
|
|
&& (strcmp(pszStrBuf+nLen-6,"999999") == 0
|
|
|| strcmp(pszStrBuf+nLen-6,"000001") == 0) )
|
|
{
|
|
CPLsprintf( pszStrBuf, "%.15g", dfValue );
|
|
}
|
|
|
|
// force to user periods regardless of locale.
|
|
if( strchr( pszStrBuf, ',' ) != NULL )
|
|
{
|
|
char *pszDelim = strchr( pszStrBuf, ',' );
|
|
*pszDelim = '.';
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OGRSpatialReference() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Constructor.
|
|
*
|
|
* This constructor takes an optional string argument which if passed
|
|
* should be a WKT representation of an SRS. Passing this is equivalent
|
|
* to not passing it, and then calling importFromWkt() with the WKT string.
|
|
*
|
|
* Note that newly created objects are given a reference count of one.
|
|
*
|
|
* The C function OSRNewSpatialReference() does the same thing as this
|
|
* constructor.
|
|
*
|
|
* @param pszWKT well known text definition to which the object should
|
|
* be initialized, or NULL (the default).
|
|
*/
|
|
|
|
OGRSpatialReference::OGRSpatialReference( const char * pszWKT )
|
|
|
|
{
|
|
bNormInfoSet = FALSE;
|
|
nRefCount = 1;
|
|
poRoot = NULL;
|
|
|
|
if( pszWKT != NULL )
|
|
importFromWkt( (char **) &pszWKT );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRNewSpatialReference() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Constructor.
|
|
*
|
|
* This function is the same as OGRSpatialReference::OGRSpatialReference()
|
|
*/
|
|
OGRSpatialReferenceH CPL_STDCALL OSRNewSpatialReference( const char *pszWKT )
|
|
|
|
{
|
|
OGRSpatialReference * poSRS;
|
|
|
|
poSRS = new OGRSpatialReference();
|
|
|
|
if( pszWKT != NULL && strlen(pszWKT) > 0 )
|
|
{
|
|
if( poSRS->importFromWkt( (char **) (&pszWKT) ) != OGRERR_NONE )
|
|
{
|
|
delete poSRS;
|
|
poSRS = NULL;
|
|
}
|
|
}
|
|
|
|
return (OGRSpatialReferenceH) poSRS;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OGRSpatialReference() */
|
|
/* */
|
|
/* Simple copy constructor. See also Clone(). */
|
|
/************************************************************************/
|
|
|
|
OGRSpatialReference::OGRSpatialReference(const OGRSpatialReference &oOther)
|
|
|
|
{
|
|
bNormInfoSet = FALSE;
|
|
nRefCount = 1;
|
|
poRoot = NULL;
|
|
|
|
if( oOther.poRoot != NULL )
|
|
poRoot = oOther.poRoot->Clone();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* ~OGRSpatialReference() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief OGRSpatialReference destructor.
|
|
*
|
|
* The C function OSRDestroySpatialReference() does the same thing as this
|
|
* method. Preferred C++ method : OGRSpatialReference::DestroySpatialReference()
|
|
*
|
|
* @deprecated
|
|
*/
|
|
|
|
OGRSpatialReference::~OGRSpatialReference()
|
|
|
|
{
|
|
if( poRoot != NULL )
|
|
delete poRoot;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* DestroySpatialReference() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief OGRSpatialReference destructor.
|
|
*
|
|
* This static method will destroy a OGRSpatialReference. It is
|
|
* equivalent to calling delete on the object, but it ensures that the
|
|
* deallocation is properly executed within the OGR libraries heap on
|
|
* platforms where this can matter (win32).
|
|
*
|
|
* This function is the same as OSRDestroySpatialReference()
|
|
*
|
|
* @param poSRS the object to delete
|
|
*
|
|
* @since GDAL 1.7.0
|
|
*/
|
|
|
|
void OGRSpatialReference::DestroySpatialReference(OGRSpatialReference* poSRS)
|
|
{
|
|
delete poSRS;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRDestroySpatialReference() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief OGRSpatialReference destructor.
|
|
*
|
|
* This function is the same as OGRSpatialReference::~OGRSpatialReference()
|
|
* and OGRSpatialReference::DestroySpatialReference()
|
|
*
|
|
* @param hSRS the object to delete
|
|
*/
|
|
void CPL_STDCALL OSRDestroySpatialReference( OGRSpatialReferenceH hSRS )
|
|
|
|
{
|
|
delete ((OGRSpatialReference *) hSRS);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* Clear() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Wipe current definition.
|
|
*
|
|
* Returns OGRSpatialReference to a state with no definition, as it
|
|
* exists when first created. It does not affect reference counts.
|
|
*/
|
|
|
|
void OGRSpatialReference::Clear()
|
|
|
|
{
|
|
if( poRoot )
|
|
delete poRoot;
|
|
|
|
poRoot = NULL;
|
|
|
|
bNormInfoSet = FALSE;
|
|
dfFromGreenwich = 1.0;
|
|
dfToMeter = 1.0;
|
|
dfToDegrees = 1.0;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* operator=() */
|
|
/************************************************************************/
|
|
|
|
OGRSpatialReference &
|
|
OGRSpatialReference::operator=(const OGRSpatialReference &oSource)
|
|
|
|
{
|
|
Clear();
|
|
|
|
if( oSource.poRoot != NULL )
|
|
poRoot = oSource.poRoot->Clone();
|
|
|
|
return *this;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* Reference() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Increments the reference count by one.
|
|
*
|
|
* The reference count is used keep track of the number of OGRGeometry objects
|
|
* referencing this SRS.
|
|
*
|
|
* The method does the same thing as the C function OSRReference().
|
|
*
|
|
* @return the updated reference count.
|
|
*/
|
|
|
|
int OGRSpatialReference::Reference()
|
|
|
|
{
|
|
return CPLAtomicInc(&nRefCount);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRReference() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Increments the reference count by one.
|
|
*
|
|
* This function is the same as OGRSpatialReference::Reference()
|
|
*/
|
|
int OSRReference( OGRSpatialReferenceH hSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRReference", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->Reference();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* Dereference() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Decrements the reference count by one.
|
|
*
|
|
* The method does the same thing as the C function OSRDereference().
|
|
*
|
|
* @return the updated reference count.
|
|
*/
|
|
|
|
int OGRSpatialReference::Dereference()
|
|
|
|
{
|
|
if( nRefCount <= 0 )
|
|
CPLDebug( "OSR",
|
|
"Dereference() called on an object with refcount %d,"
|
|
"likely already destroyed!",
|
|
nRefCount );
|
|
return CPLAtomicDec(&nRefCount);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRDereference() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Decrements the reference count by one.
|
|
*
|
|
* This function is the same as OGRSpatialReference::Dereference()
|
|
*/
|
|
int OSRDereference( OGRSpatialReferenceH hSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRDereference", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->Dereference();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetReferenceCount() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \fn int OGRSpatialReference::GetReferenceCount() const;
|
|
*
|
|
* \brief Fetch current reference count.
|
|
*
|
|
* @return the current reference count.
|
|
*/
|
|
|
|
/************************************************************************/
|
|
/* Release() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Decrements the reference count by one, and destroy if zero.
|
|
*
|
|
* The method does the same thing as the C function OSRRelease().
|
|
*/
|
|
|
|
void OGRSpatialReference::Release()
|
|
|
|
{
|
|
CPLAssert( NULL != this );
|
|
|
|
if( Dereference() <= 0 )
|
|
delete this;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRRelease() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Decrements the reference count by one, and destroy if zero.
|
|
*
|
|
* This function is the same as OGRSpatialReference::Release()
|
|
*/
|
|
void OSRRelease( OGRSpatialReferenceH hSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER0( hSRS, "OSRRelease" );
|
|
|
|
((OGRSpatialReference *) hSRS)->Release();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetRoot() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the root SRS node.
|
|
*
|
|
* If the object has an existing tree of OGR_SRSNodes, they are destroyed
|
|
* as part of assigning the new root. Ownership of the passed OGR_SRSNode is
|
|
* is assumed by the OGRSpatialReference.
|
|
*
|
|
* @param poNewRoot object to assign as root.
|
|
*/
|
|
|
|
void OGRSpatialReference::SetRoot( OGR_SRSNode * poNewRoot )
|
|
|
|
{
|
|
if( poRoot != NULL )
|
|
delete poRoot;
|
|
|
|
poRoot = poNewRoot;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetAttrNode() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Find named node in tree.
|
|
*
|
|
* This method does a pre-order traversal of the node tree searching for
|
|
* a node with this exact value (case insensitive), and returns it. Leaf
|
|
* nodes are not considered, under the assumption that they are just
|
|
* attribute value nodes.
|
|
*
|
|
* If a node appears more than once in the tree (such as UNIT for instance),
|
|
* the first encountered will be returned. Use GetNode() on a subtree to be
|
|
* more specific.
|
|
*
|
|
* @param pszNodePath the name of the node to search for. May contain multiple
|
|
* components such as "GEOGCS|UNIT".
|
|
*
|
|
* @return a pointer to the node found, or NULL if none.
|
|
*/
|
|
|
|
OGR_SRSNode *OGRSpatialReference::GetAttrNode( const char * pszNodePath )
|
|
|
|
{
|
|
char **papszPathTokens;
|
|
OGR_SRSNode *poNode;
|
|
|
|
papszPathTokens = CSLTokenizeStringComplex(pszNodePath, "|", TRUE, FALSE);
|
|
|
|
if( CSLCount( papszPathTokens ) < 1 )
|
|
{
|
|
CSLDestroy(papszPathTokens);
|
|
return NULL;
|
|
}
|
|
|
|
poNode = GetRoot();
|
|
for( int i = 0; poNode != NULL && papszPathTokens[i] != NULL; i++ )
|
|
{
|
|
poNode = poNode->GetNode( papszPathTokens[i] );
|
|
}
|
|
|
|
CSLDestroy( papszPathTokens );
|
|
|
|
return poNode;
|
|
}
|
|
|
|
const OGR_SRSNode *
|
|
OGRSpatialReference::GetAttrNode( const char * pszNodePath ) const
|
|
|
|
{
|
|
OGR_SRSNode *poNode;
|
|
|
|
poNode = ((OGRSpatialReference *) this)->GetAttrNode(pszNodePath);
|
|
|
|
return poNode;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetAttrValue() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch indicated attribute of named node.
|
|
*
|
|
* This method uses GetAttrNode() to find the named node, and then extracts
|
|
* the value of the indicated child. Thus a call to GetAttrValue("UNIT",1)
|
|
* would return the second child of the UNIT node, which is normally the
|
|
* length of the linear unit in meters.
|
|
*
|
|
* This method does the same thing as the C function OSRGetAttrValue().
|
|
*
|
|
* @param pszNodeName the tree node to look for (case insensitive).
|
|
* @param iAttr the child of the node to fetch (zero based).
|
|
*
|
|
* @return the requested value, or NULL if it fails for any reason.
|
|
*/
|
|
|
|
const char *OGRSpatialReference::GetAttrValue( const char * pszNodeName,
|
|
int iAttr ) const
|
|
|
|
{
|
|
const OGR_SRSNode *poNode;
|
|
|
|
poNode = GetAttrNode( pszNodeName );
|
|
if( poNode == NULL )
|
|
return NULL;
|
|
|
|
if( iAttr < 0 || iAttr >= poNode->GetChildCount() )
|
|
return NULL;
|
|
|
|
return poNode->GetChild(iAttr)->GetValue();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRGetAttrValue() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch indicated attribute of named node.
|
|
*
|
|
* This function is the same as OGRSpatialReference::GetAttrValue()
|
|
*/
|
|
const char * CPL_STDCALL OSRGetAttrValue( OGRSpatialReferenceH hSRS,
|
|
const char * pszKey, int iChild )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRGetAttrValue", NULL );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->GetAttrValue( pszKey, iChild );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* Clone() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Make a duplicate of this OGRSpatialReference.
|
|
*
|
|
* This method is the same as the C function OSRClone().
|
|
*
|
|
* @return a new SRS, which becomes the responsibility of the caller.
|
|
*/
|
|
|
|
OGRSpatialReference *OGRSpatialReference::Clone() const
|
|
|
|
{
|
|
OGRSpatialReference *poNewRef;
|
|
|
|
poNewRef = new OGRSpatialReference();
|
|
|
|
if( poRoot != NULL )
|
|
poNewRef->poRoot = poRoot->Clone();
|
|
|
|
return poNewRef;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRClone() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Make a duplicate of this OGRSpatialReference.
|
|
*
|
|
* This function is the same as OGRSpatialReference::Clone()
|
|
*/
|
|
OGRSpatialReferenceH CPL_STDCALL OSRClone( OGRSpatialReferenceH hSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRClone", NULL );
|
|
|
|
return (OGRSpatialReferenceH) ((OGRSpatialReference *) hSRS)->Clone();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* dumpReadable() */
|
|
/* */
|
|
/* Dump pretty wkt to stdout, mostly for debugging. */
|
|
/************************************************************************/
|
|
|
|
void OGRSpatialReference::dumpReadable()
|
|
|
|
{
|
|
char *pszPrettyWkt = NULL;
|
|
|
|
exportToPrettyWkt( &pszPrettyWkt, FALSE );
|
|
printf( "%s\n", pszPrettyWkt );
|
|
CPLFree( pszPrettyWkt );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* exportToPrettyWkt() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* Convert this SRS into a a nicely formatted WKT string for display to a person.
|
|
*
|
|
* Note that the returned WKT string should be freed with OGRFree() or
|
|
* CPLFree() when no longer needed. It is the responsibility of the caller.
|
|
*
|
|
* This method is the same as the C function OSRExportToPrettyWkt().
|
|
*
|
|
* @param ppszResult the resulting string is returned in this pointer.
|
|
* @param bSimplify TRUE if the AXIS, AUTHORITY and EXTENSION nodes should be stripped off
|
|
*
|
|
* @return currently OGRERR_NONE is always returned, but the future it
|
|
* is possible error conditions will develop.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::exportToPrettyWkt( char ** ppszResult,
|
|
int bSimplify ) const
|
|
|
|
{
|
|
if( poRoot == NULL )
|
|
{
|
|
*ppszResult = CPLStrdup("");
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
if( bSimplify )
|
|
{
|
|
OGRSpatialReference *poSimpleClone = Clone();
|
|
OGRErr eErr;
|
|
|
|
poSimpleClone->GetRoot()->StripNodes( "AXIS" );
|
|
poSimpleClone->GetRoot()->StripNodes( "AUTHORITY" );
|
|
poSimpleClone->GetRoot()->StripNodes( "EXTENSION" );
|
|
eErr = poSimpleClone->GetRoot()->exportToPrettyWkt( ppszResult, 1 );
|
|
delete poSimpleClone;
|
|
return eErr;
|
|
}
|
|
else
|
|
return poRoot->exportToPrettyWkt( ppszResult, 1 );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRExportToPrettyWkt() */
|
|
/************************************************************************/
|
|
|
|
|
|
/**
|
|
* \brief Convert this SRS into a a nicely formatted WKT string for display to a person.
|
|
*
|
|
* This function is the same as OGRSpatialReference::exportToPrettyWkt().
|
|
*/
|
|
|
|
OGRErr CPL_STDCALL OSRExportToPrettyWkt( OGRSpatialReferenceH hSRS, char ** ppszReturn,
|
|
int bSimplify)
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRExportToPrettyWkt", CE_Failure );
|
|
|
|
*ppszReturn = NULL;
|
|
|
|
return ((OGRSpatialReference *) hSRS)->exportToPrettyWkt( ppszReturn,
|
|
bSimplify );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* exportToWkt() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Convert this SRS into WKT format.
|
|
*
|
|
* Note that the returned WKT string should be freed with OGRFree() or
|
|
* CPLFree() when no longer needed. It is the responsibility of the caller.
|
|
*
|
|
* This method is the same as the C function OSRExportToWkt().
|
|
*
|
|
* @param ppszResult the resulting string is returned in this pointer.
|
|
*
|
|
* @return currently OGRERR_NONE is always returned, but the future it
|
|
* is possible error conditions will develop.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::exportToWkt( char ** ppszResult ) const
|
|
|
|
{
|
|
if( poRoot == NULL )
|
|
{
|
|
*ppszResult = CPLStrdup("");
|
|
return OGRERR_NONE;
|
|
}
|
|
else
|
|
{
|
|
return poRoot->exportToWkt(ppszResult);
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRExportToWkt() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Convert this SRS into WKT format.
|
|
*
|
|
* This function is the same as OGRSpatialReference::exportToWkt().
|
|
*/
|
|
|
|
OGRErr CPL_STDCALL OSRExportToWkt( OGRSpatialReferenceH hSRS,
|
|
char ** ppszReturn )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRExportToWkt", CE_Failure );
|
|
|
|
*ppszReturn = NULL;
|
|
|
|
return ((OGRSpatialReference *) hSRS)->exportToWkt( ppszReturn );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* importFromWkt() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Import from WKT string.
|
|
*
|
|
* This method will wipe the existing SRS definition, and
|
|
* reassign it based on the contents of the passed WKT string. Only as
|
|
* much of the input string as needed to construct this SRS is consumed from
|
|
* the input string, and the input string pointer
|
|
* is then updated to point to the remaining (unused) input.
|
|
*
|
|
* This method is the same as the C function OSRImportFromWkt().
|
|
*
|
|
* @param ppszInput Pointer to pointer to input. The pointer is updated to
|
|
* point to remaining unused input text.
|
|
*
|
|
* @return OGRERR_NONE if import succeeds, or OGRERR_CORRUPT_DATA if it
|
|
* fails for any reason.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::importFromWkt( char ** ppszInput )
|
|
|
|
{
|
|
if ( !ppszInput || !*ppszInput )
|
|
return OGRERR_FAILURE;
|
|
|
|
Clear();
|
|
|
|
poRoot = new OGR_SRSNode();
|
|
|
|
OGRErr eErr = poRoot->importFromWkt( ppszInput );
|
|
if (eErr != OGRERR_NONE)
|
|
return eErr;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* The following seems to try and detect and unconsumed */
|
|
/* VERTCS[] coordinate system definition (ESRI style) and to */
|
|
/* import and attach it to the existing root. Likely we will */
|
|
/* need to extend this somewhat to bring it into an acceptable */
|
|
/* OGRSpatialReference organization at some point. */
|
|
/* -------------------------------------------------------------------- */
|
|
if (strlen(*ppszInput) > 0 && strstr(*ppszInput, "VERTCS"))
|
|
{
|
|
if(((*ppszInput)[0]) == ',')
|
|
(*ppszInput)++;
|
|
OGR_SRSNode *poNewChild = new OGR_SRSNode();
|
|
poRoot->AddChild( poNewChild );
|
|
return poNewChild->importFromWkt( ppszInput );
|
|
}
|
|
|
|
return eErr;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRImportFromWkt() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Import from WKT string.
|
|
*
|
|
* This function is the same as OGRSpatialReference::importFromWkt().
|
|
*/
|
|
|
|
OGRErr OSRImportFromWkt( OGRSpatialReferenceH hSRS, char **ppszInput )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRImportFromWkt", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->importFromWkt( ppszInput );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetNode() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set attribute value in spatial reference.
|
|
*
|
|
* Missing intermediate nodes in the path will be created if not already
|
|
* in existance. If the attribute has no children one will be created and
|
|
* assigned the value otherwise the zeroth child will be assigned the value.
|
|
*
|
|
* This method does the same as the C function OSRSetAttrValue().
|
|
*
|
|
* @param pszNodePath full path to attribute to be set. For instance
|
|
* "PROJCS|GEOGCS|UNIT".
|
|
*
|
|
* @param pszNewNodeValue value to be assigned to node, such as "meter".
|
|
* This may be NULL if you just want to force creation of the intermediate
|
|
* path.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetNode( const char * pszNodePath,
|
|
const char * pszNewNodeValue )
|
|
|
|
{
|
|
char **papszPathTokens;
|
|
int i;
|
|
OGR_SRSNode *poNode;
|
|
|
|
papszPathTokens = CSLTokenizeStringComplex(pszNodePath, "|", TRUE, FALSE);
|
|
|
|
if( CSLCount( papszPathTokens ) < 1 )
|
|
return OGRERR_FAILURE;
|
|
|
|
if( GetRoot() == NULL || !EQUAL(papszPathTokens[0],GetRoot()->GetValue()) )
|
|
{
|
|
SetRoot( new OGR_SRSNode( papszPathTokens[0] ) );
|
|
}
|
|
|
|
poNode = GetRoot();
|
|
for( i = 1; papszPathTokens[i] != NULL; i++ )
|
|
{
|
|
int j;
|
|
|
|
for( j = 0; j < poNode->GetChildCount(); j++ )
|
|
{
|
|
if( EQUAL(poNode->GetChild( j )->GetValue(),papszPathTokens[i]) )
|
|
{
|
|
poNode = poNode->GetChild(j);
|
|
j = -1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( j != -1 )
|
|
{
|
|
OGR_SRSNode *poNewNode = new OGR_SRSNode( papszPathTokens[i] );
|
|
poNode->AddChild( poNewNode );
|
|
poNode = poNewNode;
|
|
}
|
|
}
|
|
|
|
CSLDestroy( papszPathTokens );
|
|
|
|
if( pszNewNodeValue != NULL )
|
|
{
|
|
if( poNode->GetChildCount() > 0 )
|
|
poNode->GetChild(0)->SetValue( pszNewNodeValue );
|
|
else
|
|
poNode->AddChild( new OGR_SRSNode( pszNewNodeValue ) );
|
|
}
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetAttrValue() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set attribute value in spatial reference.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetNode()
|
|
*/
|
|
OGRErr CPL_STDCALL OSRSetAttrValue( OGRSpatialReferenceH hSRS,
|
|
const char * pszPath, const char * pszValue )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetAttrValue", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetNode( pszPath, pszValue );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetNode() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetNode( const char *pszNodePath,
|
|
double dfValue )
|
|
|
|
{
|
|
char szValue[64];
|
|
|
|
if( ABS(dfValue - (int) dfValue) == 0.0 )
|
|
sprintf( szValue, "%d", (int) dfValue );
|
|
else
|
|
OGRPrintDouble( szValue, dfValue );
|
|
|
|
return SetNode( pszNodePath, szValue );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetAngularUnits() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the angular units for the geographic coordinate system.
|
|
*
|
|
* This method creates a UNIT subnode with the specified values as a
|
|
* child of the GEOGCS node.
|
|
*
|
|
* This method does the same as the C function OSRSetAngularUnits().
|
|
*
|
|
* @param pszUnitsName the units name to be used. Some preferred units
|
|
* names can be found in ogr_srs_api.h such as SRS_UA_DEGREE.
|
|
*
|
|
* @param dfInRadians the value to multiple by an angle in the indicated
|
|
* units to transform to radians. Some standard conversion factors can
|
|
* be found in ogr_srs_api.h.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetAngularUnits( const char * pszUnitsName,
|
|
double dfInRadians )
|
|
|
|
{
|
|
OGR_SRSNode *poCS;
|
|
OGR_SRSNode *poUnits;
|
|
char szValue[128];
|
|
|
|
bNormInfoSet = FALSE;
|
|
|
|
poCS = GetAttrNode( "GEOGCS" );
|
|
|
|
if( poCS == NULL )
|
|
return OGRERR_FAILURE;
|
|
|
|
OGRPrintDouble( szValue, dfInRadians );
|
|
|
|
if( poCS->FindChild( "UNIT" ) >= 0 )
|
|
{
|
|
poUnits = poCS->GetChild( poCS->FindChild( "UNIT" ) );
|
|
if (poUnits->GetChildCount() < 2)
|
|
return OGRERR_FAILURE;
|
|
poUnits->GetChild(0)->SetValue( pszUnitsName );
|
|
poUnits->GetChild(1)->SetValue( szValue );
|
|
}
|
|
else
|
|
{
|
|
poUnits = new OGR_SRSNode( "UNIT" );
|
|
poUnits->AddChild( new OGR_SRSNode( pszUnitsName ) );
|
|
poUnits->AddChild( new OGR_SRSNode( szValue ) );
|
|
|
|
poCS->AddChild( poUnits );
|
|
}
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetAngularUnits() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the angular units for the geographic coordinate system.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetAngularUnits()
|
|
*/
|
|
OGRErr OSRSetAngularUnits( OGRSpatialReferenceH hSRS,
|
|
const char * pszUnits, double dfInRadians )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetAngularUnits", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetAngularUnits( pszUnits,
|
|
dfInRadians );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetAngularUnits() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch angular geographic coordinate system units.
|
|
*
|
|
* If no units are available, a value of "degree" and SRS_UA_DEGREE_CONV
|
|
* will be assumed. This method only checks directly under the GEOGCS node
|
|
* for units.
|
|
*
|
|
* This method does the same thing as the C function OSRGetAngularUnits().
|
|
*
|
|
* @param ppszName a pointer to be updated with the pointer to the
|
|
* units name. The returned value remains internal to the OGRSpatialReference
|
|
* and shouldn't be freed, or modified. It may be invalidated on the next
|
|
* OGRSpatialReference call.
|
|
*
|
|
* @return the value to multiply by angular distances to transform them to
|
|
* radians.
|
|
*/
|
|
|
|
double OGRSpatialReference::GetAngularUnits( char ** ppszName ) const
|
|
|
|
{
|
|
const OGR_SRSNode *poCS = GetAttrNode( "GEOGCS" );
|
|
|
|
if( ppszName != NULL )
|
|
*ppszName = (char* ) "degree";
|
|
|
|
if( poCS == NULL )
|
|
return CPLAtof(SRS_UA_DEGREE_CONV);
|
|
|
|
for( int iChild = 0; iChild < poCS->GetChildCount(); iChild++ )
|
|
{
|
|
const OGR_SRSNode *poChild = poCS->GetChild(iChild);
|
|
|
|
if( EQUAL(poChild->GetValue(),"UNIT")
|
|
&& poChild->GetChildCount() >= 2 )
|
|
{
|
|
if( ppszName != NULL )
|
|
*ppszName = (char *) poChild->GetChild(0)->GetValue();
|
|
|
|
return CPLAtof( poChild->GetChild(1)->GetValue() );
|
|
}
|
|
}
|
|
|
|
return 1.0;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRGetAngularUnits() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch angular geographic coordinate system units.
|
|
*
|
|
* This function is the same as OGRSpatialReference::GetAngularUnits()
|
|
*/
|
|
double OSRGetAngularUnits( OGRSpatialReferenceH hSRS, char ** ppszName )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRGetAngularUnits", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->GetAngularUnits( ppszName );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetLinearUnitsAndUpdateParameters() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the linear units for the projection.
|
|
*
|
|
* This method creates a UNIT subnode with the specified values as a
|
|
* child of the PROJCS or LOCAL_CS node. It works the same as the
|
|
* SetLinearUnits() method, but it also updates all existing linear
|
|
* projection parameter values from the old units to the new units.
|
|
*
|
|
* @param pszName the units name to be used. Some preferred units
|
|
* names can be found in ogr_srs_api.h such as SRS_UL_METER, SRS_UL_FOOT
|
|
* and SRS_UL_US_FOOT.
|
|
*
|
|
* @param dfInMeters the value to multiple by a length in the indicated
|
|
* units to transform to meters. Some standard conversion factors can
|
|
* be found in ogr_srs_api.h.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetLinearUnitsAndUpdateParameters(
|
|
const char *pszName, double dfInMeters )
|
|
|
|
{
|
|
double dfOldInMeters = GetLinearUnits();
|
|
OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
|
|
|
|
if( dfInMeters == 0.0 )
|
|
return OGRERR_FAILURE;
|
|
|
|
if( dfInMeters == dfOldInMeters || poPROJCS == NULL )
|
|
return SetLinearUnits( pszName, dfInMeters );
|
|
|
|
for( int iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
|
|
{
|
|
const OGR_SRSNode *poChild = poPROJCS->GetChild(iChild);
|
|
|
|
if( EQUAL(poChild->GetValue(),"PARAMETER")
|
|
&& poChild->GetChildCount() > 1 )
|
|
{
|
|
char *pszParmName = CPLStrdup(poChild->GetChild(0)->GetValue());
|
|
|
|
if( IsLinearParameter( pszParmName ) )
|
|
{
|
|
double dfOldValue = GetProjParm( pszParmName );
|
|
|
|
SetProjParm( pszParmName,
|
|
dfOldValue * dfOldInMeters / dfInMeters );
|
|
}
|
|
|
|
CPLFree( pszParmName );
|
|
}
|
|
}
|
|
|
|
return SetLinearUnits( pszName, dfInMeters );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetLinearUnitsAndUpdateParameters() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the linear units for the projection.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetLinearUnitsAndUpdateParameters()
|
|
*/
|
|
OGRErr OSRSetLinearUnitsAndUpdateParameters( OGRSpatialReferenceH hSRS,
|
|
const char * pszUnits,
|
|
double dfInMeters )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetLinearUnitsAndUpdateParameters",
|
|
CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->
|
|
SetLinearUnitsAndUpdateParameters( pszUnits, dfInMeters );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetLinearUnits() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the linear units for the projection.
|
|
*
|
|
* This method creates a UNIT subnode with the specified values as a
|
|
* child of the PROJCS, GEOCCS or LOCAL_CS node.
|
|
*
|
|
* This method does the same as the C function OSRSetLinearUnits().
|
|
*
|
|
* @param pszUnitsName the units name to be used. Some preferred units
|
|
* names can be found in ogr_srs_api.h such as SRS_UL_METER, SRS_UL_FOOT
|
|
* and SRS_UL_US_FOOT.
|
|
*
|
|
* @param dfInMeters the value to multiple by a length in the indicated
|
|
* units to transform to meters. Some standard conversion factors can
|
|
* be found in ogr_srs_api.h.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetLinearUnits( const char * pszUnitsName,
|
|
double dfInMeters )
|
|
|
|
{
|
|
return SetTargetLinearUnits( NULL, pszUnitsName, dfInMeters );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetLinearUnits() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the linear units for the projection.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetLinearUnits()
|
|
*/
|
|
OGRErr OSRSetLinearUnits( OGRSpatialReferenceH hSRS,
|
|
const char * pszUnits, double dfInMeters )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetLinearUnits", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetLinearUnits( pszUnits,
|
|
dfInMeters );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetTargetLinearUnits() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the linear units for the projection.
|
|
*
|
|
* This method creates a UNIT subnode with the specified values as a
|
|
* child of the target node.
|
|
*
|
|
* This method does the same as the C function OSRSetTargetLinearUnits().
|
|
*
|
|
* @param pszTargetKey the keyword to set the linear units for. ie. "PROJCS" or "VERT_CS"
|
|
*
|
|
* @param pszUnitsName the units name to be used. Some preferred units
|
|
* names can be found in ogr_srs_api.h such as SRS_UL_METER, SRS_UL_FOOT
|
|
* and SRS_UL_US_FOOT.
|
|
*
|
|
* @param dfInMeters the value to multiple by a length in the indicated
|
|
* units to transform to meters. Some standard conversion factors can
|
|
* be found in ogr_srs_api.h.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*
|
|
* @since OGR 1.9.0
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetTargetLinearUnits( const char *pszTargetKey,
|
|
const char * pszUnitsName,
|
|
double dfInMeters )
|
|
|
|
{
|
|
OGR_SRSNode *poCS;
|
|
OGR_SRSNode *poUnits;
|
|
char szValue[128];
|
|
|
|
bNormInfoSet = FALSE;
|
|
|
|
if( pszTargetKey == NULL )
|
|
{
|
|
poCS = GetAttrNode( "PROJCS" );
|
|
|
|
if( poCS == NULL )
|
|
poCS = GetAttrNode( "LOCAL_CS" );
|
|
if( poCS == NULL )
|
|
poCS = GetAttrNode( "GEOCCS" );
|
|
if( poCS == NULL && IsVertical() )
|
|
poCS = GetAttrNode( "VERT_CS" );
|
|
}
|
|
else
|
|
poCS = GetAttrNode( pszTargetKey );
|
|
|
|
if( poCS == NULL )
|
|
return OGRERR_FAILURE;
|
|
|
|
if( dfInMeters == (int) dfInMeters )
|
|
sprintf( szValue, "%d", (int) dfInMeters );
|
|
else
|
|
OGRPrintDouble( szValue, dfInMeters );
|
|
|
|
if( poCS->FindChild( "UNIT" ) >= 0 )
|
|
{
|
|
poUnits = poCS->GetChild( poCS->FindChild( "UNIT" ) );
|
|
if (poUnits->GetChildCount() < 2)
|
|
return OGRERR_FAILURE;
|
|
poUnits->GetChild(0)->SetValue( pszUnitsName );
|
|
poUnits->GetChild(1)->SetValue( szValue );
|
|
if( poUnits->FindChild( "AUTHORITY" ) != -1 )
|
|
poUnits->DestroyChild( poUnits->FindChild( "AUTHORITY" ) );
|
|
}
|
|
else
|
|
{
|
|
poUnits = new OGR_SRSNode( "UNIT" );
|
|
poUnits->AddChild( new OGR_SRSNode( pszUnitsName ) );
|
|
poUnits->AddChild( new OGR_SRSNode( szValue ) );
|
|
|
|
poCS->AddChild( poUnits );
|
|
}
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetLinearUnits() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the linear units for the target node.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetTargetLinearUnits()
|
|
*
|
|
* @since OGR 1.9.0
|
|
*/
|
|
OGRErr OSRSetTargetLinearUnits( OGRSpatialReferenceH hSRS,
|
|
const char *pszTargetKey,
|
|
const char * pszUnits, double dfInMeters )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetTargetLinearUnits", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->
|
|
SetTargetLinearUnits( pszTargetKey, pszUnits, dfInMeters );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetLinearUnits() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch linear projection units.
|
|
*
|
|
* If no units are available, a value of "Meters" and 1.0 will be assumed.
|
|
* This method only checks directly under the PROJCS, GEOCCS or LOCAL_CS node
|
|
* for units.
|
|
*
|
|
* This method does the same thing as the C function OSRGetLinearUnits()/
|
|
*
|
|
* @param ppszName a pointer to be updated with the pointer to the
|
|
* units name. The returned value remains internal to the OGRSpatialReference
|
|
* and shouldn't be freed, or modified. It may be invalidated on the next
|
|
* OGRSpatialReference call.
|
|
*
|
|
* @return the value to multiply by linear distances to transform them to
|
|
* meters.
|
|
*/
|
|
|
|
double OGRSpatialReference::GetLinearUnits( char ** ppszName ) const
|
|
|
|
{
|
|
return GetTargetLinearUnits( NULL, ppszName );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRGetLinearUnits() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch linear projection units.
|
|
*
|
|
* This function is the same as OGRSpatialReference::GetLinearUnits()
|
|
*/
|
|
double OSRGetLinearUnits( OGRSpatialReferenceH hSRS, char ** ppszName )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRGetLinearUnits", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->GetLinearUnits( ppszName );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetTargetLinearUnits() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch linear units for target.
|
|
*
|
|
* If no units are available, a value of "Meters" and 1.0 will be assumed.
|
|
*
|
|
* This method does the same thing as the C function OSRGetTargetLinearUnits()/
|
|
*
|
|
* @param pszTargetKey the key to look on. ie. "PROJCS" or "VERT_CS".
|
|
* @param ppszName a pointer to be updated with the pointer to the
|
|
* units name. The returned value remains internal to the OGRSpatialReference
|
|
* and shouldn't be freed, or modified. It may be invalidated on the next
|
|
* OGRSpatialReference call.
|
|
*
|
|
* @return the value to multiply by linear distances to transform them to
|
|
* meters.
|
|
*
|
|
* @since OGR 1.9.0
|
|
*/
|
|
|
|
double OGRSpatialReference::GetTargetLinearUnits( const char *pszTargetKey,
|
|
char ** ppszName ) const
|
|
|
|
{
|
|
const OGR_SRSNode *poCS;
|
|
|
|
if( pszTargetKey == NULL )
|
|
{
|
|
poCS = GetAttrNode( "PROJCS" );
|
|
|
|
if( poCS == NULL )
|
|
poCS = GetAttrNode( "LOCAL_CS" );
|
|
if( poCS == NULL )
|
|
poCS = GetAttrNode( "GEOCCS" );
|
|
if( poCS == NULL && IsVertical() )
|
|
poCS = GetAttrNode( "VERT_CS" );
|
|
}
|
|
else
|
|
poCS = GetAttrNode( pszTargetKey );
|
|
|
|
if( ppszName != NULL )
|
|
*ppszName = (char*) "unknown";
|
|
|
|
if( poCS == NULL )
|
|
return 1.0;
|
|
|
|
for( int iChild = 0; iChild < poCS->GetChildCount(); iChild++ )
|
|
{
|
|
const OGR_SRSNode *poChild = poCS->GetChild(iChild);
|
|
|
|
if( EQUAL(poChild->GetValue(),"UNIT")
|
|
&& poChild->GetChildCount() >= 2 )
|
|
{
|
|
if( ppszName != NULL )
|
|
*ppszName = (char *) poChild->GetChild(0)->GetValue();
|
|
|
|
return CPLAtof( poChild->GetChild(1)->GetValue() );
|
|
}
|
|
}
|
|
|
|
return 1.0;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRGetTargetLinearUnits() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch linear projection units.
|
|
*
|
|
* This function is the same as OGRSpatialReference::GetTargetLinearUnits()
|
|
*
|
|
* @since OGR 1.9.0
|
|
*/
|
|
double OSRGetTargetLinearUnits( OGRSpatialReferenceH hSRS,
|
|
const char *pszTargetKey,
|
|
char ** ppszName )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRGetTargetLinearUnits", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->GetTargetLinearUnits( pszTargetKey,
|
|
ppszName );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetPrimeMeridian() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch prime meridian info.
|
|
*
|
|
* Returns the offset of the prime meridian from greenwich in degrees,
|
|
* and the prime meridian name (if requested). If no PRIMEM value exists
|
|
* in the coordinate system definition a value of "Greenwich" and an
|
|
* offset of 0.0 is assumed.
|
|
*
|
|
* If the prime meridian name is returned, the pointer is to an internal
|
|
* copy of the name. It should not be freed, altered or depended on after
|
|
* the next OGR call.
|
|
*
|
|
* This method is the same as the C function OSRGetPrimeMeridian().
|
|
*
|
|
* @param ppszName return location for prime meridian name. If NULL, name
|
|
* is not returned.
|
|
*
|
|
* @return the offset to the GEOGCS prime meridian from greenwich in decimal
|
|
* degrees.
|
|
*/
|
|
|
|
double OGRSpatialReference::GetPrimeMeridian( char **ppszName ) const
|
|
|
|
{
|
|
const OGR_SRSNode *poPRIMEM = GetAttrNode( "PRIMEM" );
|
|
|
|
if( poPRIMEM != NULL && poPRIMEM->GetChildCount() >= 2
|
|
&& CPLAtof(poPRIMEM->GetChild(1)->GetValue()) != 0.0 )
|
|
{
|
|
if( ppszName != NULL )
|
|
*ppszName = (char *) poPRIMEM->GetChild(0)->GetValue();
|
|
return CPLAtof(poPRIMEM->GetChild(1)->GetValue());
|
|
}
|
|
|
|
if( ppszName != NULL )
|
|
*ppszName = (char*) SRS_PM_GREENWICH;
|
|
|
|
return 0.0;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRGetPrimeMeridian() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch prime meridian info.
|
|
*
|
|
* This function is the same as OGRSpatialReference::GetPrimeMeridian()
|
|
*/
|
|
double OSRGetPrimeMeridian( OGRSpatialReferenceH hSRS, char **ppszName )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRGetPrimeMeridian", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->GetPrimeMeridian( ppszName );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetGeogCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set geographic coordinate system.
|
|
*
|
|
* This method is used to set the datum, ellipsoid, prime meridian and
|
|
* angular units for a geographic coordinate system. It can be used on it's
|
|
* own to establish a geographic spatial reference, or applied to a
|
|
* projected coordinate system to establish the underlying geographic
|
|
* coordinate system.
|
|
*
|
|
* This method does the same as the C function OSRSetGeogCS().
|
|
*
|
|
* @param pszGeogName user visible name for the geographic coordinate system
|
|
* (not to serve as a key).
|
|
*
|
|
* @param pszDatumName key name for this datum. The OpenGIS specification
|
|
* lists some known values, and otherwise EPSG datum names with a standard
|
|
* transformation are considered legal keys.
|
|
*
|
|
* @param pszSpheroidName user visible spheroid name (not to serve as a key)
|
|
*
|
|
* @param dfSemiMajor the semi major axis of the spheroid.
|
|
*
|
|
* @param dfInvFlattening the inverse flattening for the spheroid.
|
|
* This can be computed from the semi minor axis as
|
|
* 1/f = 1.0 / (1.0 - semiminor/semimajor).
|
|
*
|
|
* @param pszPMName the name of the prime merdidian (not to serve as a key)
|
|
* If this is NULL a default value of "Greenwich" will be used.
|
|
*
|
|
* @param dfPMOffset the longitude of greenwich relative to this prime
|
|
* meridian.
|
|
*
|
|
* @param pszAngularUnits the angular units name (see ogr_srs_api.h for some
|
|
* standard names). If NULL a value of "degrees" will be assumed.
|
|
*
|
|
* @param dfConvertToRadians value to multiply angular units by to transform
|
|
* them to radians. A value of SRS_UL_DEGREE_CONV will be used if
|
|
* pszAngularUnits is NULL.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr
|
|
OGRSpatialReference::SetGeogCS( const char * pszGeogName,
|
|
const char * pszDatumName,
|
|
const char * pszSpheroidName,
|
|
double dfSemiMajor, double dfInvFlattening,
|
|
const char * pszPMName, double dfPMOffset,
|
|
const char * pszAngularUnits,
|
|
double dfConvertToRadians )
|
|
|
|
{
|
|
bNormInfoSet = FALSE;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* For a geocentric coordinate system we want to set the datum */
|
|
/* and ellipsoid based on the GEOGCS. Create the GEOGCS in a */
|
|
/* temporary srs and use the copy method which has special */
|
|
/* handling for GEOCCS. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( IsGeocentric() )
|
|
{
|
|
OGRSpatialReference oGCS;
|
|
|
|
oGCS.SetGeogCS( pszGeogName, pszDatumName, pszSpheroidName,
|
|
dfSemiMajor, dfInvFlattening,
|
|
pszPMName, dfPMOffset,
|
|
pszAngularUnits, dfConvertToRadians );
|
|
return CopyGeogCSFrom( &oGCS );
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Do we already have a GEOGCS? If so, blow it away so it can */
|
|
/* be properly replaced. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( GetAttrNode( "GEOGCS" ) != NULL )
|
|
{
|
|
OGR_SRSNode *poCS;
|
|
|
|
if( EQUAL(GetRoot()->GetValue(),"GEOGCS") )
|
|
Clear();
|
|
else if( (poCS = GetAttrNode( "PROJCS" )) != NULL
|
|
&& poCS->FindChild( "GEOGCS" ) != -1 )
|
|
poCS->DestroyChild( poCS->FindChild( "GEOGCS" ) );
|
|
else
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Set defaults for various parameters. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( pszGeogName == NULL )
|
|
pszGeogName = "unnamed";
|
|
|
|
if( pszPMName == NULL )
|
|
pszPMName = SRS_PM_GREENWICH;
|
|
|
|
if( pszDatumName == NULL )
|
|
pszDatumName = "unknown";
|
|
|
|
if( pszSpheroidName == NULL )
|
|
pszSpheroidName = "unnamed";
|
|
|
|
if( pszAngularUnits == NULL )
|
|
{
|
|
pszAngularUnits = SRS_UA_DEGREE;
|
|
dfConvertToRadians = CPLAtof(SRS_UA_DEGREE_CONV);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Build the GEOGCS object. */
|
|
/* -------------------------------------------------------------------- */
|
|
char szValue[128];
|
|
OGR_SRSNode *poGeogCS, *poSpheroid, *poDatum, *poPM, *poUnits;
|
|
|
|
poGeogCS = new OGR_SRSNode( "GEOGCS" );
|
|
poGeogCS->AddChild( new OGR_SRSNode( pszGeogName ) );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Setup the spheroid. */
|
|
/* -------------------------------------------------------------------- */
|
|
poSpheroid = new OGR_SRSNode( "SPHEROID" );
|
|
poSpheroid->AddChild( new OGR_SRSNode( pszSpheroidName ) );
|
|
|
|
OGRPrintDouble( szValue, dfSemiMajor );
|
|
poSpheroid->AddChild( new OGR_SRSNode(szValue) );
|
|
|
|
OGRPrintDouble( szValue, dfInvFlattening );
|
|
poSpheroid->AddChild( new OGR_SRSNode(szValue) );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Setup the Datum. */
|
|
/* -------------------------------------------------------------------- */
|
|
poDatum = new OGR_SRSNode( "DATUM" );
|
|
poDatum->AddChild( new OGR_SRSNode(pszDatumName) );
|
|
poDatum->AddChild( poSpheroid );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Setup the prime meridian. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( dfPMOffset == 0.0 )
|
|
strcpy( szValue, "0" );
|
|
else
|
|
OGRPrintDouble( szValue, dfPMOffset );
|
|
|
|
poPM = new OGR_SRSNode( "PRIMEM" );
|
|
poPM->AddChild( new OGR_SRSNode( pszPMName ) );
|
|
poPM->AddChild( new OGR_SRSNode( szValue ) );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Setup the rotational units. */
|
|
/* -------------------------------------------------------------------- */
|
|
OGRPrintDouble( szValue, dfConvertToRadians );
|
|
|
|
poUnits = new OGR_SRSNode( "UNIT" );
|
|
poUnits->AddChild( new OGR_SRSNode(pszAngularUnits) );
|
|
poUnits->AddChild( new OGR_SRSNode(szValue) );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Complete the GeogCS */
|
|
/* -------------------------------------------------------------------- */
|
|
poGeogCS->AddChild( poDatum );
|
|
poGeogCS->AddChild( poPM );
|
|
poGeogCS->AddChild( poUnits );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Attach below the PROJCS if there is one, or make this the root. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( GetRoot() != NULL && EQUAL(GetRoot()->GetValue(),"PROJCS") )
|
|
poRoot->InsertChild( poGeogCS, 1 );
|
|
else
|
|
SetRoot( poGeogCS );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetGeogCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set geographic coordinate system.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetGeogCS()
|
|
*/
|
|
OGRErr OSRSetGeogCS( OGRSpatialReferenceH hSRS,
|
|
const char * pszGeogName,
|
|
const char * pszDatumName,
|
|
const char * pszSpheroidName,
|
|
double dfSemiMajor, double dfInvFlattening,
|
|
const char * pszPMName, double dfPMOffset,
|
|
const char * pszAngularUnits,
|
|
double dfConvertToRadians )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetGeogCS", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetGeogCS(
|
|
pszGeogName, pszDatumName,
|
|
pszSpheroidName, dfSemiMajor, dfInvFlattening,
|
|
pszPMName, dfPMOffset, pszAngularUnits, dfConvertToRadians );
|
|
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetWellKnownGeogCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set a GeogCS based on well known name.
|
|
*
|
|
* This may be called on an empty OGRSpatialReference to make a geographic
|
|
* coordinate system, or on something with an existing PROJCS node to
|
|
* set the underlying geographic coordinate system of a projected coordinate
|
|
* system.
|
|
*
|
|
* The following well known text values are currently supported:
|
|
* <ul>
|
|
* <li> "WGS84": same as "EPSG:4326" but has no dependence on EPSG data files.
|
|
* <li> "WGS72": same as "EPSG:4322" but has no dependence on EPSG data files.
|
|
* <li> "NAD27": same as "EPSG:4267" but has no dependence on EPSG data files.
|
|
* <li> "NAD83": same as "EPSG:4269" but has no dependence on EPSG data files.
|
|
* <li> "EPSG:n": same as doing an ImportFromEPSG(n).
|
|
* </ul>
|
|
*
|
|
* @param pszName name of well known geographic coordinate system.
|
|
* @return OGRERR_NONE on success, or OGRERR_FAILURE if the name isn't
|
|
* recognised, the target object is already initialized, or an EPSG value
|
|
* can't be successfully looked up.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetWellKnownGeogCS( const char * pszName )
|
|
|
|
{
|
|
OGRSpatialReference oSRS2;
|
|
OGRErr eErr;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Check for EPSG authority numbers. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( EQUALN(pszName, "EPSG:",5) )
|
|
{
|
|
eErr = oSRS2.importFromEPSG( atoi(pszName+5) );
|
|
if( eErr != OGRERR_NONE )
|
|
return eErr;
|
|
|
|
if( !oSRS2.IsGeographic() )
|
|
return OGRERR_FAILURE;
|
|
|
|
return CopyGeogCSFrom( &oSRS2 );
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Check for EPSGA authority numbers. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( EQUALN(pszName, "EPSGA:",6) )
|
|
{
|
|
eErr = oSRS2.importFromEPSGA( atoi(pszName+6) );
|
|
if( eErr != OGRERR_NONE )
|
|
return eErr;
|
|
|
|
if( !oSRS2.IsGeographic() )
|
|
return OGRERR_FAILURE;
|
|
|
|
return CopyGeogCSFrom( &oSRS2 );
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Check for simple names. */
|
|
/* -------------------------------------------------------------------- */
|
|
char *pszWKT = NULL;
|
|
|
|
if( EQUAL(pszName, "WGS84") || EQUAL(pszName,"CRS84") || EQUAL(pszName,"CRS:84") )
|
|
pszWKT = (char* ) SRS_WKT_WGS84;
|
|
|
|
else if( EQUAL(pszName, "WGS72") )
|
|
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\"]]";
|
|
|
|
else if( EQUAL(pszName, "NAD27") || EQUAL(pszName, "CRS27") || EQUAL(pszName,"CRS:27") )
|
|
pszWKT = (char* ) "GEOGCS[\"NAD27\",DATUM[\"North_American_Datum_1927\",SPHEROID[\"Clarke 1866\",6378206.4,294.978698213898,AUTHORITY[\"EPSG\",\"7008\"]],AUTHORITY[\"EPSG\",\"6267\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9108\"]],AUTHORITY[\"EPSG\",\"4267\"]]";
|
|
|
|
else if( EQUAL(pszName, "NAD83") || EQUAL(pszName,"CRS83") || EQUAL(pszName,"CRS:83") )
|
|
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\"]]";
|
|
|
|
else
|
|
return OGRERR_FAILURE;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Import the WKT */
|
|
/* -------------------------------------------------------------------- */
|
|
eErr = oSRS2.importFromWkt( &pszWKT );
|
|
if( eErr != OGRERR_NONE )
|
|
return eErr;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Copy over. */
|
|
/* -------------------------------------------------------------------- */
|
|
return CopyGeogCSFrom( &oSRS2 );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetWellKnownGeogCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set a GeogCS based on well known name.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetWellKnownGeogCS()
|
|
*/
|
|
OGRErr OSRSetWellKnownGeogCS( OGRSpatialReferenceH hSRS, const char *pszName )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetWellKnownGeogCS", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetWellKnownGeogCS( pszName );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* CopyGeogCSFrom() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Copy GEOGCS from another OGRSpatialReference.
|
|
*
|
|
* The GEOGCS information is copied into this OGRSpatialReference from another.
|
|
* If this object has a PROJCS root already, the GEOGCS is installed within
|
|
* it, otherwise it is installed as the root.
|
|
*
|
|
* @param poSrcSRS the spatial reference to copy the GEOGCS information from.
|
|
*
|
|
* @return OGRERR_NONE on success or an error code.
|
|
*/
|
|
|
|
|
|
OGRErr OGRSpatialReference::CopyGeogCSFrom(
|
|
const OGRSpatialReference * poSrcSRS )
|
|
|
|
{
|
|
const OGR_SRSNode *poGeogCS = NULL;
|
|
|
|
bNormInfoSet = FALSE;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Handle geocentric coordinate systems specially. We just */
|
|
/* want to copy the DATUM and PRIMEM nodes. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( IsGeocentric() )
|
|
{
|
|
if( GetRoot()->FindChild( "DATUM" ) != -1 )
|
|
GetRoot()->DestroyChild( GetRoot()->FindChild( "DATUM" ) );
|
|
if( GetRoot()->FindChild( "PRIMEM" ) != -1 )
|
|
GetRoot()->DestroyChild( GetRoot()->FindChild( "PRIMEM" ) );
|
|
|
|
const OGR_SRSNode *poDatum = poSrcSRS->GetAttrNode( "DATUM" );
|
|
const OGR_SRSNode *poPrimeM = poSrcSRS->GetAttrNode( "PRIMEM" );
|
|
|
|
if( poDatum == NULL || poPrimeM == NULL )
|
|
return OGRERR_FAILURE;
|
|
|
|
poRoot->InsertChild( poDatum->Clone(), 1 );
|
|
poRoot->InsertChild( poPrimeM->Clone(), 2 );
|
|
|
|
return OGRERR_NONE;
|
|
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Do we already have a GEOGCS? If so, blow it away so it can */
|
|
/* be properly replaced. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( GetAttrNode( "GEOGCS" ) != NULL )
|
|
{
|
|
OGR_SRSNode *poPROJCS;
|
|
|
|
if( EQUAL(GetRoot()->GetValue(),"GEOGCS") )
|
|
Clear();
|
|
else if( (poPROJCS = GetAttrNode( "PROJCS" )) != NULL
|
|
&& poPROJCS->FindChild( "GEOGCS" ) != -1 )
|
|
poPROJCS->DestroyChild( poPROJCS->FindChild( "GEOGCS" ) );
|
|
else
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Find the GEOGCS node on the source. */
|
|
/* -------------------------------------------------------------------- */
|
|
poGeogCS = poSrcSRS->GetAttrNode( "GEOGCS" );
|
|
if( poGeogCS == NULL )
|
|
return OGRERR_FAILURE;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Attach below the PROJCS if there is one, or make this the root. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( GetRoot() != NULL && EQUAL(GetRoot()->GetValue(),"PROJCS") )
|
|
poRoot->InsertChild( poGeogCS->Clone(), 1 );
|
|
else
|
|
SetRoot( poGeogCS->Clone() );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRCopyGeogCSFrom() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Copy GEOGCS from another OGRSpatialReference.
|
|
*
|
|
* This function is the same as OGRSpatialReference::CopyGeogCSFrom()
|
|
*/
|
|
OGRErr OSRCopyGeogCSFrom( OGRSpatialReferenceH hSRS,
|
|
OGRSpatialReferenceH hSrcSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRCopyGeogCSFrom", CE_Failure );
|
|
VALIDATE_POINTER1( hSrcSRS, "OSRCopyGeogCSFrom", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->CopyGeogCSFrom(
|
|
(const OGRSpatialReference *) hSrcSRS );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetFromUserInput() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set spatial reference from various text formats.
|
|
*
|
|
* This method will examine the provided input, and try to deduce the
|
|
* format, and then use it to initialize the spatial reference system. It
|
|
* may take the following forms:
|
|
*
|
|
* <ol>
|
|
* <li> Well Known Text definition - passed on to importFromWkt().
|
|
* <li> "EPSG:n" - number passed on to importFromEPSG().
|
|
* <li> "EPSGA:n" - number passed on to importFromEPSGA().
|
|
* <li> "AUTO:proj_id,unit_id,lon0,lat0" - WMS auto projections.
|
|
* <li> "urn:ogc:def:crs:EPSG::n" - ogc urns
|
|
* <li> PROJ.4 definitions - passed on to importFromProj4().
|
|
* <li> filename - file read for WKT, XML or PROJ.4 definition.
|
|
* <li> well known name accepted by SetWellKnownGeogCS(), such as NAD27, NAD83,
|
|
* WGS84 or WGS72.
|
|
* <li> WKT (directly or in a file) in ESRI format should be prefixed with
|
|
* ESRI:: to trigger an automatic morphFromESRI().
|
|
* <li> "IGNF:xxx" - "+init=IGNF:xxx" passed on to importFromProj4().
|
|
* </ol>
|
|
*
|
|
* It is expected that this method will be extended in the future to support
|
|
* XML and perhaps a simplified "minilanguage" for indicating common UTM and
|
|
* State Plane definitions.
|
|
*
|
|
* This method is intended to be flexible, but by it's nature it is
|
|
* imprecise as it must guess information about the format intended. When
|
|
* possible applications should call the specific method appropriate if the
|
|
* input is known to be in a particular format.
|
|
*
|
|
* This method does the same thing as the OSRSetFromUserInput() function.
|
|
*
|
|
* @param pszDefinition text definition to try to deduce SRS from.
|
|
*
|
|
* @return OGRERR_NONE on success, or an error code if the name isn't
|
|
* recognised, the definition is corrupt, or an EPSG value can't be
|
|
* successfully looked up.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetFromUserInput( const char * pszDefinition )
|
|
|
|
{
|
|
int bESRI = FALSE;
|
|
OGRErr err;
|
|
|
|
if( EQUALN(pszDefinition,"ESRI::",6) )
|
|
{
|
|
bESRI = TRUE;
|
|
pszDefinition += 6;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Is it a recognised syntax? */
|
|
/* -------------------------------------------------------------------- */
|
|
if( EQUALN(pszDefinition,"PROJCS",6)
|
|
|| EQUALN(pszDefinition,"GEOGCS",6)
|
|
|| EQUALN(pszDefinition,"COMPD_CS",8)
|
|
|| EQUALN(pszDefinition,"GEOCCS",6)
|
|
|| EQUALN(pszDefinition,"VERT_CS",7)
|
|
|| EQUALN(pszDefinition,"LOCAL_CS",8) )
|
|
{
|
|
err = importFromWkt( (char **) &pszDefinition );
|
|
if( err == OGRERR_NONE && bESRI )
|
|
err = morphFromESRI();
|
|
|
|
return err;
|
|
}
|
|
|
|
if( EQUALN(pszDefinition,"EPSG:",5)
|
|
|| EQUALN(pszDefinition,"EPSGA:",6) )
|
|
{
|
|
OGRErr eStatus;
|
|
|
|
if( EQUALN(pszDefinition,"EPSG:",5) )
|
|
eStatus = importFromEPSG( atoi(pszDefinition+5) );
|
|
|
|
else /* if( EQUALN(pszDefinition,"EPSGA:",6) ) */
|
|
eStatus = importFromEPSGA( atoi(pszDefinition+6) );
|
|
|
|
// Do we want to turn this into a compound definition
|
|
// with a vertical datum?
|
|
if( eStatus == OGRERR_NONE && strchr( pszDefinition, '+' ) != NULL )
|
|
{
|
|
OGRSpatialReference oVertSRS;
|
|
|
|
eStatus = oVertSRS.importFromEPSG(
|
|
atoi(strchr(pszDefinition,'+')+1) );
|
|
if( eStatus == OGRERR_NONE )
|
|
{
|
|
OGR_SRSNode *poHorizSRS = GetRoot()->Clone();
|
|
|
|
Clear();
|
|
|
|
CPLString osName = poHorizSRS->GetChild(0)->GetValue();
|
|
osName += " + ";
|
|
osName += oVertSRS.GetRoot()->GetChild(0)->GetValue();
|
|
|
|
SetNode( "COMPD_CS", osName );
|
|
GetRoot()->AddChild( poHorizSRS );
|
|
GetRoot()->AddChild( oVertSRS.GetRoot()->Clone() );
|
|
}
|
|
|
|
return eStatus;
|
|
}
|
|
else
|
|
return eStatus;
|
|
}
|
|
|
|
if( EQUALN(pszDefinition,"urn:ogc:def:crs:",16)
|
|
|| EQUALN(pszDefinition,"urn:ogc:def:crs,crs:",20)
|
|
|| EQUALN(pszDefinition,"urn:x-ogc:def:crs:",18)
|
|
|| EQUALN(pszDefinition,"urn:opengis:crs:",16)
|
|
|| EQUALN(pszDefinition,"urn:opengis:def:crs:",20))
|
|
return importFromURN( pszDefinition );
|
|
|
|
if( EQUALN(pszDefinition,"http://opengis.net/def/crs",26)
|
|
|| EQUALN(pszDefinition,"http://www.opengis.net/def/crs",30)
|
|
|| EQUALN(pszDefinition,"www.opengis.net/def/crs",23))
|
|
return importFromCRSURL( pszDefinition );
|
|
|
|
if( EQUALN(pszDefinition,"AUTO:",5) )
|
|
return importFromWMSAUTO( pszDefinition );
|
|
|
|
if( EQUALN(pszDefinition,"OGC:",4) ) // WMS/WCS OGC codes like OGC:CRS84
|
|
return SetWellKnownGeogCS( pszDefinition+4 );
|
|
|
|
if( EQUALN(pszDefinition,"CRS:",4) )
|
|
return SetWellKnownGeogCS( pszDefinition );
|
|
|
|
if( EQUALN(pszDefinition,"DICT:",5)
|
|
&& strstr(pszDefinition,",") )
|
|
{
|
|
char *pszFile = CPLStrdup(pszDefinition+5);
|
|
char *pszCode = strstr(pszFile,",") + 1;
|
|
|
|
pszCode[-1] = '\0';
|
|
|
|
err = importFromDict( pszFile, pszCode );
|
|
CPLFree( pszFile );
|
|
|
|
if( err == OGRERR_NONE && bESRI )
|
|
err = morphFromESRI();
|
|
|
|
return err;
|
|
}
|
|
|
|
if( EQUAL(pszDefinition,"NAD27")
|
|
|| EQUAL(pszDefinition,"NAD83")
|
|
|| EQUAL(pszDefinition,"WGS84")
|
|
|| EQUAL(pszDefinition,"WGS72") )
|
|
{
|
|
Clear();
|
|
return SetWellKnownGeogCS( pszDefinition );
|
|
}
|
|
|
|
if( strstr(pszDefinition,"+proj") != NULL
|
|
|| strstr(pszDefinition,"+init") != NULL )
|
|
return importFromProj4( pszDefinition );
|
|
|
|
if( EQUALN(pszDefinition,"IGNF:", 5) )
|
|
{
|
|
char* pszProj4Str = (char*) CPLMalloc(6 + strlen(pszDefinition) + 1);
|
|
strcpy(pszProj4Str, "+init=");
|
|
strcat(pszProj4Str, pszDefinition);
|
|
err = importFromProj4( pszProj4Str );
|
|
CPLFree(pszProj4Str);
|
|
|
|
return err;
|
|
}
|
|
|
|
if( EQUALN(pszDefinition,"http://",7) )
|
|
{
|
|
return importFromUrl (pszDefinition);
|
|
}
|
|
|
|
if( EQUAL(pszDefinition,"osgb:BNG") )
|
|
{
|
|
return importFromEPSG(27700);
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Try to open it as a file. */
|
|
/* -------------------------------------------------------------------- */
|
|
FILE *fp;
|
|
int nBufMax = 100000;
|
|
char *pszBufPtr, *pszBuffer;
|
|
int nBytes;
|
|
|
|
fp = VSIFOpen( pszDefinition, "rt" );
|
|
if( fp == NULL )
|
|
return OGRERR_CORRUPT_DATA;
|
|
|
|
pszBuffer = (char *) CPLMalloc(nBufMax);
|
|
nBytes = VSIFRead( pszBuffer, 1, nBufMax-1, fp );
|
|
VSIFClose( fp );
|
|
|
|
if( nBytes == nBufMax-1 )
|
|
{
|
|
CPLDebug( "OGR",
|
|
"OGRSpatialReference::SetFromUserInput(%s), opened file\n"
|
|
"but it is to large for our generous buffer. Is it really\n"
|
|
"just a WKT definition?", pszDefinition );
|
|
CPLFree( pszBuffer );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
pszBuffer[nBytes] = '\0';
|
|
|
|
pszBufPtr = pszBuffer;
|
|
while( pszBufPtr[0] == ' ' || pszBufPtr[0] == '\n' )
|
|
pszBufPtr++;
|
|
|
|
if( pszBufPtr[0] == '<' )
|
|
err = importFromXML( pszBufPtr );
|
|
else if( (strstr(pszBuffer,"+proj") != NULL
|
|
|| strstr(pszBuffer,"+init") != NULL)
|
|
&& (strstr(pszBuffer,"EXTENSION") == NULL
|
|
&& strstr(pszBuffer,"extension") == NULL) )
|
|
err = importFromProj4( pszBufPtr );
|
|
else
|
|
{
|
|
if( EQUALN(pszBufPtr,"ESRI::",6) )
|
|
{
|
|
bESRI = TRUE;
|
|
pszBufPtr += 6;
|
|
}
|
|
|
|
err = importFromWkt( &pszBufPtr );
|
|
if( err == OGRERR_NONE && bESRI )
|
|
err = morphFromESRI();
|
|
}
|
|
|
|
CPLFree( pszBuffer );
|
|
|
|
return err;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetFromUserInput() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set spatial reference from various text formats.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetFromUserInput()
|
|
*/
|
|
OGRErr CPL_STDCALL OSRSetFromUserInput( OGRSpatialReferenceH hSRS,
|
|
const char *pszDef )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetFromUserInput", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetFromUserInput( pszDef );
|
|
}
|
|
|
|
|
|
/************************************************************************/
|
|
/* ImportFromUrl() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set spatial reference from a URL.
|
|
*
|
|
* This method will download the spatial reference at a given URL and
|
|
* feed it into SetFromUserInput for you.
|
|
*
|
|
* This method does the same thing as the OSRImportFromUrl() function.
|
|
*
|
|
* @param pszUrl text definition to try to deduce SRS from.
|
|
*
|
|
* @return OGRERR_NONE on success, or an error code with the curl
|
|
* error message if it is unable to dowload data.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::importFromUrl( const char * pszUrl )
|
|
|
|
{
|
|
|
|
|
|
if( !EQUALN(pszUrl,"http://",7) )
|
|
{
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"The given string is not recognized as a URL"
|
|
"starting with 'http://' -- %s", pszUrl );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Fetch the result. */
|
|
/* -------------------------------------------------------------------- */
|
|
CPLErrorReset();
|
|
|
|
const char* pszHeaders = "HEADERS=Accept: application/x-ogcwkt";
|
|
const char* pszTimeout = "TIMEOUT=10";
|
|
char *apszOptions[] = {
|
|
(char *) pszHeaders,
|
|
(char *) pszTimeout,
|
|
NULL
|
|
};
|
|
|
|
CPLHTTPResult *psResult = CPLHTTPFetch( pszUrl, apszOptions );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Try to handle errors. */
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
if ( psResult == NULL)
|
|
return OGRERR_FAILURE;
|
|
if( psResult->nDataLen == 0
|
|
|| CPLGetLastErrorNo() != 0 || psResult->pabyData == NULL )
|
|
{
|
|
if (CPLGetLastErrorNo() == 0)
|
|
{
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"No data was returned from the given URL" );
|
|
}
|
|
CPLHTTPDestroyResult( psResult );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
if (psResult->nStatus != 0)
|
|
{
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"Curl reports error: %d: %s", psResult->nStatus, psResult->pszErrBuf );
|
|
CPLHTTPDestroyResult( psResult );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
if( EQUALN( (const char*) psResult->pabyData,"http://",7) )
|
|
{
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"The data that was downloaded also starts with 'http://' "
|
|
"and cannot be passed into SetFromUserInput. Is this "
|
|
"really a spatial reference definition? ");
|
|
CPLHTTPDestroyResult( psResult );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
if( OGRERR_NONE != SetFromUserInput( (const char *) psResult->pabyData )) {
|
|
CPLHTTPDestroyResult( psResult );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
CPLHTTPDestroyResult( psResult );
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRimportFromUrl() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set spatial reference from a URL.
|
|
*
|
|
* This function is the same as OGRSpatialReference::importFromUrl()
|
|
*/
|
|
OGRErr OSRImportFromUrl( OGRSpatialReferenceH hSRS, const char *pszUrl )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRImportFromUrl", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->importFromUrl( pszUrl );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* importFromURNPart() */
|
|
/************************************************************************/
|
|
OGRErr OGRSpatialReference::importFromURNPart(const char* pszAuthority,
|
|
const char* pszCode,
|
|
const char* pszURN)
|
|
{
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Is this an EPSG code? Note that we import it with EPSG */
|
|
/* preferred axis ordering for geographic coordinate systems! */
|
|
/* -------------------------------------------------------------------- */
|
|
if( EQUALN(pszAuthority,"EPSG",4) )
|
|
return importFromEPSGA( atoi(pszCode) );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Is this an IAU code? Lets try for the IAU2000 dictionary. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( EQUALN(pszAuthority,"IAU",3) )
|
|
return importFromDict( "IAU2000.wkt", pszCode );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Is this an OGC code? */
|
|
/* -------------------------------------------------------------------- */
|
|
if( !EQUALN(pszAuthority,"OGC",3) )
|
|
{
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"URN %s has unrecognised authority.",
|
|
pszURN );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
if( EQUALN(pszCode,"CRS84",5) )
|
|
return SetWellKnownGeogCS( pszCode );
|
|
else if( EQUALN(pszCode,"CRS83",5) )
|
|
return SetWellKnownGeogCS( pszCode );
|
|
else if( EQUALN(pszCode,"CRS27",5) )
|
|
return SetWellKnownGeogCS( pszCode );
|
|
else if( EQUALN(pszCode,"84",2) ) /* urn:ogc:def:crs:OGC:2:84 */
|
|
return SetWellKnownGeogCS( "CRS84" );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Handle auto codes. We need to convert from format */
|
|
/* AUTO42001:99:8888 to format AUTO:42001,99,8888. */
|
|
/* -------------------------------------------------------------------- */
|
|
else if( EQUALN(pszCode,"AUTO",4) )
|
|
{
|
|
char szWMSAuto[100];
|
|
int i;
|
|
|
|
if( strlen(pszCode) > sizeof(szWMSAuto)-2 )
|
|
return OGRERR_FAILURE;
|
|
|
|
strcpy( szWMSAuto, "AUTO:" );
|
|
strcpy( szWMSAuto + 5, pszCode + 4 );
|
|
for( i = 5; szWMSAuto[i] != '\0'; i++ )
|
|
{
|
|
if( szWMSAuto[i] == ':' )
|
|
szWMSAuto[i] = ',';
|
|
}
|
|
|
|
return importFromWMSAUTO( szWMSAuto );
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Not a recognise OGC item. */
|
|
/* -------------------------------------------------------------------- */
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"URN %s value not supported.",
|
|
pszURN );
|
|
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* importFromURN() */
|
|
/* */
|
|
/* See OGC recommendation paper 06-023r1 or later for details. */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Initialize from OGC URN.
|
|
*
|
|
* Initializes this spatial reference from a coordinate system defined
|
|
* by an OGC URN prefixed with "urn:ogc:def:crs:" per recommendation
|
|
* paper 06-023r1. Currently EPSG and OGC authority values are supported,
|
|
* including OGC auto codes, but not including CRS1 or CRS88 (NAVD88).
|
|
*
|
|
* This method is also support through SetFromUserInput() which can
|
|
* normally be used for URNs.
|
|
*
|
|
* @param pszURN the urn string.
|
|
*
|
|
* @return OGRERR_NONE on success or an error code.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::importFromURN( const char *pszURN )
|
|
|
|
{
|
|
const char *pszCur;
|
|
|
|
if( EQUALN(pszURN,"urn:ogc:def:crs:",16) )
|
|
pszCur = pszURN + 16;
|
|
else if( EQUALN(pszURN,"urn:ogc:def:crs,crs:",20) )
|
|
pszCur = pszURN + 20;
|
|
else if( EQUALN(pszURN,"urn:x-ogc:def:crs:",18) )
|
|
pszCur = pszURN + 18;
|
|
else if( EQUALN(pszURN,"urn:opengis:crs:",16) )
|
|
pszCur = pszURN + 16;
|
|
else if( EQUALN(pszURN,"urn:opengis:def:crs:",20) )
|
|
pszCur = pszURN + 20;
|
|
else
|
|
{
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"URN %s not a supported format.", pszURN );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Clear any existing definition. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( GetRoot() != NULL )
|
|
{
|
|
delete poRoot;
|
|
poRoot = NULL;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Find code (ignoring version) out of string like: */
|
|
/* */
|
|
/* authority:[version]:code */
|
|
/* -------------------------------------------------------------------- */
|
|
const char *pszAuthority = pszCur;
|
|
|
|
// skip authority
|
|
while( *pszCur != ':' && *pszCur )
|
|
pszCur++;
|
|
if( *pszCur == ':' )
|
|
pszCur++;
|
|
|
|
// skip version
|
|
const char* pszBeforeVersion = pszCur;
|
|
while( *pszCur != ':' && *pszCur )
|
|
pszCur++;
|
|
if( *pszCur == ':' )
|
|
pszCur++;
|
|
else
|
|
/* We come here in the case, the content to parse is authority:code (instead of authority::code) */
|
|
/* which is probably illegal according to http://www.opengeospatial.org/ogcUrnPolicy */
|
|
/* but such content is found for example in what is returned by GeoServer */
|
|
pszCur = pszBeforeVersion;
|
|
|
|
const char *pszCode = pszCur;
|
|
|
|
const char* pszComma = strchr(pszCur, ',');
|
|
if (pszComma == NULL)
|
|
return importFromURNPart(pszAuthority, pszCode, pszURN);
|
|
|
|
|
|
/* There's a second part with the vertical SRS */
|
|
pszCur = pszComma + 1;
|
|
if (strncmp(pszCur, "crs:", 4) != 0)
|
|
{
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"URN %s not a supported format.", pszURN );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
pszCur += 4;
|
|
|
|
char* pszFirstCode = CPLStrdup(pszCode);
|
|
pszFirstCode[pszComma - pszCode] = '\0';
|
|
OGRErr eStatus = importFromURNPart(pszAuthority, pszFirstCode, pszURN);
|
|
CPLFree(pszFirstCode);
|
|
|
|
// Do we want to turn this into a compound definition
|
|
// with a vertical datum?
|
|
if( eStatus == OGRERR_NONE )
|
|
{
|
|
OGRSpatialReference oVertSRS;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Find code (ignoring version) out of string like: */
|
|
/* */
|
|
/* authority:[version]:code */
|
|
/* -------------------------------------------------------------------- */
|
|
pszAuthority = pszCur;
|
|
|
|
// skip authority
|
|
while( *pszCur != ':' && *pszCur )
|
|
pszCur++;
|
|
if( *pszCur == ':' )
|
|
pszCur++;
|
|
|
|
// skip version
|
|
pszBeforeVersion = pszCur;
|
|
while( *pszCur != ':' && *pszCur )
|
|
pszCur++;
|
|
if( *pszCur == ':' )
|
|
pszCur++;
|
|
else
|
|
pszCur = pszBeforeVersion;
|
|
|
|
pszCode = pszCur;
|
|
|
|
eStatus = oVertSRS.importFromURNPart(pszAuthority, pszCode, pszURN);
|
|
if( eStatus == OGRERR_NONE )
|
|
{
|
|
OGR_SRSNode *poHorizSRS = GetRoot()->Clone();
|
|
|
|
Clear();
|
|
|
|
CPLString osName = poHorizSRS->GetChild(0)->GetValue();
|
|
osName += " + ";
|
|
osName += oVertSRS.GetRoot()->GetChild(0)->GetValue();
|
|
|
|
SetNode( "COMPD_CS", osName );
|
|
GetRoot()->AddChild( poHorizSRS );
|
|
GetRoot()->AddChild( oVertSRS.GetRoot()->Clone() );
|
|
}
|
|
|
|
return eStatus;
|
|
}
|
|
else
|
|
return eStatus;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* importFromCRSURL() */
|
|
/* */
|
|
/* See OGC Best Practice document 11-135 for details. */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Initialize from OGC URL.
|
|
*
|
|
* Initializes this spatial reference from a coordinate system defined
|
|
* by an OGC URL prefixed with "http://opengis.net/def/crs" per best practice
|
|
* paper 11-135. Currently EPSG and OGC authority values are supported,
|
|
* including OGC auto codes, but not including CRS1 or CRS88 (NAVD88).
|
|
*
|
|
* This method is also supported through SetFromUserInput() which can
|
|
* normally be used for URLs.
|
|
*
|
|
* @param pszURL the URL string.
|
|
*
|
|
* @return OGRERR_NONE on success or an error code.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::importFromCRSURL( const char *pszURL )
|
|
|
|
{
|
|
const char *pszCur;
|
|
|
|
if( EQUALN(pszURL,"http://opengis.net/def/crs",26) )
|
|
pszCur = pszURL + 26;
|
|
else if( EQUALN(pszURL,"http://www.opengis.net/def/crs",30) )
|
|
pszCur = pszURL + 30;
|
|
else if( EQUALN(pszURL,"www.opengis.net/def/crs",23) )
|
|
pszCur = pszURL + 23;
|
|
else
|
|
{
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"URL %s not a supported format.", pszURL );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Clear any existing definition. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( GetRoot() != NULL )
|
|
{
|
|
delete poRoot;
|
|
poRoot = NULL;
|
|
}
|
|
|
|
if( EQUALN(pszCur, "-compound?1=", 12) )
|
|
{
|
|
/* -------------------------------------------------------------------- */
|
|
/* It's a compound CRS, of the form: */
|
|
/* */
|
|
/* http://opengis.net/def/crs-compound?1=URL1&2=URL2&3=URL3&.. */
|
|
/* -------------------------------------------------------------------- */
|
|
pszCur += 12;
|
|
|
|
// extract each component CRS URL
|
|
int iComponentUrl = 2;
|
|
|
|
CPLString osName = "";
|
|
Clear();
|
|
|
|
while (iComponentUrl != -1)
|
|
{
|
|
char searchStr[5];
|
|
sprintf(searchStr, "&%d=", iComponentUrl);
|
|
|
|
const char* pszUrlEnd = strstr(pszCur, searchStr);
|
|
|
|
// figure out the next component URL
|
|
char* pszComponentUrl;
|
|
|
|
if( pszUrlEnd )
|
|
{
|
|
size_t nLen = pszUrlEnd - pszCur;
|
|
pszComponentUrl = (char*) CPLMalloc(nLen + 1);
|
|
strncpy(pszComponentUrl, pszCur, nLen);
|
|
pszComponentUrl[nLen] = '\0';
|
|
|
|
++iComponentUrl;
|
|
pszCur += nLen + strlen(searchStr);
|
|
}
|
|
else
|
|
{
|
|
if( iComponentUrl == 2 )
|
|
{
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"Compound CRS URLs must have at least two component CRSs." );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
pszComponentUrl = CPLStrdup(pszCur);
|
|
// no more components
|
|
iComponentUrl = -1;
|
|
}
|
|
}
|
|
|
|
OGRSpatialReference oComponentSRS;
|
|
OGRErr eStatus = oComponentSRS.importFromCRSURL( pszComponentUrl );
|
|
|
|
CPLFree(pszComponentUrl);
|
|
pszComponentUrl = NULL;
|
|
|
|
if( eStatus == OGRERR_NONE )
|
|
{
|
|
if( osName.length() != 0 )
|
|
{
|
|
osName += " + ";
|
|
}
|
|
osName += oComponentSRS.GetRoot()->GetValue();
|
|
SetNode( "COMPD_CS", osName );
|
|
GetRoot()->AddChild( oComponentSRS.GetRoot()->Clone() );
|
|
}
|
|
else
|
|
return eStatus;
|
|
}
|
|
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
else
|
|
{
|
|
/* -------------------------------------------------------------------- */
|
|
/* It's a normal CRS URL, of the form: */
|
|
/* */
|
|
/* http://opengis.net/def/crs/AUTHORITY/VERSION/CODE */
|
|
/* -------------------------------------------------------------------- */
|
|
++pszCur;
|
|
const char *pszAuthority = pszCur;
|
|
|
|
// skip authority
|
|
while( *pszCur != '/' && *pszCur )
|
|
pszCur++;
|
|
if( *pszCur == '/' )
|
|
pszCur++;
|
|
|
|
|
|
// skip version
|
|
while( *pszCur != '/' && *pszCur )
|
|
pszCur++;
|
|
if( *pszCur == '/' )
|
|
pszCur++;
|
|
|
|
const char *pszCode = pszCur;
|
|
|
|
return importFromURNPart( pszAuthority, pszCode, pszURL );
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* importFromWMSAUTO() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Initialize from WMSAUTO string.
|
|
*
|
|
* Note that the WMS 1.3 specification does not include the
|
|
* units code, while apparently earlier specs do. We try to
|
|
* guess around this.
|
|
*
|
|
* @param pszDefinition the WMSAUTO string
|
|
*
|
|
* @return OGRERR_NONE on success or an error code.
|
|
*/
|
|
OGRErr OGRSpatialReference::importFromWMSAUTO( const char * pszDefinition )
|
|
|
|
{
|
|
char **papszTokens;
|
|
int nProjId, nUnitsId;
|
|
double dfRefLong, dfRefLat = 0.0;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Tokenize */
|
|
/* -------------------------------------------------------------------- */
|
|
if( EQUALN(pszDefinition,"AUTO:",5) )
|
|
pszDefinition += 5;
|
|
|
|
papszTokens = CSLTokenizeStringComplex( pszDefinition, ",", FALSE, TRUE );
|
|
|
|
if( CSLCount(papszTokens) == 4 )
|
|
{
|
|
nProjId = atoi(papszTokens[0]);
|
|
nUnitsId = atoi(papszTokens[1]);
|
|
dfRefLong = CPLAtof(papszTokens[2]);
|
|
dfRefLat = CPLAtof(papszTokens[3]);
|
|
}
|
|
else if( CSLCount(papszTokens) == 3 && atoi(papszTokens[0]) == 42005 )
|
|
{
|
|
nProjId = atoi(papszTokens[0]);
|
|
nUnitsId = atoi(papszTokens[1]);
|
|
dfRefLong = CPLAtof(papszTokens[2]);
|
|
dfRefLat = 0.0;
|
|
}
|
|
else if( CSLCount(papszTokens) == 3 )
|
|
{
|
|
nProjId = atoi(papszTokens[0]);
|
|
nUnitsId = 9001;
|
|
dfRefLong = CPLAtof(papszTokens[1]);
|
|
dfRefLat = CPLAtof(papszTokens[2]);
|
|
|
|
}
|
|
else if( CSLCount(papszTokens) == 2 && atoi(papszTokens[0]) == 42005 )
|
|
{
|
|
nProjId = atoi(papszTokens[0]);
|
|
nUnitsId = 9001;
|
|
dfRefLong = CPLAtof(papszTokens[1]);
|
|
}
|
|
else
|
|
{
|
|
CSLDestroy( papszTokens );
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"AUTO projection has wrong number of arguments, expected\n"
|
|
"AUTO:proj_id,units_id,ref_long,ref_lat or"
|
|
"AUTO:proj_id,ref_long,ref_lat" );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
CSLDestroy( papszTokens );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Build coordsys. */
|
|
/* -------------------------------------------------------------------- */
|
|
Clear();
|
|
|
|
switch( nProjId )
|
|
{
|
|
case 42001: // Auto UTM
|
|
SetUTM( (int) floor( (dfRefLong + 180.0) / 6.0 ) + 1,
|
|
dfRefLat >= 0.0 );
|
|
break;
|
|
|
|
case 42002: // Auto TM (strangely very UTM-like).
|
|
SetTM( 0, dfRefLong, 0.9996,
|
|
500000.0, (dfRefLat >= 0.0) ? 0.0 : 10000000.0 );
|
|
break;
|
|
|
|
case 42003: // Auto Orthographic.
|
|
SetOrthographic( dfRefLat, dfRefLong, 0.0, 0.0 );
|
|
break;
|
|
|
|
case 42004: // Auto Equirectangular
|
|
SetEquirectangular( dfRefLat, dfRefLong, 0.0, 0.0 );
|
|
break;
|
|
|
|
case 42005:
|
|
SetMollweide( dfRefLong, 0.0, 0.0 );
|
|
break;
|
|
|
|
default:
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"Unsupported projection id in importFromWMSAUTO(): %d",
|
|
nProjId );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Set units. */
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
switch( nUnitsId )
|
|
{
|
|
case 9001:
|
|
SetLinearUnits( SRS_UL_METER, 1.0 );
|
|
break;
|
|
|
|
case 9002:
|
|
SetLinearUnits( "Foot", 0.3048 );
|
|
break;
|
|
|
|
case 9003:
|
|
SetLinearUnits( "US survey foot", CPLAtof(SRS_UL_US_FOOT_CONV) );
|
|
break;
|
|
|
|
default:
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"Unsupported units code (%d).",
|
|
nUnitsId );
|
|
return OGRERR_FAILURE;
|
|
break;
|
|
}
|
|
|
|
SetAuthority( "PROJCS|UNIT", "EPSG", nUnitsId );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Set WGS84. */
|
|
/* -------------------------------------------------------------------- */
|
|
SetWellKnownGeogCS( "WGS84" );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetSemiMajor() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Get spheroid semi major axis.
|
|
*
|
|
* This method does the same thing as the C function OSRGetSemiMajor().
|
|
*
|
|
* @param pnErr if non-NULL set to OGRERR_FAILURE if semi major axis
|
|
* can be found.
|
|
*
|
|
* @return semi-major axis, or SRS_WGS84_SEMIMAJOR if it can't be found.
|
|
*/
|
|
|
|
double OGRSpatialReference::GetSemiMajor( OGRErr * pnErr ) const
|
|
|
|
{
|
|
const OGR_SRSNode *poSpheroid = GetAttrNode( "SPHEROID" );
|
|
|
|
if( pnErr != NULL )
|
|
*pnErr = OGRERR_NONE;
|
|
|
|
if( poSpheroid != NULL && poSpheroid->GetChildCount() >= 3 )
|
|
{
|
|
return CPLAtof( poSpheroid->GetChild(1)->GetValue() );
|
|
}
|
|
else
|
|
{
|
|
if( pnErr != NULL )
|
|
*pnErr = OGRERR_FAILURE;
|
|
|
|
return SRS_WGS84_SEMIMAJOR;
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRGetSemiMajor() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Get spheroid semi major axis.
|
|
*
|
|
* This function is the same as OGRSpatialReference::GetSemiMajor()
|
|
*/
|
|
double OSRGetSemiMajor( OGRSpatialReferenceH hSRS, OGRErr *pnErr )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRGetSemiMajor", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->GetSemiMajor( pnErr );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetInvFlattening() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Get spheroid inverse flattening.
|
|
*
|
|
* This method does the same thing as the C function OSRGetInvFlattening().
|
|
*
|
|
* @param pnErr if non-NULL set to OGRERR_FAILURE if no inverse flattening
|
|
* can be found.
|
|
*
|
|
* @return inverse flattening, or SRS_WGS84_INVFLATTENING if it can't be found.
|
|
*/
|
|
|
|
double OGRSpatialReference::GetInvFlattening( OGRErr * pnErr ) const
|
|
|
|
{
|
|
const OGR_SRSNode *poSpheroid = GetAttrNode( "SPHEROID" );
|
|
|
|
if( pnErr != NULL )
|
|
*pnErr = OGRERR_NONE;
|
|
|
|
if( poSpheroid != NULL && poSpheroid->GetChildCount() >= 3 )
|
|
{
|
|
return CPLAtof( poSpheroid->GetChild(2)->GetValue() );
|
|
}
|
|
else
|
|
{
|
|
if( pnErr != NULL )
|
|
*pnErr = OGRERR_FAILURE;
|
|
|
|
return SRS_WGS84_INVFLATTENING;
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRGetInvFlattening() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Get spheroid inverse flattening.
|
|
*
|
|
* This function is the same as OGRSpatialReference::GetInvFlattening()
|
|
*/
|
|
double OSRGetInvFlattening( OGRSpatialReferenceH hSRS, OGRErr *pnErr )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRGetInvFlattening", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->GetInvFlattening( pnErr );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetSemiMinor() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Get spheroid semi minor axis.
|
|
*
|
|
* This method does the same thing as the C function OSRGetSemiMinor().
|
|
*
|
|
* @param pnErr if non-NULL set to OGRERR_FAILURE if semi minor axis
|
|
* can be found.
|
|
*
|
|
* @return semi-minor axis, or WGS84 semi minor if it can't be found.
|
|
*/
|
|
|
|
double OGRSpatialReference::GetSemiMinor( OGRErr * pnErr ) const
|
|
|
|
{
|
|
double dfInvFlattening, dfSemiMajor;
|
|
|
|
dfSemiMajor = GetSemiMajor( pnErr );
|
|
dfInvFlattening = GetInvFlattening( pnErr );
|
|
|
|
return OSRCalcSemiMinorFromInvFlattening(dfSemiMajor, dfInvFlattening);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRGetSemiMinor() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Get spheroid semi minor axis.
|
|
*
|
|
* This function is the same as OGRSpatialReference::GetSemiMinor()
|
|
*/
|
|
double OSRGetSemiMinor( OGRSpatialReferenceH hSRS, OGRErr *pnErr )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRGetSemiMinor", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->GetSemiMinor( pnErr );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetLocalCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the user visible LOCAL_CS name.
|
|
*
|
|
* This method is the same as the C function OSRSetLocalCS().
|
|
*
|
|
* This method will ensure a LOCAL_CS node is created as the root,
|
|
* and set the provided name on it. It must be used before SetLinearUnits().
|
|
*
|
|
* @param pszName the user visible name to assign. Not used as a key.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetLocalCS( const char * pszName )
|
|
|
|
{
|
|
OGR_SRSNode *poCS = GetAttrNode( "LOCAL_CS" );
|
|
|
|
if( poCS == NULL && GetRoot() != NULL )
|
|
{
|
|
CPLDebug( "OGR",
|
|
"OGRSpatialReference::SetLocalCS(%s) failed.\n"
|
|
"It appears an incompatible root node (%s) already exists.\n",
|
|
pszName, GetRoot()->GetValue() );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
SetNode( "LOCAL_CS", pszName );
|
|
return OGRERR_NONE;
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetLocalCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the user visible LOCAL_CS name.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetLocalCS()
|
|
*/
|
|
OGRErr OSRSetLocalCS( OGRSpatialReferenceH hSRS, const char * pszName )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetLocalCS", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetLocalCS( pszName );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetGeocCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the user visible GEOCCS name.
|
|
*
|
|
* This method is the same as the C function OSRSetGeocCS().
|
|
|
|
* This method will ensure a GEOCCS node is created as the root,
|
|
* and set the provided name on it. If used on a GEOGCS coordinate system,
|
|
* the DATUM and PRIMEM nodes from the GEOGCS will be tarnsferred over to
|
|
* the GEOGCS.
|
|
*
|
|
* @param pszName the user visible name to assign. Not used as a key.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*
|
|
* @since OGR 1.9.0
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetGeocCS( const char * pszName )
|
|
|
|
{
|
|
OGR_SRSNode *poGeogCS = NULL;
|
|
OGR_SRSNode *poGeocCS = GetAttrNode( "GEOCCS" );
|
|
|
|
if( poRoot != NULL && EQUAL(poRoot->GetValue(),"GEOGCS") )
|
|
{
|
|
poGeogCS = poRoot;
|
|
poRoot = NULL;
|
|
}
|
|
|
|
if( poGeocCS == NULL && GetRoot() != NULL )
|
|
{
|
|
CPLDebug( "OGR",
|
|
"OGRSpatialReference::SetGeocCS(%s) failed.\n"
|
|
"It appears an incompatible root node (%s) already exists.\n",
|
|
pszName, GetRoot()->GetValue() );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
SetNode( "GEOCCS", pszName );
|
|
|
|
if( poGeogCS != NULL )
|
|
{
|
|
OGR_SRSNode *poDatum = poGeogCS->GetNode( "DATUM" );
|
|
OGR_SRSNode *poPRIMEM = poGeogCS->GetNode( "PRIMEM" );
|
|
if ( poDatum != NULL && poPRIMEM != NULL )
|
|
{
|
|
poRoot->InsertChild( poDatum->Clone(), 1 );
|
|
poRoot->InsertChild( poPRIMEM->Clone(), 2 );
|
|
}
|
|
delete poGeogCS;
|
|
}
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetGeocCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the user visible PROJCS name.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetGeocCS()
|
|
*
|
|
* @since OGR 1.9.0
|
|
*/
|
|
OGRErr OSRSetGeocCS( OGRSpatialReferenceH hSRS, const char * pszName )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetGeocCS", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetGeocCS( pszName );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetVertCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the user visible VERT_CS name.
|
|
*
|
|
* This method is the same as the C function OSRSetVertCS().
|
|
|
|
* This method will ensure a VERT_CS node is created if needed. If the
|
|
* existing coordinate system is GEOGCS or PROJCS rooted, then it will be
|
|
* turned into a COMPD_CS.
|
|
*
|
|
* @param pszVertCSName the user visible name of the vertical coordinate
|
|
* system. Not used as a key.
|
|
*
|
|
* @param pszVertDatumName the user visible name of the vertical datum. It
|
|
* is helpful if this matches the EPSG name.
|
|
*
|
|
* @param nVertDatumType the OGC vertical datum type, usually 2005.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*
|
|
* @since OGR 1.9.0
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetVertCS( const char * pszVertCSName,
|
|
const char * pszVertDatumName,
|
|
int nVertDatumType )
|
|
|
|
{
|
|
/* -------------------------------------------------------------------- */
|
|
/* Handle the case where we want to make a compound coordinate */
|
|
/* system. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( IsProjected() || IsGeographic() )
|
|
{
|
|
OGR_SRSNode *poNewRoot = new OGR_SRSNode( "COMPD_CS" );
|
|
poNewRoot->AddChild( poRoot );
|
|
poRoot = poNewRoot;
|
|
}
|
|
|
|
else if( GetAttrNode( "VERT_CS" ) == NULL )
|
|
Clear();
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* If we already have a VERT_CS, wipe and recreate the root */
|
|
/* otherwise create the VERT_CS now. */
|
|
/* -------------------------------------------------------------------- */
|
|
OGR_SRSNode *poVertCS = GetAttrNode( "VERT_CS" );
|
|
|
|
if( poVertCS != NULL )
|
|
{
|
|
poVertCS->ClearChildren();
|
|
}
|
|
else
|
|
{
|
|
poVertCS = new OGR_SRSNode( "VERT_CS" );
|
|
if( poRoot != NULL && EQUAL(poRoot->GetValue(),"COMPD_CS") )
|
|
{
|
|
poRoot->AddChild( poVertCS );
|
|
}
|
|
else
|
|
SetRoot( poVertCS );
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Set the name, datumname, and type. */
|
|
/* -------------------------------------------------------------------- */
|
|
OGR_SRSNode *poVertDatum;
|
|
|
|
poVertCS->AddChild( new OGR_SRSNode( pszVertCSName ) );
|
|
|
|
poVertDatum = new OGR_SRSNode( "VERT_DATUM" );
|
|
poVertCS->AddChild( poVertDatum );
|
|
|
|
poVertDatum->AddChild( new OGR_SRSNode( pszVertDatumName ) );
|
|
|
|
CPLString osVertDatumType;
|
|
osVertDatumType.Printf( "%d", nVertDatumType );
|
|
poVertDatum->AddChild( new OGR_SRSNode( osVertDatumType ) );
|
|
|
|
// add default axis node.
|
|
OGR_SRSNode *poAxis = new OGR_SRSNode( "AXIS" );
|
|
|
|
poAxis->AddChild( new OGR_SRSNode( "Up" ) );
|
|
poAxis->AddChild( new OGR_SRSNode( "UP" ) );
|
|
|
|
poVertCS->AddChild( poAxis );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetVertCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Setup the vertical coordinate system.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetVertCS()
|
|
*
|
|
* @since OGR 1.9.0
|
|
*/
|
|
OGRErr OSRSetVertCS( OGRSpatialReferenceH hSRS,
|
|
const char * pszVertCSName,
|
|
const char * pszVertDatumName,
|
|
int nVertDatumType )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetVertCS", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetVertCS( pszVertCSName,
|
|
pszVertDatumName,
|
|
nVertDatumType );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetCompoundCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Setup a compound coordinate system.
|
|
*
|
|
* This method is the same as the C function OSRSetCompoundCS().
|
|
|
|
* This method is replace the current SRS with a COMPD_CS coordinate system
|
|
* consisting of the passed in horizontal and vertical coordinate systems.
|
|
*
|
|
* @param pszName the name of the compound coordinate system.
|
|
*
|
|
* @param poHorizSRS the horizontal SRS (PROJCS or GEOGCS).
|
|
*
|
|
* @param poVertSRS the vertical SRS (VERT_CS).
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr
|
|
OGRSpatialReference::SetCompoundCS( const char *pszName,
|
|
const OGRSpatialReference *poHorizSRS,
|
|
const OGRSpatialReference *poVertSRS )
|
|
|
|
{
|
|
/* -------------------------------------------------------------------- */
|
|
/* Verify these are legal horizontal and vertical coordinate */
|
|
/* systems. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( !poVertSRS->IsVertical() )
|
|
{
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"SetCompoundCS() fails, vertical component is not VERT_CS." );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
if( !poHorizSRS->IsProjected()
|
|
&& !poHorizSRS->IsGeographic() )
|
|
{
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"SetCompoundCS() fails, horizontal component is not PROJCS or GEOGCS." );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Replace with compound srs. */
|
|
/* -------------------------------------------------------------------- */
|
|
Clear();
|
|
|
|
poRoot = new OGR_SRSNode( "COMPD_CS" );
|
|
poRoot->AddChild( new OGR_SRSNode( pszName ) );
|
|
poRoot->AddChild( poHorizSRS->GetRoot()->Clone() );
|
|
poRoot->AddChild( poVertSRS->GetRoot()->Clone() );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetCompoundCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Setup a compound coordinate system.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetCompoundCS()
|
|
*/
|
|
OGRErr OSRSetCompoundCS( OGRSpatialReferenceH hSRS,
|
|
const char *pszName,
|
|
OGRSpatialReferenceH hHorizSRS,
|
|
OGRSpatialReferenceH hVertSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetCompoundCS", CE_Failure );
|
|
VALIDATE_POINTER1( hHorizSRS, "OSRSetCompoundCS", CE_Failure );
|
|
VALIDATE_POINTER1( hVertSRS, "OSRSetCompoundCS", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->
|
|
SetCompoundCS( pszName,
|
|
(OGRSpatialReference *) hHorizSRS,
|
|
(OGRSpatialReference *) hVertSRS );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetProjCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the user visible PROJCS name.
|
|
*
|
|
* This method is the same as the C function OSRSetProjCS().
|
|
*
|
|
* This method will ensure a PROJCS node is created as the root,
|
|
* and set the provided name on it. If used on a GEOGCS coordinate system,
|
|
* the GEOGCS node will be demoted to be a child of the new PROJCS root.
|
|
*
|
|
* @param pszName the user visible name to assign. Not used as a key.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetProjCS( const char * pszName )
|
|
|
|
{
|
|
OGR_SRSNode *poGeogCS = NULL;
|
|
OGR_SRSNode *poProjCS = GetAttrNode( "PROJCS" );
|
|
|
|
if( poRoot != NULL && EQUAL(poRoot->GetValue(),"GEOGCS") )
|
|
{
|
|
poGeogCS = poRoot;
|
|
poRoot = NULL;
|
|
}
|
|
|
|
if( poProjCS == NULL && GetRoot() != NULL )
|
|
{
|
|
CPLDebug( "OGR",
|
|
"OGRSpatialReference::SetProjCS(%s) failed.\n"
|
|
"It appears an incompatible root node (%s) already exists.\n",
|
|
pszName, GetRoot()->GetValue() );
|
|
return OGRERR_FAILURE;
|
|
}
|
|
|
|
SetNode( "PROJCS", pszName );
|
|
|
|
if( poGeogCS != NULL )
|
|
poRoot->InsertChild( poGeogCS, 1 );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetProjCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the user visible PROJCS name.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetProjCS()
|
|
*/
|
|
OGRErr OSRSetProjCS( OGRSpatialReferenceH hSRS, const char * pszName )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetProjCS", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetProjCS( pszName );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetProjection() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set a projection name.
|
|
*
|
|
* This method is the same as the C function OSRSetProjection().
|
|
*
|
|
* @param pszProjection the projection name, which should be selected from
|
|
* the macros in ogr_srs_api.h, such as SRS_PT_TRANSVERSE_MERCATOR.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetProjection( const char * pszProjection )
|
|
|
|
{
|
|
OGR_SRSNode *poGeogCS = NULL;
|
|
OGRErr eErr;
|
|
|
|
if( poRoot != NULL && EQUAL(poRoot->GetValue(),"GEOGCS") )
|
|
{
|
|
poGeogCS = poRoot;
|
|
poRoot = NULL;
|
|
}
|
|
|
|
if( !GetAttrNode( "PROJCS" ) )
|
|
{
|
|
SetNode( "PROJCS", "unnamed" );
|
|
}
|
|
|
|
eErr = SetNode( "PROJCS|PROJECTION", pszProjection );
|
|
if( eErr != OGRERR_NONE )
|
|
return eErr;
|
|
|
|
if( poGeogCS != NULL )
|
|
poRoot->InsertChild( poGeogCS, 1 );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetProjection() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set a projection name.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetProjection()
|
|
*/
|
|
OGRErr OSRSetProjection( OGRSpatialReferenceH hSRS,
|
|
const char * pszProjection )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetProjection", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetProjection( pszProjection );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetProjParm() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set a projection parameter value.
|
|
*
|
|
* Adds a new PARAMETER under the PROJCS with the indicated name and value.
|
|
*
|
|
* This method is the same as the C function OSRSetProjParm().
|
|
*
|
|
* Please check http://www.remotesensing.org/geotiff/proj_list pages for
|
|
* legal parameter names for specific projections.
|
|
*
|
|
*
|
|
* @param pszParmName the parameter name, which should be selected from
|
|
* the macros in ogr_srs_api.h, such as SRS_PP_CENTRAL_MERIDIAN.
|
|
*
|
|
* @param dfValue value to assign.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetProjParm( const char * pszParmName,
|
|
double dfValue )
|
|
|
|
{
|
|
OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
|
|
OGR_SRSNode *poParm;
|
|
char szValue[64];
|
|
|
|
if( poPROJCS == NULL )
|
|
return OGRERR_FAILURE;
|
|
|
|
OGRPrintDouble( szValue, dfValue );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Try to find existing parameter with this name. */
|
|
/* -------------------------------------------------------------------- */
|
|
for( int iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
|
|
{
|
|
poParm = poPROJCS->GetChild( iChild );
|
|
|
|
if( EQUAL(poParm->GetValue(),"PARAMETER")
|
|
&& poParm->GetChildCount() == 2
|
|
&& EQUAL(poParm->GetChild(0)->GetValue(),pszParmName) )
|
|
{
|
|
poParm->GetChild(1)->SetValue( szValue );
|
|
return OGRERR_NONE;
|
|
}
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Otherwise create a new parameter and append. */
|
|
/* -------------------------------------------------------------------- */
|
|
poParm = new OGR_SRSNode( "PARAMETER" );
|
|
poParm->AddChild( new OGR_SRSNode( pszParmName ) );
|
|
poParm->AddChild( new OGR_SRSNode( szValue ) );
|
|
|
|
poPROJCS->AddChild( poParm );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetProjParm() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set a projection parameter value.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetProjParm()
|
|
*/
|
|
OGRErr OSRSetProjParm( OGRSpatialReferenceH hSRS,
|
|
const char * pszParmName, double dfValue )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetProjParm", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetProjParm( pszParmName, dfValue );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* FindProjParm() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Return the child index of the named projection parameter on
|
|
* its parent PROJCS node.
|
|
*
|
|
* @param pszParameter projection parameter to look for
|
|
* @param poPROJCS projection CS node to look in. If NULL is passed,
|
|
* the PROJCS node of the SpatialReference object will be searched.
|
|
*
|
|
* @return the child index of the named projection parameter. -1 on failure
|
|
*/
|
|
int OGRSpatialReference::FindProjParm( const char *pszParameter,
|
|
const OGR_SRSNode *poPROJCS ) const
|
|
|
|
{
|
|
const OGR_SRSNode *poParameter = NULL;
|
|
|
|
if( poPROJCS == NULL )
|
|
poPROJCS = GetAttrNode( "PROJCS" );
|
|
|
|
if( poPROJCS == NULL )
|
|
return -1;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Search for requested parameter. */
|
|
/* -------------------------------------------------------------------- */
|
|
int iChild;
|
|
|
|
for( iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
|
|
{
|
|
poParameter = poPROJCS->GetChild(iChild);
|
|
|
|
if( EQUAL(poParameter->GetValue(),"PARAMETER")
|
|
&& poParameter->GetChildCount() == 2
|
|
&& EQUAL(poPROJCS->GetChild(iChild)->GetChild(0)->GetValue(),
|
|
pszParameter) )
|
|
{
|
|
return iChild;
|
|
}
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Try similar names, for selected parameters. */
|
|
/* -------------------------------------------------------------------- */
|
|
iChild = -1;
|
|
|
|
if( EQUAL(pszParameter,SRS_PP_LATITUDE_OF_ORIGIN) )
|
|
{
|
|
iChild = FindProjParm( SRS_PP_LATITUDE_OF_CENTER, poPROJCS );
|
|
}
|
|
else if( EQUAL(pszParameter,SRS_PP_CENTRAL_MERIDIAN) )
|
|
{
|
|
iChild = FindProjParm(SRS_PP_LONGITUDE_OF_CENTER, poPROJCS );
|
|
if( iChild == -1 )
|
|
iChild = FindProjParm(SRS_PP_LONGITUDE_OF_ORIGIN, poPROJCS );
|
|
}
|
|
|
|
return iChild;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetProjParm() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch a projection parameter value.
|
|
*
|
|
* NOTE: This code should be modified to translate non degree angles into
|
|
* degrees based on the GEOGCS unit. This has not yet been done.
|
|
*
|
|
* This method is the same as the C function OSRGetProjParm().
|
|
*
|
|
* @param pszName the name of the parameter to fetch, from the set of
|
|
* SRS_PP codes in ogr_srs_api.h.
|
|
*
|
|
* @param dfDefaultValue the value to return if this parameter doesn't exist.
|
|
*
|
|
* @param pnErr place to put error code on failure. Ignored if NULL.
|
|
*
|
|
* @return value of parameter.
|
|
*/
|
|
|
|
double OGRSpatialReference::GetProjParm( const char * pszName,
|
|
double dfDefaultValue,
|
|
OGRErr *pnErr ) const
|
|
|
|
{
|
|
const OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
|
|
|
|
if( pnErr != NULL )
|
|
*pnErr = OGRERR_NONE;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Find the desired parameter. */
|
|
/* -------------------------------------------------------------------- */
|
|
int iChild = FindProjParm( pszName, poPROJCS );
|
|
|
|
if( iChild != -1 )
|
|
{
|
|
const OGR_SRSNode *poParameter = NULL;
|
|
poParameter = poPROJCS->GetChild(iChild);
|
|
return CPLAtof(poParameter->GetChild(1)->GetValue());
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Return default value on failure. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( pnErr != NULL )
|
|
*pnErr = OGRERR_FAILURE;
|
|
|
|
return dfDefaultValue;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRGetProjParm() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch a projection parameter value.
|
|
*
|
|
* This function is the same as OGRSpatialReference::GetProjParm()
|
|
*/
|
|
double OSRGetProjParm( OGRSpatialReferenceH hSRS, const char *pszName,
|
|
double dfDefaultValue, OGRErr *pnErr )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRGetProjParm", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->
|
|
GetProjParm(pszName, dfDefaultValue, pnErr);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetNormProjParm() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch a normalized projection parameter value.
|
|
*
|
|
* This method is the same as GetProjParm() except that the value of
|
|
* the parameter is "normalized" into degrees or meters depending on
|
|
* whether it is linear or angular.
|
|
*
|
|
* This method is the same as the C function OSRGetNormProjParm().
|
|
*
|
|
* @param pszName the name of the parameter to fetch, from the set of
|
|
* SRS_PP codes in ogr_srs_api.h.
|
|
*
|
|
* @param dfDefaultValue the value to return if this parameter doesn't exist.
|
|
*
|
|
* @param pnErr place to put error code on failure. Ignored if NULL.
|
|
*
|
|
* @return value of parameter.
|
|
*/
|
|
|
|
double OGRSpatialReference::GetNormProjParm( const char * pszName,
|
|
double dfDefaultValue,
|
|
OGRErr *pnErr ) const
|
|
|
|
{
|
|
double dfRawResult;
|
|
OGRErr nError;
|
|
|
|
if( pnErr == NULL )
|
|
pnErr = &nError;
|
|
|
|
GetNormInfo();
|
|
|
|
dfRawResult = GetProjParm( pszName, dfDefaultValue, pnErr );
|
|
|
|
// If we got the default just return it unadjusted.
|
|
if( *pnErr != OGRERR_NONE )
|
|
return dfRawResult;
|
|
|
|
if( dfToDegrees != 1.0 && IsAngularParameter(pszName) )
|
|
dfRawResult *= dfToDegrees;
|
|
|
|
if( dfToMeter != 1.0 && IsLinearParameter( pszName ) )
|
|
return dfRawResult * dfToMeter;
|
|
#ifdef WKT_LONGITUDE_RELATIVE_TO_PM
|
|
else if( dfFromGreenwich != 0.0 && IsLongitudeParameter( pszName ) )
|
|
return dfRawResult + dfFromGreenwich;
|
|
#endif
|
|
else
|
|
return dfRawResult;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRGetNormProjParm() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief This function is the same as OGRSpatialReference::
|
|
*
|
|
* This function is the same as OGRSpatialReference::GetNormProjParm()
|
|
*/
|
|
double OSRGetNormProjParm( OGRSpatialReferenceH hSRS, const char *pszName,
|
|
double dfDefaultValue, OGRErr *pnErr )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRGetNormProjParm", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->
|
|
GetNormProjParm(pszName, dfDefaultValue, pnErr);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetNormProjParm() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set a projection parameter with a normalized value.
|
|
*
|
|
* This method is the same as SetProjParm() except that the value of
|
|
* the parameter passed in is assumed to be in "normalized" form (decimal
|
|
* degrees for angular values, meters for linear values. The values are
|
|
* converted in a form suitable for the GEOGCS and linear units in effect.
|
|
*
|
|
* This method is the same as the C function OSRSetNormProjParm().
|
|
*
|
|
* @param pszName the parameter name, which should be selected from
|
|
* the macros in ogr_srs_api.h, such as SRS_PP_CENTRAL_MERIDIAN.
|
|
*
|
|
* @param dfValue value to assign.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetNormProjParm( const char * pszName,
|
|
double dfValue )
|
|
|
|
{
|
|
GetNormInfo();
|
|
|
|
if( (dfToDegrees != 1.0 || dfFromGreenwich != 0.0)
|
|
&& IsAngularParameter(pszName) )
|
|
{
|
|
#ifdef WKT_LONGITUDE_RELATIVE_TO_PM
|
|
if( dfFromGreenwich != 0.0 && IsLongitudeParameter( pszName ) )
|
|
dfValue -= dfFromGreenwich;
|
|
#endif
|
|
|
|
dfValue /= dfToDegrees;
|
|
}
|
|
else if( dfToMeter != 1.0 && IsLinearParameter( pszName ) )
|
|
dfValue /= dfToMeter;
|
|
|
|
return SetProjParm( pszName, dfValue );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetNormProjParm() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set a projection parameter with a normalized value.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetNormProjParm()
|
|
*/
|
|
OGRErr OSRSetNormProjParm( OGRSpatialReferenceH hSRS,
|
|
const char * pszParmName, double dfValue )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetNormProjParm", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->
|
|
SetNormProjParm( pszParmName, dfValue );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetTM() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetTM( double dfCenterLat, double dfCenterLong,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_TRANSVERSE_MERCATOR );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetTM() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetTM( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetTM", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetTM(
|
|
dfCenterLat, dfCenterLong,
|
|
dfScale,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetTMVariant() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetTMVariant(
|
|
const char *pszVariantName,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( pszVariantName );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetTMVariant() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetTMVariant( OGRSpatialReferenceH hSRS,
|
|
const char *pszVariantName,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetTMVariant", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetTMVariant(
|
|
pszVariantName,
|
|
dfCenterLat, dfCenterLong,
|
|
dfScale,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetTMSO() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetTMSO( double dfCenterLat, double dfCenterLong,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_TRANSVERSE_MERCATOR_SOUTH_ORIENTED );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetTPED() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetTPED( double dfLat1, double dfLong1,
|
|
double dfLat2, double dfLong2,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_TWO_POINT_EQUIDISTANT );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_1ST_POINT, dfLat1 );
|
|
SetNormProjParm( SRS_PP_LONGITUDE_OF_1ST_POINT, dfLong1 );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_2ND_POINT, dfLat2 );
|
|
SetNormProjParm( SRS_PP_LONGITUDE_OF_2ND_POINT, dfLong2 );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetTPED() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetTPED( OGRSpatialReferenceH hSRS,
|
|
double dfLat1, double dfLong1,
|
|
double dfLat2, double dfLong2,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetTPED", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetTPED(
|
|
dfLat1, dfLong1, dfLat2, dfLong2,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetTMSO() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetTMSO( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetTMSO", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetTMSO(
|
|
dfCenterLat, dfCenterLong,
|
|
dfScale,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetTMG() */
|
|
/************************************************************************/
|
|
|
|
OGRErr
|
|
OGRSpatialReference::SetTMG( double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_TUNISIA_MINING_GRID );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetTMG() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetTMG( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetTMG", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetTMG(
|
|
dfCenterLat, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetACEA() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetACEA( double dfStdP1, double dfStdP2,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_ALBERS_CONIC_EQUAL_AREA );
|
|
SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
|
|
SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetACEA() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetACEA( OGRSpatialReferenceH hSRS,
|
|
double dfStdP1, double dfStdP2,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetACEA", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetACEA(
|
|
dfStdP1, dfStdP2,
|
|
dfCenterLat, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetAE() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetAE( double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_AZIMUTHAL_EQUIDISTANT );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetAE() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetAE( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetACEA", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetAE(
|
|
dfCenterLat, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetBonne() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetBonne(
|
|
double dfStdP1, double dfCentralMeridian,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_BONNE );
|
|
SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetBonne() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetBonne( OGRSpatialReferenceH hSRS,
|
|
double dfStdP1, double dfCentralMeridian,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetBonne", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetBonne(
|
|
dfStdP1, dfCentralMeridian,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetCEA() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetCEA( double dfStdP1, double dfCentralMeridian,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_CYLINDRICAL_EQUAL_AREA );
|
|
SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetCEA() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetCEA( OGRSpatialReferenceH hSRS,
|
|
double dfStdP1, double dfCentralMeridian,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetCEA", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetCEA(
|
|
dfStdP1, dfCentralMeridian,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetCS() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetCS( double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_CASSINI_SOLDNER );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetCS() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetCS( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetCS", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetCS(
|
|
dfCenterLat, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetEC() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetEC( double dfStdP1, double dfStdP2,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_EQUIDISTANT_CONIC );
|
|
SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
|
|
SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetEC() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetEC( OGRSpatialReferenceH hSRS,
|
|
double dfStdP1, double dfStdP2,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetEC", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetEC(
|
|
dfStdP1, dfStdP2,
|
|
dfCenterLat, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetEckert() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetEckert( int nVariation /* 1-6 */,
|
|
double dfCentralMeridian,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
if( nVariation == 1 )
|
|
SetProjection( SRS_PT_ECKERT_I );
|
|
else if( nVariation == 2 )
|
|
SetProjection( SRS_PT_ECKERT_II );
|
|
else if( nVariation == 3 )
|
|
SetProjection( SRS_PT_ECKERT_III );
|
|
else if( nVariation == 4 )
|
|
SetProjection( SRS_PT_ECKERT_IV );
|
|
else if( nVariation == 5 )
|
|
SetProjection( SRS_PT_ECKERT_V );
|
|
else if( nVariation == 6 )
|
|
SetProjection( SRS_PT_ECKERT_VI );
|
|
else
|
|
{
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"Unsupported Eckert variation (%d).",
|
|
nVariation );
|
|
return OGRERR_UNSUPPORTED_SRS;
|
|
}
|
|
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetEckert() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetEckert( OGRSpatialReferenceH hSRS,
|
|
int nVariation,
|
|
double dfCentralMeridian,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetEckert", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetEckert(
|
|
nVariation, dfCentralMeridian,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetEckertIV() */
|
|
/* */
|
|
/* Deprecated */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetEckertIV( double dfCentralMeridian,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_ECKERT_IV );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetEckertIV() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetEckertIV( OGRSpatialReferenceH hSRS,
|
|
double dfCentralMeridian,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetEckertIV", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetEckertIV(
|
|
dfCentralMeridian,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetEckertVI() */
|
|
/* */
|
|
/* Deprecated */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetEckertVI( double dfCentralMeridian,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_ECKERT_VI );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetEckertVI() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetEckertVI( OGRSpatialReferenceH hSRS,
|
|
double dfCentralMeridian,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetEckertVI", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetEckertVI(
|
|
dfCentralMeridian,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetEquirectangular() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetEquirectangular(
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_EQUIRECTANGULAR );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetEquirectangular() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetEquirectangular( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetEquirectangular", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetEquirectangular(
|
|
dfCenterLat, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetEquirectangular2() */
|
|
/* Generalized form */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetEquirectangular2(
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfStdParallel1,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_EQUIRECTANGULAR );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdParallel1 );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetEquirectangular2() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetEquirectangular2( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfStdParallel1,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetEquirectangular2", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetEquirectangular2(
|
|
dfCenterLat, dfCenterLong,
|
|
dfStdParallel1,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetGS() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetGS( double dfCentralMeridian,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_GALL_STEREOGRAPHIC );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetGS() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetGS( OGRSpatialReferenceH hSRS,
|
|
double dfCentralMeridian,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetGS", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetGS(
|
|
dfCentralMeridian,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetGH() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetGH( double dfCentralMeridian,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_GOODE_HOMOLOSINE );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetGH() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetGH( OGRSpatialReferenceH hSRS,
|
|
double dfCentralMeridian,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetGH", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetGH(
|
|
dfCentralMeridian,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetIGH() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetIGH()
|
|
|
|
{
|
|
SetProjection( SRS_PT_IGH );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetIGH() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetIGH( OGRSpatialReferenceH hSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetIGH", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetIGH();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetGEOS() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetGEOS( double dfCentralMeridian,
|
|
double dfSatelliteHeight,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_GEOSTATIONARY_SATELLITE );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
|
|
SetNormProjParm( SRS_PP_SATELLITE_HEIGHT, dfSatelliteHeight );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetGEOS() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetGEOS( OGRSpatialReferenceH hSRS,
|
|
double dfCentralMeridian,
|
|
double dfSatelliteHeight,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetGEOS", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetGEOS(
|
|
dfCentralMeridian, dfSatelliteHeight,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetGaussSchreiberTMercator() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetGaussSchreiberTMercator(
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_GAUSSSCHREIBERTMERCATOR );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetGaussSchreiberTMercator() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetGaussSchreiberTMercator( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetGaussSchreiberTMercator", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetGaussSchreiberTMercator(
|
|
dfCenterLat, dfCenterLong, dfScale,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetGnomonic() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetGnomonic(
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_GNOMONIC );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetGnomonic() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetGnomonic( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetGnomonic", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetGnomonic(
|
|
dfCenterLat, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetHOMAC() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set an Hotine Oblique Mercator Azimuth Center projection using
|
|
* azimuth angle.
|
|
*
|
|
* This projection corresponds to EPSG projection method 9815, also
|
|
* sometimes known as hotine oblique mercator (variant B).
|
|
*
|
|
* This method does the same thing as the C function OSRSetHOMAC().
|
|
*
|
|
* @param dfCenterLat Latitude of the projection origin.
|
|
* @param dfCenterLong Longitude of the projection origin.
|
|
* @param dfAzimuth Azimuth, measured clockwise from North, of the projection
|
|
* centerline.
|
|
* @param dfRectToSkew ?.
|
|
* @param dfScale Scale factor applies to the projection origin.
|
|
* @param dfFalseEasting False easting.
|
|
* @param dfFalseNorthing False northing.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetHOMAC( double dfCenterLat, double dfCenterLong,
|
|
double dfAzimuth, double dfRectToSkew,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_HOTINE_OBLIQUE_MERCATOR_AZIMUTH_CENTER );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_AZIMUTH, dfAzimuth );
|
|
SetNormProjParm( SRS_PP_RECTIFIED_GRID_ANGLE, dfRectToSkew );
|
|
SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetHOMAC() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set an Oblique Mercator projection using azimuth angle.
|
|
*
|
|
* This is the same as the C++ method OGRSpatialReference::SetHOMAC()
|
|
*/
|
|
OGRErr OSRSetHOMAC( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfAzimuth, double dfRectToSkew,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetHOMAC", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetHOMAC(
|
|
dfCenterLat, dfCenterLong,
|
|
dfAzimuth, dfRectToSkew,
|
|
dfScale,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetHOM() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set a Hotine Oblique Mercator projection using azimuth angle.
|
|
*
|
|
* This projection corresponds to EPSG projection method 9812, also
|
|
* sometimes known as hotine oblique mercator (variant A)..
|
|
*
|
|
* This method does the same thing as the C function OSRSetHOM().
|
|
*
|
|
* @param dfCenterLat Latitude of the projection origin.
|
|
* @param dfCenterLong Longitude of the projection origin.
|
|
* @param dfAzimuth Azimuth, measured clockwise from North, of the projection
|
|
* centerline.
|
|
* @param dfRectToSkew ?.
|
|
* @param dfScale Scale factor applies to the projection origin.
|
|
* @param dfFalseEasting False easting.
|
|
* @param dfFalseNorthing False northing.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetHOM( double dfCenterLat, double dfCenterLong,
|
|
double dfAzimuth, double dfRectToSkew,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_HOTINE_OBLIQUE_MERCATOR );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_AZIMUTH, dfAzimuth );
|
|
SetNormProjParm( SRS_PP_RECTIFIED_GRID_ANGLE, dfRectToSkew );
|
|
SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetHOM() */
|
|
/************************************************************************/
|
|
/**
|
|
* \brief Set a Hotine Oblique Mercator projection using azimuth angle.
|
|
*
|
|
* This is the same as the C++ method OGRSpatialReference::SetHOM()
|
|
*/
|
|
OGRErr OSRSetHOM( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfAzimuth, double dfRectToSkew,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetHOM", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetHOM(
|
|
dfCenterLat, dfCenterLong,
|
|
dfAzimuth, dfRectToSkew,
|
|
dfScale,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetHOM2PNO() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set a Hotine Oblique Mercator projection using two points on projection
|
|
* centerline.
|
|
*
|
|
* This method does the same thing as the C function OSRSetHOM2PNO().
|
|
*
|
|
* @param dfCenterLat Latitude of the projection origin.
|
|
* @param dfLat1 Latitude of the first point on center line.
|
|
* @param dfLong1 Longitude of the first point on center line.
|
|
* @param dfLat2 Latitude of the second point on center line.
|
|
* @param dfLong2 Longitude of the second point on center line.
|
|
* @param dfScale Scale factor applies to the projection origin.
|
|
* @param dfFalseEasting False easting.
|
|
* @param dfFalseNorthing False northing.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetHOM2PNO( double dfCenterLat,
|
|
double dfLat1, double dfLong1,
|
|
double dfLat2, double dfLong2,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_HOTINE_OBLIQUE_MERCATOR_TWO_POINT_NATURAL_ORIGIN );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_POINT_1, dfLat1 );
|
|
SetNormProjParm( SRS_PP_LONGITUDE_OF_POINT_1, dfLong1 );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_POINT_2, dfLat2 );
|
|
SetNormProjParm( SRS_PP_LONGITUDE_OF_POINT_2, dfLong2 );
|
|
SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetHOM2PNO() */
|
|
/************************************************************************/
|
|
/**
|
|
* \brief Set a Hotine Oblique Mercator projection using two points on projection
|
|
* centerline.
|
|
*
|
|
* This is the same as the C++ method OGRSpatialReference::SetHOM2PNO()
|
|
*/
|
|
OGRErr OSRSetHOM2PNO( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat,
|
|
double dfLat1, double dfLong1,
|
|
double dfLat2, double dfLong2,
|
|
double dfScale,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetHOM2PNO", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetHOM2PNO(
|
|
dfCenterLat,
|
|
dfLat1, dfLong1,
|
|
dfLat2, dfLong2,
|
|
dfScale,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetIWMPolyconic() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetIWMPolyconic(
|
|
double dfLat1, double dfLat2,
|
|
double dfCenterLong,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_IMW_POLYCONIC );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_1ST_POINT, dfLat1 );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_2ND_POINT, dfLat2 );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetIWMPolyconic() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetIWMPolyconic( OGRSpatialReferenceH hSRS,
|
|
double dfLat1, double dfLat2,
|
|
double dfCenterLong,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetIWMPolyconic", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetIWMPolyconic(
|
|
dfLat1, dfLat2, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetKrovak() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetKrovak( double dfCenterLat, double dfCenterLong,
|
|
double dfAzimuth,
|
|
double dfPseudoStdParallel1,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_KROVAK );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_AZIMUTH, dfAzimuth );
|
|
SetNormProjParm( SRS_PP_PSEUDO_STD_PARALLEL_1, dfPseudoStdParallel1 );
|
|
SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetKrovak() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetKrovak( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfAzimuth, double dfPseudoStdParallel1,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetKrovak", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetKrovak(
|
|
dfCenterLat, dfCenterLong,
|
|
dfAzimuth, dfPseudoStdParallel1,
|
|
dfScale,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetLAEA() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetLAEA( double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_LAMBERT_AZIMUTHAL_EQUAL_AREA );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetLAEA() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetLAEA( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetLAEA", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetLAEA(
|
|
dfCenterLat, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetLCC() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetLCC( double dfStdP1, double dfStdP2,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP );
|
|
SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
|
|
SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetLCC() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetLCC( OGRSpatialReferenceH hSRS,
|
|
double dfStdP1, double dfStdP2,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetLCC", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetLCC(
|
|
dfStdP1, dfStdP2,
|
|
dfCenterLat, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetLCC1SP() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetLCC1SP( double dfCenterLat, double dfCenterLong,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_LAMBERT_CONFORMAL_CONIC_1SP );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetLCC1SP() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetLCC1SP( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfScale,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetLCC1SP", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetLCC1SP(
|
|
dfCenterLat, dfCenterLong,
|
|
dfScale,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetLCCB() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetLCCB( double dfStdP1, double dfStdP2,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_LAMBERT_CONFORMAL_CONIC_2SP_BELGIUM );
|
|
SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
|
|
SetNormProjParm( SRS_PP_STANDARD_PARALLEL_2, dfStdP2 );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetLCCB() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetLCCB( OGRSpatialReferenceH hSRS,
|
|
double dfStdP1, double dfStdP2,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetLCCB", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetLCCB(
|
|
dfStdP1, dfStdP2,
|
|
dfCenterLat, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetMC() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetMC( double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_MILLER_CYLINDRICAL );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetMC() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetMC( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetMC", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetMC(
|
|
dfCenterLat, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetMercator() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetMercator( double dfCenterLat, double dfCenterLong,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_MERCATOR_1SP );
|
|
|
|
if( dfCenterLat != 0.0 )
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetMercator() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetMercator( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfScale,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetMercator", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetMercator(
|
|
dfCenterLat, dfCenterLong,
|
|
dfScale,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetMercator2SP() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetMercator2SP(
|
|
double dfStdP1,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_MERCATOR_2SP );
|
|
|
|
SetNormProjParm( SRS_PP_STANDARD_PARALLEL_1, dfStdP1 );
|
|
if( dfCenterLat != 0.0 )
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetMercator2SP() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetMercator2SP( OGRSpatialReferenceH hSRS,
|
|
double dfStdP1,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetMercator2SP", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetMercator2SP(
|
|
dfStdP1,
|
|
dfCenterLat, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetMollweide() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetMollweide( double dfCentralMeridian,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_MOLLWEIDE );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetMollweide() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetMollweide( OGRSpatialReferenceH hSRS,
|
|
double dfCentralMeridian,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetMollweide", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetMollweide(
|
|
dfCentralMeridian,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetNZMG() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetNZMG( double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_NEW_ZEALAND_MAP_GRID );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetNZMG() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetNZMG( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetNZMG", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetNZMG(
|
|
dfCenterLat, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetOS() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetOS( double dfOriginLat, double dfCMeridian,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_OBLIQUE_STEREOGRAPHIC );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfOriginLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCMeridian );
|
|
SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetOS() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetOS( OGRSpatialReferenceH hSRS,
|
|
double dfOriginLat, double dfCMeridian,
|
|
double dfScale,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetOS", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetOS(
|
|
dfOriginLat, dfCMeridian,
|
|
dfScale,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetOrthographic() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetOrthographic(
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_ORTHOGRAPHIC );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetOrthographic() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetOrthographic( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetOrthographic", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetOrthographic(
|
|
dfCenterLat, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetPolyconic() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetPolyconic(
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
// note: it seems that by some definitions this should include a
|
|
// scale_factor parameter.
|
|
|
|
SetProjection( SRS_PT_POLYCONIC );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetPolyconic() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetPolyconic( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetPolyconic", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetPolyconic(
|
|
dfCenterLat, dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetPS() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetPS(
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfScale,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_POLAR_STEREOGRAPHIC );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetPS() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetPS( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong,
|
|
double dfScale,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetPS", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetPS(
|
|
dfCenterLat, dfCenterLong,
|
|
dfScale,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetRobinson() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetRobinson( double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_ROBINSON );
|
|
SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetRobinson() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetRobinson( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLong,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetRobinson", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetRobinson(
|
|
dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetSinusoidal() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetSinusoidal( double dfCenterLong,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_SINUSOIDAL );
|
|
SetNormProjParm( SRS_PP_LONGITUDE_OF_CENTER, dfCenterLong );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetSinusoidal() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetSinusoidal( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLong,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetSinusoidal", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetSinusoidal(
|
|
dfCenterLong,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetStereographic() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetStereographic(
|
|
double dfOriginLat, double dfCMeridian,
|
|
double dfScale,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_STEREOGRAPHIC );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfOriginLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCMeridian );
|
|
SetNormProjParm( SRS_PP_SCALE_FACTOR, dfScale );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetStereographic() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetStereographic( OGRSpatialReferenceH hSRS,
|
|
double dfOriginLat, double dfCMeridian,
|
|
double dfScale,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetStereographic", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetStereographic(
|
|
dfOriginLat, dfCMeridian,
|
|
dfScale,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetSOC() */
|
|
/* */
|
|
/* NOTE: This definition isn't really used in practice any more */
|
|
/* and should be considered deprecated. It seems that swiss */
|
|
/* oblique mercator is now define as Hotine_Oblique_Mercator */
|
|
/* with an azimuth of 90 and a rectified_grid_angle of 90. See */
|
|
/* EPSG:2056 and Bug 423. */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetSOC( double dfLatitudeOfOrigin,
|
|
double dfCentralMeridian,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_SWISS_OBLIQUE_CYLINDRICAL );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_CENTER, dfLatitudeOfOrigin );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCentralMeridian );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetSOC() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetSOC( OGRSpatialReferenceH hSRS,
|
|
double dfLatitudeOfOrigin, double dfCentralMeridian,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetSOC", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetSOC(
|
|
dfLatitudeOfOrigin, dfCentralMeridian,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetVDG() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetVDG( double dfCMeridian,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
SetProjection( SRS_PT_VANDERGRINTEN );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCMeridian );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetVDG() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetVDG( OGRSpatialReferenceH hSRS,
|
|
double dfCentralMeridian,
|
|
double dfFalseEasting, double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetVDG", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetVDG(
|
|
dfCentralMeridian,
|
|
dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetUTM() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set UTM projection definition.
|
|
*
|
|
* This will generate a projection definition with the full set of
|
|
* transverse mercator projection parameters for the given UTM zone.
|
|
* If no PROJCS[] description is set yet, one will be set to look
|
|
* like "UTM Zone %d, {Northern, Southern} Hemisphere".
|
|
*
|
|
* This method is the same as the C function OSRSetUTM().
|
|
*
|
|
* @param nZone UTM zone.
|
|
*
|
|
* @param bNorth TRUE for northern hemisphere, or FALSE for southern
|
|
* hemisphere.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetUTM( int nZone, int bNorth )
|
|
|
|
{
|
|
SetProjection( SRS_PT_TRANSVERSE_MERCATOR );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0 );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, nZone * 6 - 183 );
|
|
SetNormProjParm( SRS_PP_SCALE_FACTOR, 0.9996 );
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, 500000.0 );
|
|
|
|
if( bNorth )
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, 0 );
|
|
else
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, 10000000 );
|
|
|
|
if( EQUAL(GetAttrValue("PROJCS"),"unnamed") )
|
|
{
|
|
char szUTMName[128];
|
|
|
|
if( bNorth )
|
|
sprintf( szUTMName, "UTM Zone %d, Northern Hemisphere", nZone );
|
|
else
|
|
sprintf( szUTMName, "UTM Zone %d, Southern Hemisphere", nZone );
|
|
|
|
SetNode( "PROJCS", szUTMName );
|
|
}
|
|
|
|
SetLinearUnits( SRS_UL_METER, 1.0 );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetUTM() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set UTM projection definition.
|
|
*
|
|
* This is the same as the C++ method OGRSpatialReference::SetUTM()
|
|
*/
|
|
OGRErr OSRSetUTM( OGRSpatialReferenceH hSRS, int nZone, int bNorth )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetUTM", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetUTM( nZone, bNorth );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetUTMZone() */
|
|
/* */
|
|
/* Returns zero if it isn't UTM. */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Get utm zone information.
|
|
*
|
|
* This is the same as the C function OSRGetUTMZone().
|
|
*
|
|
* In SWIG bindings (Python, Java, etc) the GetUTMZone() method returns a
|
|
* zone which is negative in the southern hemisphere instead of having the
|
|
* pbNorth flag used in the C and C++ interface.
|
|
*
|
|
* @param pbNorth pointer to in to set to TRUE if northern hemisphere, or
|
|
* FALSE if southern.
|
|
*
|
|
* @return UTM zone number or zero if this isn't a UTM definition.
|
|
*/
|
|
|
|
int OGRSpatialReference::GetUTMZone( int * pbNorth ) const
|
|
|
|
{
|
|
const char *pszProjection = GetAttrValue( "PROJECTION" );
|
|
|
|
if( pszProjection == NULL
|
|
|| !EQUAL(pszProjection,SRS_PT_TRANSVERSE_MERCATOR) )
|
|
return 0;
|
|
|
|
if( GetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, 0.0 ) != 0.0 )
|
|
return 0;
|
|
|
|
if( GetProjParm( SRS_PP_SCALE_FACTOR, 1.0 ) != 0.9996 )
|
|
return 0;
|
|
|
|
if( fabs(GetNormProjParm( SRS_PP_FALSE_EASTING, 0.0 )-500000.0) > 0.001 )
|
|
return 0;
|
|
|
|
double dfFalseNorthing = GetNormProjParm( SRS_PP_FALSE_NORTHING, 0.0);
|
|
|
|
if( dfFalseNorthing != 0.0
|
|
&& fabs(dfFalseNorthing-10000000.0) > 0.001 )
|
|
return 0;
|
|
|
|
if( pbNorth != NULL )
|
|
*pbNorth = (dfFalseNorthing == 0);
|
|
|
|
double dfCentralMeridian = GetNormProjParm( SRS_PP_CENTRAL_MERIDIAN,
|
|
0.0);
|
|
double dfZone = ( dfCentralMeridian + 186.0 ) / 6.0;
|
|
|
|
if( ABS(dfZone - (int) dfZone - 0.5 ) > 0.00001
|
|
|| dfCentralMeridian < -177.00001
|
|
|| dfCentralMeridian > 177.000001 )
|
|
return 0;
|
|
else
|
|
return (int) dfZone;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRGetUTMZone() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Get utm zone information.
|
|
*
|
|
* This is the same as the C++ method OGRSpatialReference::GetUTMZone()
|
|
*/
|
|
int OSRGetUTMZone( OGRSpatialReferenceH hSRS, int *pbNorth )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRGetUTMZone", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->GetUTMZone( pbNorth );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetWagner() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetWagner( int nVariation /* 1 -- 7 */,
|
|
double dfCenterLat,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
if( nVariation == 1 )
|
|
SetProjection( SRS_PT_WAGNER_I );
|
|
else if( nVariation == 2 )
|
|
SetProjection( SRS_PT_WAGNER_II );
|
|
else if( nVariation == 3 )
|
|
{
|
|
SetProjection( SRS_PT_WAGNER_III );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
}
|
|
else if( nVariation == 4 )
|
|
SetProjection( SRS_PT_WAGNER_IV );
|
|
else if( nVariation == 5 )
|
|
SetProjection( SRS_PT_WAGNER_V );
|
|
else if( nVariation == 6 )
|
|
SetProjection( SRS_PT_WAGNER_VI );
|
|
else if( nVariation == 7 )
|
|
SetProjection( SRS_PT_WAGNER_VII );
|
|
else
|
|
{
|
|
CPLError( CE_Failure, CPLE_AppDefined,
|
|
"Unsupported Wagner variation (%d).", nVariation );
|
|
return OGRERR_UNSUPPORTED_SRS;
|
|
}
|
|
|
|
SetNormProjParm( SRS_PP_FALSE_EASTING, dfFalseEasting );
|
|
SetNormProjParm( SRS_PP_FALSE_NORTHING, dfFalseNorthing );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetWagner() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetWagner( OGRSpatialReferenceH hSRS,
|
|
int nVariation, double dfCenterLat,
|
|
double dfFalseEasting,
|
|
double dfFalseNorthing )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetWagner", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetWagner(
|
|
nVariation, dfCenterLat, dfFalseEasting, dfFalseNorthing );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetQSC() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OGRSpatialReference::SetQSC( double dfCenterLat, double dfCenterLong )
|
|
|
|
{
|
|
SetProjection( SRS_PT_QSC );
|
|
SetNormProjParm( SRS_PP_LATITUDE_OF_ORIGIN, dfCenterLat );
|
|
SetNormProjParm( SRS_PP_CENTRAL_MERIDIAN, dfCenterLong );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetQSC() */
|
|
/************************************************************************/
|
|
|
|
OGRErr OSRSetQSC( OGRSpatialReferenceH hSRS,
|
|
double dfCenterLat, double dfCenterLong )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetQSC", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetQSC(
|
|
dfCenterLat, dfCenterLong );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetAuthority() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the authority for a node.
|
|
*
|
|
* This method is the same as the C function OSRSetAuthority().
|
|
*
|
|
* @param pszTargetKey the partial or complete path to the node to
|
|
* set an authority on. ie. "PROJCS", "GEOGCS" or "GEOGCS|UNIT".
|
|
*
|
|
* @param pszAuthority authority name, such as "EPSG".
|
|
*
|
|
* @param nCode code for value with this authority.
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetAuthority( const char *pszTargetKey,
|
|
const char * pszAuthority,
|
|
int nCode )
|
|
|
|
{
|
|
/* -------------------------------------------------------------------- */
|
|
/* Find the node below which the authority should be put. */
|
|
/* -------------------------------------------------------------------- */
|
|
OGR_SRSNode *poNode = GetAttrNode( pszTargetKey );
|
|
|
|
if( poNode == NULL )
|
|
return OGRERR_FAILURE;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* If there is an existing AUTHORITY child blow it away before */
|
|
/* trying to set a new one. */
|
|
/* -------------------------------------------------------------------- */
|
|
int iOldChild = poNode->FindChild( "AUTHORITY" );
|
|
if( iOldChild != -1 )
|
|
poNode->DestroyChild( iOldChild );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Create a new authority node. */
|
|
/* -------------------------------------------------------------------- */
|
|
char szCode[32];
|
|
OGR_SRSNode *poAuthNode;
|
|
|
|
sprintf( szCode, "%d", nCode );
|
|
|
|
poAuthNode = new OGR_SRSNode( "AUTHORITY" );
|
|
poAuthNode->AddChild( new OGR_SRSNode( pszAuthority ) );
|
|
poAuthNode->AddChild( new OGR_SRSNode( szCode ) );
|
|
|
|
poNode->AddChild( poAuthNode );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetAuthority() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the authority for a node.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetAuthority().
|
|
*/
|
|
OGRErr OSRSetAuthority( OGRSpatialReferenceH hSRS,
|
|
const char *pszTargetKey,
|
|
const char * pszAuthority,
|
|
int nCode )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetAuthority", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetAuthority( pszTargetKey,
|
|
pszAuthority,
|
|
nCode );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetAuthorityCode() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Get the authority code for a node.
|
|
*
|
|
* This method is used to query an AUTHORITY[] node from within the
|
|
* WKT tree, and fetch the code value.
|
|
*
|
|
* While in theory values may be non-numeric, for the EPSG authority all
|
|
* code values should be integral.
|
|
*
|
|
* This method is the same as the C function OSRGetAuthorityCode().
|
|
*
|
|
* @param pszTargetKey the partial or complete path to the node to
|
|
* get an authority from. ie. "PROJCS", "GEOGCS", "GEOGCS|UNIT" or NULL to
|
|
* search for an authority node on the root element.
|
|
*
|
|
* @return value code from authority node, or NULL on failure. The value
|
|
* returned is internal and should not be freed or modified.
|
|
*/
|
|
|
|
const char *
|
|
OGRSpatialReference::GetAuthorityCode( const char *pszTargetKey ) const
|
|
|
|
{
|
|
/* -------------------------------------------------------------------- */
|
|
/* Find the node below which the authority should be put. */
|
|
/* -------------------------------------------------------------------- */
|
|
const OGR_SRSNode *poNode;
|
|
|
|
if( pszTargetKey == NULL )
|
|
poNode = poRoot;
|
|
else
|
|
poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
|
|
|
|
if( poNode == NULL )
|
|
return NULL;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Fetch AUTHORITY child if there is one. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( poNode->FindChild("AUTHORITY") == -1 )
|
|
return NULL;
|
|
|
|
poNode = poNode->GetChild(poNode->FindChild("AUTHORITY"));
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Create a new authority node. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( poNode->GetChildCount() < 2 )
|
|
return NULL;
|
|
|
|
return poNode->GetChild(1)->GetValue();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRGetAuthorityCode() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Get the authority code for a node.
|
|
*
|
|
* This function is the same as OGRSpatialReference::GetAuthorityCode().
|
|
*/
|
|
const char *OSRGetAuthorityCode( OGRSpatialReferenceH hSRS,
|
|
const char *pszTargetKey )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRGetAuthorityCode", NULL );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->GetAuthorityCode( pszTargetKey );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetAuthorityName() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Get the authority name for a node.
|
|
*
|
|
* This method is used to query an AUTHORITY[] node from within the
|
|
* WKT tree, and fetch the authority name value.
|
|
*
|
|
* The most common authority is "EPSG".
|
|
*
|
|
* This method is the same as the C function OSRGetAuthorityName().
|
|
*
|
|
* @param pszTargetKey the partial or complete path to the node to
|
|
* get an authority from. ie. "PROJCS", "GEOGCS", "GEOGCS|UNIT" or NULL to
|
|
* search for an authority node on the root element.
|
|
*
|
|
* @return value code from authority node, or NULL on failure. The value
|
|
* returned is internal and should not be freed or modified.
|
|
*/
|
|
|
|
const char *
|
|
OGRSpatialReference::GetAuthorityName( const char *pszTargetKey ) const
|
|
|
|
{
|
|
/* -------------------------------------------------------------------- */
|
|
/* Find the node below which the authority should be put. */
|
|
/* -------------------------------------------------------------------- */
|
|
const OGR_SRSNode *poNode;
|
|
|
|
if( pszTargetKey == NULL )
|
|
poNode = poRoot;
|
|
else
|
|
poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
|
|
|
|
if( poNode == NULL )
|
|
return NULL;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Fetch AUTHORITY child if there is one. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( poNode->FindChild("AUTHORITY") == -1 )
|
|
return NULL;
|
|
|
|
poNode = poNode->GetChild(poNode->FindChild("AUTHORITY"));
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Create a new authority node. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( poNode->GetChildCount() < 2 )
|
|
return NULL;
|
|
|
|
return poNode->GetChild(0)->GetValue();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRGetAuthorityName() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Get the authority name for a node.
|
|
*
|
|
* This function is the same as OGRSpatialReference::GetAuthorityName().
|
|
*/
|
|
const char *OSRGetAuthorityName( OGRSpatialReferenceH hSRS,
|
|
const char *pszTargetKey )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRGetAuthorityName", NULL );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->GetAuthorityName( pszTargetKey );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* StripVertical() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Convert a compound cs into a horizontal CS.
|
|
*
|
|
* If this SRS is of type COMPD_CS[] then the vertical CS and the root COMPD_CS
|
|
* nodes are stripped resulting and only the horizontal coordinate system
|
|
* portion remains (normally PROJCS, GEOGCS or LOCAL_CS).
|
|
*
|
|
* If this is not a compound coordinate system then nothing is changed.
|
|
*
|
|
* @since OGR 1.8.0
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::StripVertical()
|
|
|
|
{
|
|
if( GetRoot() == NULL
|
|
|| !EQUAL(GetRoot()->GetValue(),"COMPD_CS") )
|
|
return OGRERR_NONE;
|
|
|
|
OGR_SRSNode *poHorizontalCS = GetRoot()->GetChild( 1 );
|
|
if( poHorizontalCS != NULL )
|
|
poHorizontalCS = poHorizontalCS->Clone();
|
|
SetRoot( poHorizontalCS );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* StripCTParms() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Strip OGC CT Parameters.
|
|
*
|
|
* This method will remove all components of the coordinate system
|
|
* that are specific to the OGC CT Specification. That is it will attempt
|
|
* to strip it down to being compatible with the Simple Features 1.0
|
|
* specification.
|
|
*
|
|
* This method is the same as the C function OSRStripCTParms().
|
|
*
|
|
* @param poCurrent node to operate on. NULL to operate on whole tree.
|
|
*
|
|
* @return OGRERR_NONE on success or an error code.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::StripCTParms( OGR_SRSNode * poCurrent )
|
|
|
|
{
|
|
if( poCurrent == NULL )
|
|
{
|
|
StripVertical();
|
|
poCurrent = GetRoot();
|
|
}
|
|
|
|
if( poCurrent == NULL )
|
|
return OGRERR_NONE;
|
|
|
|
if( poCurrent == GetRoot() && EQUAL(poCurrent->GetValue(),"LOCAL_CS") )
|
|
{
|
|
delete poCurrent;
|
|
poRoot = NULL;
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
if( poCurrent == NULL )
|
|
return OGRERR_NONE;
|
|
|
|
poCurrent->StripNodes( "AUTHORITY" );
|
|
poCurrent->StripNodes( "TOWGS84" );
|
|
poCurrent->StripNodes( "AXIS" );
|
|
poCurrent->StripNodes( "EXTENSION" );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRStripCTParms() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Strip OGC CT Parameters.
|
|
*
|
|
* This function is the same as OGRSpatialReference::StripCTParms().
|
|
*/
|
|
OGRErr OSRStripCTParms( OGRSpatialReferenceH hSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRStripCTParms", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->StripCTParms( NULL );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* IsCompound() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Check if coordinate system is compound.
|
|
*
|
|
* This method is the same as the C function OSRIsCompound().
|
|
*
|
|
* @return TRUE if this is rooted with a COMPD_CS node.
|
|
*/
|
|
|
|
int OGRSpatialReference::IsCompound() const
|
|
|
|
{
|
|
if( poRoot == NULL )
|
|
return FALSE;
|
|
|
|
return EQUAL(poRoot->GetValue(),"COMPD_CS");
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRIsCompound() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Check if the coordinate system is compound.
|
|
*
|
|
* This function is the same as OGRSpatialReference::IsCompound().
|
|
*/
|
|
int OSRIsCompound( OGRSpatialReferenceH hSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRIsCompound", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->IsCompound();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* IsProjected() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Check if projected coordinate system.
|
|
*
|
|
* This method is the same as the C function OSRIsProjected().
|
|
*
|
|
* @return TRUE if this contains a PROJCS node indicating a it is a
|
|
* projected coordinate system.
|
|
*/
|
|
|
|
int OGRSpatialReference::IsProjected() const
|
|
|
|
{
|
|
if( poRoot == NULL )
|
|
return FALSE;
|
|
|
|
if( EQUAL(poRoot->GetValue(),"PROJCS") )
|
|
return TRUE;
|
|
else if( EQUAL(poRoot->GetValue(),"COMPD_CS") )
|
|
return GetAttrNode( "PROJCS" ) != NULL;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRIsProjected() */
|
|
/************************************************************************/
|
|
/**
|
|
* \brief Check if projected coordinate system.
|
|
*
|
|
* This function is the same as OGRSpatialReference::IsProjected().
|
|
*/
|
|
int OSRIsProjected( OGRSpatialReferenceH hSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRIsProjected", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->IsProjected();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* IsGeocentric() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Check if geocentric coordinate system.
|
|
*
|
|
* This method is the same as the C function OSRIsGeocentric().
|
|
*
|
|
* @return TRUE if this contains a GEOCCS node indicating a it is a
|
|
* geocentric coordinate system.
|
|
*
|
|
* @since OGR 1.9.0
|
|
*/
|
|
|
|
int OGRSpatialReference::IsGeocentric() const
|
|
|
|
{
|
|
if( poRoot == NULL )
|
|
return FALSE;
|
|
|
|
if( EQUAL(poRoot->GetValue(),"GEOCCS") )
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRIsGeocentric() */
|
|
/************************************************************************/
|
|
/**
|
|
* \brief Check if geocentric coordinate system.
|
|
*
|
|
* This function is the same as OGRSpatialReference::IsGeocentric().
|
|
*
|
|
* @since OGR 1.9.0
|
|
*/
|
|
int OSRIsGeocentric( OGRSpatialReferenceH hSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRIsGeocentric", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->IsGeocentric();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* IsGeographic() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Check if geographic coordinate system.
|
|
*
|
|
* This method is the same as the C function OSRIsGeographic().
|
|
*
|
|
* @return TRUE if this spatial reference is geographic ... that is the
|
|
* root is a GEOGCS node.
|
|
*/
|
|
|
|
int OGRSpatialReference::IsGeographic() const
|
|
|
|
{
|
|
if( GetRoot() == NULL )
|
|
return FALSE;
|
|
|
|
if( EQUAL(poRoot->GetValue(),"GEOGCS") )
|
|
return TRUE;
|
|
else if( EQUAL(poRoot->GetValue(),"COMPD_CS") )
|
|
return GetAttrNode( "GEOGCS" ) != NULL
|
|
&& GetAttrNode( "PROJCS" ) == NULL;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRIsGeographic() */
|
|
/************************************************************************/
|
|
/**
|
|
* \brief Check if geographic coordinate system.
|
|
*
|
|
* This function is the same as OGRSpatialReference::IsGeographic().
|
|
*/
|
|
int OSRIsGeographic( OGRSpatialReferenceH hSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRIsGeographic", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->IsGeographic();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* IsLocal() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Check if local coordinate system.
|
|
*
|
|
* This method is the same as the C function OSRIsLocal().
|
|
*
|
|
* @return TRUE if this spatial reference is local ... that is the
|
|
* root is a LOCAL_CS node.
|
|
*/
|
|
|
|
int OGRSpatialReference::IsLocal() const
|
|
|
|
{
|
|
if( GetRoot() == NULL )
|
|
return FALSE;
|
|
|
|
return EQUAL(GetRoot()->GetValue(),"LOCAL_CS");
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRIsLocal() */
|
|
/************************************************************************/
|
|
/**
|
|
* \brief Check if local coordinate system.
|
|
*
|
|
* This function is the same as OGRSpatialReference::IsLocal().
|
|
*/
|
|
int OSRIsLocal( OGRSpatialReferenceH hSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRIsLocal", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->IsLocal();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* IsVertical() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Check if vertical coordinate system.
|
|
*
|
|
* This method is the same as the C function OSRIsVertical().
|
|
*
|
|
* @return TRUE if this contains a VERT_CS node indicating a it is a
|
|
* vertical coordinate system.
|
|
*
|
|
* @since OGR 1.8.0
|
|
*/
|
|
|
|
int OGRSpatialReference::IsVertical() const
|
|
|
|
{
|
|
if( poRoot == NULL )
|
|
return FALSE;
|
|
|
|
if( EQUAL(poRoot->GetValue(),"VERT_CS") )
|
|
return TRUE;
|
|
else if( EQUAL(poRoot->GetValue(),"COMPD_CS") )
|
|
return GetAttrNode( "VERT_CS" ) != NULL;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRIsVertical() */
|
|
/************************************************************************/
|
|
/**
|
|
* \brief Check if vertical coordinate system.
|
|
*
|
|
* This function is the same as OGRSpatialReference::IsVertical().
|
|
*
|
|
* @since OGR 1.8.0
|
|
*/
|
|
int OSRIsVertical( OGRSpatialReferenceH hSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRIsVertical", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->IsVertical();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* CloneGeogCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Make a duplicate of the GEOGCS node of this OGRSpatialReference object.
|
|
*
|
|
* @return a new SRS, which becomes the responsibility of the caller.
|
|
*/
|
|
OGRSpatialReference *OGRSpatialReference::CloneGeogCS() const
|
|
|
|
{
|
|
const OGR_SRSNode *poGeogCS;
|
|
OGRSpatialReference * poNewSRS;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* We have to reconstruct the GEOGCS node for geocentric */
|
|
/* coordinate systems. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( IsGeocentric() )
|
|
{
|
|
const OGR_SRSNode *poDatum = GetAttrNode( "DATUM" );
|
|
const OGR_SRSNode *poPRIMEM = GetAttrNode( "PRIMEM" );
|
|
OGR_SRSNode *poGeogCS;
|
|
|
|
if( poDatum == NULL || poPRIMEM == NULL )
|
|
return NULL;
|
|
|
|
poGeogCS = new OGR_SRSNode( "GEOGCS" );
|
|
poGeogCS->AddChild( new OGR_SRSNode( "unnamed" ) );
|
|
poGeogCS->AddChild( poDatum->Clone() );
|
|
poGeogCS->AddChild( poPRIMEM->Clone() );
|
|
|
|
poNewSRS = new OGRSpatialReference();
|
|
poNewSRS->SetRoot( poGeogCS );
|
|
|
|
poNewSRS->SetAngularUnits( "degree", CPLAtof(SRS_UA_DEGREE_CONV) );
|
|
|
|
return poNewSRS;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* For all others we just search the tree, and duplicate. */
|
|
/* -------------------------------------------------------------------- */
|
|
poGeogCS = GetAttrNode( "GEOGCS" );
|
|
if( poGeogCS == NULL )
|
|
return NULL;
|
|
|
|
poNewSRS = new OGRSpatialReference();
|
|
poNewSRS->SetRoot( poGeogCS->Clone() );
|
|
|
|
return poNewSRS;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRCloneGeogCS() */
|
|
/************************************************************************/
|
|
/**
|
|
* \brief Make a duplicate of the GEOGCS node of this OGRSpatialReference object.
|
|
*
|
|
* This function is the same as OGRSpatialReference::CloneGeogCS().
|
|
*/
|
|
OGRSpatialReferenceH CPL_STDCALL OSRCloneGeogCS( OGRSpatialReferenceH hSource )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSource, "OSRCloneGeogCS", NULL );
|
|
|
|
return (OGRSpatialReferenceH)
|
|
((OGRSpatialReference *) hSource)->CloneGeogCS();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* IsSameGeogCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Do the GeogCS'es match?
|
|
*
|
|
* This method is the same as the C function OSRIsSameGeogCS().
|
|
*
|
|
* @param poOther the SRS being compared against.
|
|
*
|
|
* @return TRUE if they are the same or FALSE otherwise.
|
|
*/
|
|
|
|
int OGRSpatialReference::IsSameGeogCS( const OGRSpatialReference *poOther ) const
|
|
|
|
{
|
|
const char *pszThisValue, *pszOtherValue;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Does the datum name match? Note that we assume */
|
|
/* compatibility if either is missing a datum. */
|
|
/* -------------------------------------------------------------------- */
|
|
pszThisValue = this->GetAttrValue( "DATUM" );
|
|
pszOtherValue = poOther->GetAttrValue( "DATUM" );
|
|
|
|
if( pszThisValue != NULL && pszOtherValue != NULL
|
|
&& !EQUAL(pszThisValue,pszOtherValue) )
|
|
return FALSE;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Do the datum TOWGS84 values match if present? */
|
|
/* -------------------------------------------------------------------- */
|
|
double adfTOWGS84[7], adfOtherTOWGS84[7];
|
|
int i;
|
|
|
|
this->GetTOWGS84( adfTOWGS84, 7 );
|
|
poOther->GetTOWGS84( adfOtherTOWGS84, 7 );
|
|
|
|
for( i = 0; i < 7; i++ )
|
|
{
|
|
if( fabs(adfTOWGS84[i] - adfOtherTOWGS84[i]) > 0.00001 )
|
|
return FALSE;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Do the prime meridians match? If missing assume a value of zero.*/
|
|
/* -------------------------------------------------------------------- */
|
|
pszThisValue = this->GetAttrValue( "PRIMEM", 1 );
|
|
if( pszThisValue == NULL )
|
|
pszThisValue = "0.0";
|
|
|
|
pszOtherValue = poOther->GetAttrValue( "PRIMEM", 1 );
|
|
if( pszOtherValue == NULL )
|
|
pszOtherValue = "0.0";
|
|
|
|
if( CPLAtof(pszOtherValue) != CPLAtof(pszThisValue) )
|
|
return FALSE;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Do the units match? */
|
|
/* -------------------------------------------------------------------- */
|
|
pszThisValue = this->GetAttrValue( "GEOGCS|UNIT", 1 );
|
|
if( pszThisValue == NULL )
|
|
pszThisValue = SRS_UA_DEGREE_CONV;
|
|
|
|
pszOtherValue = poOther->GetAttrValue( "GEOGCS|UNIT", 1 );
|
|
if( pszOtherValue == NULL )
|
|
pszOtherValue = SRS_UA_DEGREE_CONV;
|
|
|
|
if( ABS(CPLAtof(pszOtherValue) - CPLAtof(pszThisValue)) > 0.00000001 )
|
|
return FALSE;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Does the spheroid match. Check semi major, and inverse */
|
|
/* flattening. */
|
|
/* -------------------------------------------------------------------- */
|
|
pszThisValue = this->GetAttrValue( "SPHEROID", 1 );
|
|
pszOtherValue = poOther->GetAttrValue( "SPHEROID", 1 );
|
|
if( pszThisValue != NULL && pszOtherValue != NULL
|
|
&& ABS(CPLAtof(pszThisValue) - CPLAtof(pszOtherValue)) > 0.01 )
|
|
return FALSE;
|
|
|
|
pszThisValue = this->GetAttrValue( "SPHEROID", 2 );
|
|
pszOtherValue = poOther->GetAttrValue( "SPHEROID", 2 );
|
|
if( pszThisValue != NULL && pszOtherValue != NULL
|
|
&& ABS(CPLAtof(pszThisValue) - CPLAtof(pszOtherValue)) > 0.0001 )
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRIsSameGeogCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Do the GeogCS'es match?
|
|
*
|
|
* This function is the same as OGRSpatialReference::IsSameGeogCS().
|
|
*/
|
|
int OSRIsSameGeogCS( OGRSpatialReferenceH hSRS1, OGRSpatialReferenceH hSRS2 )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS1, "OSRIsSameGeogCS", 0 );
|
|
VALIDATE_POINTER1( hSRS2, "OSRIsSameGeogCS", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS1)->IsSameGeogCS(
|
|
(OGRSpatialReference *) hSRS2 );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* IsSameVertCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Do the VertCS'es match?
|
|
*
|
|
* This method is the same as the C function OSRIsSameVertCS().
|
|
*
|
|
* @param poOther the SRS being compared against.
|
|
*
|
|
* @return TRUE if they are the same or FALSE otherwise.
|
|
*/
|
|
|
|
int OGRSpatialReference::IsSameVertCS( const OGRSpatialReference *poOther ) const
|
|
|
|
{
|
|
const char *pszThisValue, *pszOtherValue;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Does the datum name match? */
|
|
/* -------------------------------------------------------------------- */
|
|
pszThisValue = this->GetAttrValue( "VERT_DATUM" );
|
|
pszOtherValue = poOther->GetAttrValue( "VERT_DATUM" );
|
|
|
|
if( pszThisValue == NULL || pszOtherValue == NULL
|
|
|| !EQUAL(pszThisValue, pszOtherValue) )
|
|
return FALSE;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Do the units match? */
|
|
/* -------------------------------------------------------------------- */
|
|
pszThisValue = this->GetAttrValue( "VERT_CS|UNIT", 1 );
|
|
if( pszThisValue == NULL )
|
|
pszThisValue = "1.0";
|
|
|
|
pszOtherValue = poOther->GetAttrValue( "VERT_CS|UNIT", 1 );
|
|
if( pszOtherValue == NULL )
|
|
pszOtherValue = "1.0";
|
|
|
|
if( ABS(CPLAtof(pszOtherValue) - CPLAtof(pszThisValue)) > 0.00000001 )
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRIsSameVertCS() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Do the VertCS'es match?
|
|
*
|
|
* This function is the same as OGRSpatialReference::IsSameVertCS().
|
|
*/
|
|
int OSRIsSameVertCS( OGRSpatialReferenceH hSRS1, OGRSpatialReferenceH hSRS2 )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS1, "OSRIsSameVertCS", 0 );
|
|
VALIDATE_POINTER1( hSRS2, "OSRIsSameVertCS", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS1)->IsSameVertCS(
|
|
(OGRSpatialReference *) hSRS2 );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* IsSame() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Do these two spatial references describe the same system ?
|
|
*
|
|
* @param poOtherSRS the SRS being compared to.
|
|
*
|
|
* @return TRUE if equivalent or FALSE otherwise.
|
|
*/
|
|
|
|
int OGRSpatialReference::IsSame( const OGRSpatialReference * poOtherSRS ) const
|
|
|
|
{
|
|
if( GetRoot() == NULL && poOtherSRS->GetRoot() == NULL )
|
|
return TRUE;
|
|
else if( GetRoot() == NULL || poOtherSRS->GetRoot() == NULL )
|
|
return FALSE;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Compare geographic coordinate system. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( !IsSameGeogCS( poOtherSRS ) )
|
|
return FALSE;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Do the have the same root types? Ie. is one PROJCS and one */
|
|
/* GEOGCS or perhaps LOCALCS? */
|
|
/* -------------------------------------------------------------------- */
|
|
if( !EQUAL(GetRoot()->GetValue(),poOtherSRS->GetRoot()->GetValue()) )
|
|
return FALSE;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Compare projected coordinate system. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( IsProjected() )
|
|
{
|
|
const char *pszValue1, *pszValue2;
|
|
const OGR_SRSNode *poPROJCS = GetAttrNode( "PROJCS" );
|
|
|
|
pszValue1 = this->GetAttrValue( "PROJECTION" );
|
|
pszValue2 = poOtherSRS->GetAttrValue( "PROJECTION" );
|
|
if( pszValue1 == NULL || pszValue2 == NULL
|
|
|| !EQUAL(pszValue1,pszValue2) )
|
|
return FALSE;
|
|
|
|
for( int iChild = 0; iChild < poPROJCS->GetChildCount(); iChild++ )
|
|
{
|
|
const OGR_SRSNode *poNode;
|
|
|
|
poNode = poPROJCS->GetChild( iChild );
|
|
if( !EQUAL(poNode->GetValue(),"PARAMETER")
|
|
|| poNode->GetChildCount() != 2 )
|
|
continue;
|
|
|
|
/* this this eventually test within some epsilon? */
|
|
if( this->GetProjParm( poNode->GetChild(0)->GetValue() )
|
|
!= poOtherSRS->GetProjParm( poNode->GetChild(0)->GetValue() ) )
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* If they are LOCALCS/PROJCS, do they have the same units? */
|
|
/* -------------------------------------------------------------------- */
|
|
if( IsLocal() || IsProjected() )
|
|
{
|
|
if( GetLinearUnits() != 0.0 )
|
|
{
|
|
double dfRatio;
|
|
|
|
dfRatio = poOtherSRS->GetLinearUnits() / GetLinearUnits();
|
|
if( dfRatio < 0.9999999999 || dfRatio > 1.000000001 )
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Compare vertical coordinate system. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( IsVertical() && !IsSameVertCS( poOtherSRS ) )
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRIsSame() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Do these two spatial references describe the same system ?
|
|
*
|
|
* This function is the same as OGRSpatialReference::IsSame().
|
|
*/
|
|
int OSRIsSame( OGRSpatialReferenceH hSRS1, OGRSpatialReferenceH hSRS2 )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS1, "OSRIsSame", 0 );
|
|
VALIDATE_POINTER1( hSRS2, "OSRIsSame", 0 );
|
|
|
|
return ((OGRSpatialReference *) hSRS1)->IsSame(
|
|
(OGRSpatialReference *) hSRS2 );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetTOWGS84() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the Bursa-Wolf conversion to WGS84.
|
|
*
|
|
* This will create the TOWGS84 node as a child of the DATUM. It will fail
|
|
* if there is no existing DATUM node. Unlike most OGRSpatialReference
|
|
* methods it will insert itself in the appropriate order, and will replace
|
|
* an existing TOWGS84 node if there is one.
|
|
*
|
|
* The parameters have the same meaning as EPSG transformation 9606
|
|
* (Position Vector 7-param. transformation).
|
|
*
|
|
* This method is the same as the C function OSRSetTOWGS84().
|
|
*
|
|
* @param dfDX X child in meters.
|
|
* @param dfDY Y child in meters.
|
|
* @param dfDZ Z child in meters.
|
|
* @param dfEX X rotation in arc seconds (optional, defaults to zero).
|
|
* @param dfEY Y rotation in arc seconds (optional, defaults to zero).
|
|
* @param dfEZ Z rotation in arc seconds (optional, defaults to zero).
|
|
* @param dfPPM scaling factor (parts per million).
|
|
*
|
|
* @return OGRERR_NONE on success.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetTOWGS84( double dfDX, double dfDY, double dfDZ,
|
|
double dfEX, double dfEY, double dfEZ,
|
|
double dfPPM )
|
|
|
|
{
|
|
OGR_SRSNode *poDatum, *poTOWGS84;
|
|
int iPosition;
|
|
char szValue[64];
|
|
|
|
poDatum = GetAttrNode( "DATUM" );
|
|
if( poDatum == NULL )
|
|
return OGRERR_FAILURE;
|
|
|
|
if( poDatum->FindChild( "TOWGS84" ) != -1 )
|
|
poDatum->DestroyChild( poDatum->FindChild( "TOWGS84" ) );
|
|
|
|
iPosition = poDatum->GetChildCount();
|
|
if( poDatum->FindChild("AUTHORITY") != -1 )
|
|
{
|
|
iPosition = poDatum->FindChild("AUTHORITY");
|
|
}
|
|
|
|
poTOWGS84 = new OGR_SRSNode("TOWGS84");
|
|
|
|
OGRPrintDouble( szValue, dfDX );
|
|
poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
|
|
|
|
OGRPrintDouble( szValue, dfDY );
|
|
poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
|
|
|
|
OGRPrintDouble( szValue, dfDZ );
|
|
poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
|
|
|
|
OGRPrintDouble( szValue, dfEX );
|
|
poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
|
|
|
|
OGRPrintDouble( szValue, dfEY );
|
|
poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
|
|
|
|
OGRPrintDouble( szValue, dfEZ );
|
|
poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
|
|
|
|
OGRPrintDouble( szValue, dfPPM );
|
|
poTOWGS84->AddChild( new OGR_SRSNode( szValue ) );
|
|
|
|
poDatum->InsertChild( poTOWGS84, iPosition );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetTOWGS84() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the Bursa-Wolf conversion to WGS84.
|
|
*
|
|
* This function is the same as OGRSpatialReference::SetTOWGS84().
|
|
*/
|
|
OGRErr OSRSetTOWGS84( OGRSpatialReferenceH hSRS,
|
|
double dfDX, double dfDY, double dfDZ,
|
|
double dfEX, double dfEY, double dfEZ,
|
|
double dfPPM )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetTOWGS84", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetTOWGS84( dfDX, dfDY, dfDZ,
|
|
dfEX, dfEY, dfEZ,
|
|
dfPPM );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetTOWGS84() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch TOWGS84 parameters, if available.
|
|
*
|
|
* @param padfCoeff array into which up to 7 coefficients are placed.
|
|
* @param nCoeffCount size of padfCoeff - defaults to 7.
|
|
*
|
|
* @return OGRERR_NONE on success, or OGRERR_FAILURE if there is no
|
|
* TOWGS84 node available.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::GetTOWGS84( double * padfCoeff,
|
|
int nCoeffCount ) const
|
|
|
|
{
|
|
const OGR_SRSNode *poNode = GetAttrNode( "TOWGS84" );
|
|
|
|
memset( padfCoeff, 0, sizeof(double) * nCoeffCount );
|
|
|
|
if( poNode == NULL )
|
|
return OGRERR_FAILURE;
|
|
|
|
for( int i = 0; i < nCoeffCount && i < poNode->GetChildCount(); i++ )
|
|
{
|
|
padfCoeff[i] = CPLAtof(poNode->GetChild(i)->GetValue());
|
|
}
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRGetTOWGS84() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch TOWGS84 parameters, if available.
|
|
*
|
|
* This function is the same as OGRSpatialReference::GetTOWGS84().
|
|
*/
|
|
OGRErr OSRGetTOWGS84( OGRSpatialReferenceH hSRS,
|
|
double * padfCoeff, int nCoeffCount )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRGetTOWGS84", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->GetTOWGS84( padfCoeff, nCoeffCount);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* IsAngularParameter() */
|
|
/* */
|
|
/* Is the passed projection parameter an angular one? */
|
|
/************************************************************************/
|
|
|
|
int OGRSpatialReference::IsAngularParameter( const char *pszParameterName )
|
|
|
|
{
|
|
if( EQUALN(pszParameterName,"long",4)
|
|
|| EQUALN(pszParameterName,"lati",4)
|
|
|| EQUAL(pszParameterName,SRS_PP_CENTRAL_MERIDIAN)
|
|
|| EQUALN(pszParameterName,"standard_parallel",17)
|
|
|| EQUAL(pszParameterName,SRS_PP_AZIMUTH)
|
|
|| EQUAL(pszParameterName,SRS_PP_RECTIFIED_GRID_ANGLE) )
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* IsLongitudeParameter() */
|
|
/* */
|
|
/* Is the passed projection parameter an angular longitude */
|
|
/* (relative to a prime meridian)? */
|
|
/************************************************************************/
|
|
|
|
int OGRSpatialReference::IsLongitudeParameter( const char *pszParameterName )
|
|
|
|
{
|
|
if( EQUALN(pszParameterName,"long",4)
|
|
|| EQUAL(pszParameterName,SRS_PP_CENTRAL_MERIDIAN) )
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* IsLinearParameter() */
|
|
/* */
|
|
/* Is the passed projection parameter an linear one measured in */
|
|
/* meters or some similar linear measure. */
|
|
/************************************************************************/
|
|
|
|
int OGRSpatialReference::IsLinearParameter( const char *pszParameterName )
|
|
|
|
{
|
|
if( EQUALN(pszParameterName,"false_",6)
|
|
|| EQUAL(pszParameterName,SRS_PP_SATELLITE_HEIGHT) )
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetNormInfo() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the internal information for normalizing linear, and angular values.
|
|
*/
|
|
void OGRSpatialReference::GetNormInfo(void) const
|
|
|
|
{
|
|
if( bNormInfoSet )
|
|
return;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Initialize values. */
|
|
/* -------------------------------------------------------------------- */
|
|
OGRSpatialReference *poThis = (OGRSpatialReference *) this;
|
|
|
|
poThis->bNormInfoSet = TRUE;
|
|
|
|
poThis->dfFromGreenwich = GetPrimeMeridian(NULL);
|
|
poThis->dfToMeter = GetLinearUnits(NULL);
|
|
poThis->dfToDegrees = GetAngularUnits(NULL) / CPLAtof(SRS_UA_DEGREE_CONV);
|
|
if( fabs(poThis->dfToDegrees-1.0) < 0.000000001 )
|
|
poThis->dfToDegrees = 1.0;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* FixupOrdering() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Correct parameter ordering to match CT Specification.
|
|
*
|
|
* Some mechanisms to create WKT using OGRSpatialReference, and some
|
|
* imported WKT fail to maintain the order of parameters required according
|
|
* to the BNF definitions in the OpenGIS SF-SQL and CT Specifications. This
|
|
* method attempts to massage things back into the required order.
|
|
*
|
|
* This method is the same as the C function OSRFixupOrdering().
|
|
*
|
|
* @return OGRERR_NONE on success or an error code if something goes
|
|
* wrong.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::FixupOrdering()
|
|
|
|
{
|
|
if( GetRoot() != NULL )
|
|
return GetRoot()->FixupOrdering();
|
|
else
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRFixupOrdering() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Correct parameter ordering to match CT Specification.
|
|
*
|
|
* This function is the same as OGRSpatialReference::FixupOrdering().
|
|
*/
|
|
OGRErr OSRFixupOrdering( OGRSpatialReferenceH hSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRFixupOrdering", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->FixupOrdering();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* Fixup() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fixup as needed.
|
|
*
|
|
* Some mechanisms to create WKT using OGRSpatialReference, and some
|
|
* imported WKT, are not valid according to the OGC CT specification. This
|
|
* method attempts to fill in any missing defaults that are required, and
|
|
* fixup ordering problems (using OSRFixupOrdering()) so that the resulting
|
|
* WKT is valid.
|
|
*
|
|
* This method should be expected to evolve over time to as problems are
|
|
* discovered. The following are amoung the fixup actions this method will
|
|
* take:
|
|
*
|
|
* - Fixup the ordering of nodes to match the BNF WKT ordering, using
|
|
* the FixupOrdering() method.
|
|
*
|
|
* - Add missing linear or angular units nodes.
|
|
*
|
|
* This method is the same as the C function OSRFixup().
|
|
*
|
|
* @return OGRERR_NONE on success or an error code if something goes
|
|
* wrong.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::Fixup()
|
|
|
|
{
|
|
/* -------------------------------------------------------------------- */
|
|
/* Ensure linear units defaulted to METER if missing for PROJCS, */
|
|
/* GEOCCS or LOCAL_CS. */
|
|
/* -------------------------------------------------------------------- */
|
|
const OGR_SRSNode *poCS = GetAttrNode( "PROJCS" );
|
|
|
|
if( poCS == NULL )
|
|
poCS = GetAttrNode( "LOCAL_CS" );
|
|
|
|
if( poCS == NULL )
|
|
poCS = GetAttrNode( "GEOCCS" );
|
|
|
|
if( poCS != NULL && poCS->FindChild( "UNIT" ) == -1 )
|
|
SetLinearUnits( SRS_UL_METER, 1.0 );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Ensure angular units defaulted to degrees on the GEOGCS. */
|
|
/* -------------------------------------------------------------------- */
|
|
poCS = GetAttrNode( "GEOGCS" );
|
|
if( poCS != NULL && poCS->FindChild( "UNIT" ) == -1 )
|
|
SetAngularUnits( SRS_UA_DEGREE, CPLAtof(SRS_UA_DEGREE_CONV) );
|
|
|
|
return FixupOrdering();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRFixup() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fixup as needed.
|
|
*
|
|
* This function is the same as OGRSpatialReference::Fixup().
|
|
*/
|
|
OGRErr OSRFixup( OGRSpatialReferenceH hSRS )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRFixup", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->Fixup();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetExtension() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch extension value.
|
|
*
|
|
* Fetch the value of the named EXTENSION item for the identified
|
|
* target node.
|
|
*
|
|
* @param pszTargetKey the name or path to the parent node of the EXTENSION.
|
|
* @param pszName the name of the extension being fetched.
|
|
* @param pszDefault the value to return if the extension is not found.
|
|
*
|
|
* @return node value if successful or pszDefault on failure.
|
|
*/
|
|
|
|
const char *OGRSpatialReference::GetExtension( const char *pszTargetKey,
|
|
const char *pszName,
|
|
const char *pszDefault ) const
|
|
|
|
{
|
|
/* -------------------------------------------------------------------- */
|
|
/* Find the target node. */
|
|
/* -------------------------------------------------------------------- */
|
|
const OGR_SRSNode *poNode;
|
|
|
|
if( pszTargetKey == NULL )
|
|
poNode = poRoot;
|
|
else
|
|
poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
|
|
|
|
if( poNode == NULL )
|
|
return NULL;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Fetch matching EXTENSION if there is one. */
|
|
/* -------------------------------------------------------------------- */
|
|
for( int i = poNode->GetChildCount()-1; i >= 0; i-- )
|
|
{
|
|
const OGR_SRSNode *poChild = poNode->GetChild(i);
|
|
|
|
if( EQUAL(poChild->GetValue(),"EXTENSION")
|
|
&& poChild->GetChildCount() >= 2 )
|
|
{
|
|
if( EQUAL(poChild->GetChild(0)->GetValue(),pszName) )
|
|
return poChild->GetChild(1)->GetValue();
|
|
}
|
|
}
|
|
|
|
return pszDefault;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetExtension() */
|
|
/************************************************************************/
|
|
/**
|
|
* \brief Set extension value.
|
|
*
|
|
* Set the value of the named EXTENSION item for the identified
|
|
* target node.
|
|
*
|
|
* @param pszTargetKey the name or path to the parent node of the EXTENSION.
|
|
* @param pszName the name of the extension being fetched.
|
|
* @param pszValue the value to set
|
|
*
|
|
* @return OGRERR_NONE on success
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::SetExtension( const char *pszTargetKey,
|
|
const char *pszName,
|
|
const char *pszValue )
|
|
|
|
{
|
|
/* -------------------------------------------------------------------- */
|
|
/* Find the target node. */
|
|
/* -------------------------------------------------------------------- */
|
|
OGR_SRSNode *poNode;
|
|
|
|
if( pszTargetKey == NULL )
|
|
poNode = poRoot;
|
|
else
|
|
poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
|
|
|
|
if( poNode == NULL )
|
|
return OGRERR_FAILURE;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Fetch matching EXTENSION if there is one. */
|
|
/* -------------------------------------------------------------------- */
|
|
for( int i = poNode->GetChildCount()-1; i >= 0; i-- )
|
|
{
|
|
OGR_SRSNode *poChild = poNode->GetChild(i);
|
|
|
|
if( EQUAL(poChild->GetValue(),"EXTENSION")
|
|
&& poChild->GetChildCount() >= 2 )
|
|
{
|
|
if( EQUAL(poChild->GetChild(0)->GetValue(),pszName) )
|
|
{
|
|
poChild->GetChild(1)->SetValue( pszValue );
|
|
return OGRERR_NONE;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Create a new EXTENSION node. */
|
|
/* -------------------------------------------------------------------- */
|
|
OGR_SRSNode *poAuthNode;
|
|
|
|
poAuthNode = new OGR_SRSNode( "EXTENSION" );
|
|
poAuthNode->AddChild( new OGR_SRSNode( pszName ) );
|
|
poAuthNode->AddChild( new OGR_SRSNode( pszValue ) );
|
|
|
|
poNode->AddChild( poAuthNode );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRCleanup() */
|
|
/************************************************************************/
|
|
|
|
CPL_C_START
|
|
void CleanupESRIDatumMappingTable();
|
|
CPL_C_END
|
|
static void CleanupSRSWGS84Thread();
|
|
|
|
/**
|
|
* \brief Cleanup cached SRS related memory.
|
|
*
|
|
* This function will attempt to cleanup any cache spatial reference
|
|
* related information, such as cached tables of coordinate systems.
|
|
*/
|
|
void OSRCleanup( void )
|
|
|
|
{
|
|
CleanupESRIDatumMappingTable();
|
|
CSVDeaccess( NULL );
|
|
OCTCleanupProjMutex();
|
|
CleanupSRSWGS84Thread();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetAxis() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch the orientation of one axis.
|
|
*
|
|
* Fetches the the request axis (iAxis - zero based) from the
|
|
* indicated portion of the coordinate system (pszTargetKey) which
|
|
* should be either "GEOGCS" or "PROJCS".
|
|
*
|
|
* No CPLError is issued on routine failures (such as not finding the AXIS).
|
|
*
|
|
* This method is equivalent to the C function OSRGetAxis().
|
|
*
|
|
* @param pszTargetKey the coordinate system part to query ("PROJCS" or "GEOGCS").
|
|
* @param iAxis the axis to query (0 for first, 1 for second).
|
|
* @param peOrientation location into which to place the fetch orientation, may be NULL.
|
|
*
|
|
* @return the name of the axis or NULL on failure.
|
|
*/
|
|
|
|
const char *
|
|
OGRSpatialReference::GetAxis( const char *pszTargetKey, int iAxis,
|
|
OGRAxisOrientation *peOrientation ) const
|
|
|
|
{
|
|
if( peOrientation != NULL )
|
|
*peOrientation = OAO_Other;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Find the target node. */
|
|
/* -------------------------------------------------------------------- */
|
|
OGR_SRSNode *poNode;
|
|
|
|
if( pszTargetKey == NULL )
|
|
poNode = poRoot;
|
|
else
|
|
poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
|
|
|
|
if( poNode == NULL )
|
|
return NULL;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Find desired child AXIS. */
|
|
/* -------------------------------------------------------------------- */
|
|
OGR_SRSNode *poAxis = NULL;
|
|
int iChild, nChildCount = poNode->GetChildCount();
|
|
|
|
for( iChild = 0; iChild < nChildCount; iChild++ )
|
|
{
|
|
OGR_SRSNode *poChild = poNode->GetChild( iChild );
|
|
|
|
if( !EQUAL(poChild->GetValue(),"AXIS") )
|
|
continue;
|
|
|
|
if( iAxis == 0 )
|
|
{
|
|
poAxis = poChild;
|
|
break;
|
|
}
|
|
iAxis--;
|
|
}
|
|
|
|
if( poAxis == NULL )
|
|
return NULL;
|
|
|
|
if( poAxis->GetChildCount() < 2 )
|
|
return NULL;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Extract name and orientation if possible. */
|
|
/* -------------------------------------------------------------------- */
|
|
if( peOrientation != NULL )
|
|
{
|
|
const char *pszOrientation = poAxis->GetChild(1)->GetValue();
|
|
|
|
if( EQUAL(pszOrientation,"NORTH") )
|
|
*peOrientation = OAO_North;
|
|
else if( EQUAL(pszOrientation,"EAST") )
|
|
*peOrientation = OAO_East;
|
|
else if( EQUAL(pszOrientation,"SOUTH") )
|
|
*peOrientation = OAO_South;
|
|
else if( EQUAL(pszOrientation,"WEST") )
|
|
*peOrientation = OAO_West;
|
|
else if( EQUAL(pszOrientation,"UP") )
|
|
*peOrientation = OAO_Up;
|
|
else if( EQUAL(pszOrientation,"DOWN") )
|
|
*peOrientation = OAO_Down;
|
|
else if( EQUAL(pszOrientation,"OTHER") )
|
|
*peOrientation = OAO_Other;
|
|
else
|
|
{
|
|
CPLDebug( "OSR", "Unrecognised orientation value '%s'.",
|
|
pszOrientation );
|
|
}
|
|
}
|
|
|
|
return poAxis->GetChild(0)->GetValue();
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRGetAxis() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Fetch the orientation of one axis.
|
|
*
|
|
* This method is the equivalent of the C++ method OGRSpatialReference::GetAxis
|
|
*/
|
|
const char *OSRGetAxis( OGRSpatialReferenceH hSRS,
|
|
const char *pszTargetKey, int iAxis,
|
|
OGRAxisOrientation *peOrientation )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRGetAxis", NULL );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->GetAxis( pszTargetKey, iAxis,
|
|
peOrientation );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRAxisEnumToName() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Return the string representation for the OGRAxisOrientation enumeration.
|
|
*
|
|
* For example "NORTH" for OAO_North.
|
|
*
|
|
* @return an internal string
|
|
*/
|
|
const char *OSRAxisEnumToName( OGRAxisOrientation eOrientation )
|
|
|
|
{
|
|
if( eOrientation == OAO_North )
|
|
return "NORTH";
|
|
if( eOrientation == OAO_East )
|
|
return "EAST";
|
|
if( eOrientation == OAO_South )
|
|
return "SOUTH";
|
|
if( eOrientation == OAO_West )
|
|
return "WEST";
|
|
if( eOrientation == OAO_Up )
|
|
return "UP";
|
|
if( eOrientation == OAO_Down )
|
|
return "DOWN";
|
|
if( eOrientation == OAO_Other )
|
|
return "OTHER";
|
|
|
|
return "UNKNOWN";
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* SetAxes() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Set the axes for a coordinate system.
|
|
*
|
|
* Set the names, and orientations of the axes for either a projected
|
|
* (PROJCS) or geographic (GEOGCS) coordinate system.
|
|
*
|
|
* This method is equivalent to the C function OSRSetAxes().
|
|
*
|
|
* @param pszTargetKey either "PROJCS" or "GEOGCS", must already exist in SRS.
|
|
* @param pszXAxisName name of first axis, normally "Long" or "Easting".
|
|
* @param eXAxisOrientation normally OAO_East.
|
|
* @param pszYAxisName name of second axis, normally "Lat" or "Northing".
|
|
* @param eYAxisOrientation normally OAO_North.
|
|
*
|
|
* @return OGRERR_NONE on success or an error code.
|
|
*/
|
|
|
|
OGRErr
|
|
OGRSpatialReference::SetAxes( const char *pszTargetKey,
|
|
const char *pszXAxisName,
|
|
OGRAxisOrientation eXAxisOrientation,
|
|
const char *pszYAxisName,
|
|
OGRAxisOrientation eYAxisOrientation )
|
|
|
|
{
|
|
/* -------------------------------------------------------------------- */
|
|
/* Find the target node. */
|
|
/* -------------------------------------------------------------------- */
|
|
OGR_SRSNode *poNode;
|
|
|
|
if( pszTargetKey == NULL )
|
|
poNode = poRoot;
|
|
else
|
|
poNode= ((OGRSpatialReference *) this)->GetAttrNode( pszTargetKey );
|
|
|
|
if( poNode == NULL )
|
|
return OGRERR_FAILURE;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Strip any existing AXIS children. */
|
|
/* -------------------------------------------------------------------- */
|
|
while( poNode->FindChild( "AXIS" ) >= 0 )
|
|
poNode->DestroyChild( poNode->FindChild( "AXIS" ) );
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/* Insert desired axes */
|
|
/* -------------------------------------------------------------------- */
|
|
OGR_SRSNode *poAxis = new OGR_SRSNode( "AXIS" );
|
|
|
|
poAxis->AddChild( new OGR_SRSNode( pszXAxisName ) );
|
|
poAxis->AddChild( new OGR_SRSNode( OSRAxisEnumToName(eXAxisOrientation) ));
|
|
|
|
poNode->AddChild( poAxis );
|
|
|
|
poAxis = new OGR_SRSNode( "AXIS" );
|
|
|
|
poAxis->AddChild( new OGR_SRSNode( pszYAxisName ) );
|
|
poAxis->AddChild( new OGR_SRSNode( OSRAxisEnumToName(eYAxisOrientation) ));
|
|
|
|
poNode->AddChild( poAxis );
|
|
|
|
return OGRERR_NONE;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRSetAxes() */
|
|
/************************************************************************/
|
|
/**
|
|
* \brief Set the axes for a coordinate system.
|
|
*
|
|
* This method is the equivalent of the C++ method OGRSpatialReference::SetAxes
|
|
*/
|
|
OGRErr OSRSetAxes( OGRSpatialReferenceH hSRS,
|
|
const char *pszTargetKey,
|
|
const char *pszXAxisName,
|
|
OGRAxisOrientation eXAxisOrientation,
|
|
const char *pszYAxisName,
|
|
OGRAxisOrientation eYAxisOrientation )
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRSetAxes", OGRERR_FAILURE );
|
|
|
|
return ((OGRSpatialReference *) hSRS)->SetAxes( pszTargetKey,
|
|
pszXAxisName,
|
|
eXAxisOrientation,
|
|
pszYAxisName,
|
|
eYAxisOrientation );
|
|
}
|
|
|
|
#ifdef HAVE_MITAB
|
|
char CPL_DLL *MITABSpatialRef2CoordSys( OGRSpatialReference * );
|
|
OGRSpatialReference CPL_DLL * MITABCoordSys2SpatialRef( const char * );
|
|
#endif
|
|
|
|
/************************************************************************/
|
|
/* OSRExportToMICoordSys() */
|
|
/************************************************************************/
|
|
/**
|
|
* \brief Export coordinate system in Mapinfo style CoordSys format.
|
|
*
|
|
* This method is the equivalent of the C++ method OGRSpatialReference::exportToMICoordSys
|
|
*/
|
|
OGRErr OSRExportToMICoordSys( OGRSpatialReferenceH hSRS, char ** ppszReturn )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRExportToMICoordSys", CE_Failure );
|
|
|
|
*ppszReturn = NULL;
|
|
|
|
return ((OGRSpatialReference *) hSRS)->exportToMICoordSys( ppszReturn );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* exportToMICoordSys() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Export coordinate system in Mapinfo style CoordSys format.
|
|
*
|
|
* Note that the returned WKT string should be freed with OGRFree() or
|
|
* CPLFree() when no longer needed. It is the responsibility of the caller.
|
|
*
|
|
* This method is the same as the C function OSRExportToMICoordSys().
|
|
*
|
|
* @param ppszResult pointer to which dynamically allocated Mapinfo CoordSys
|
|
* definition will be assigned.
|
|
*
|
|
* @return OGRERR_NONE on success, OGRERR_FAILURE on failure,
|
|
* OGRERR_UNSUPPORTED_OPERATION if MITAB library was not linked in.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::exportToMICoordSys( char **ppszResult ) const
|
|
|
|
{
|
|
#ifdef HAVE_MITAB
|
|
*ppszResult = MITABSpatialRef2CoordSys( (OGRSpatialReference *) this );
|
|
if( *ppszResult != NULL && strlen(*ppszResult) > 0 )
|
|
return OGRERR_NONE;
|
|
else
|
|
return OGRERR_FAILURE;
|
|
#else
|
|
CPLError( CE_Failure, CPLE_NotSupported,
|
|
"MITAB not available, CoordSys support disabled." );
|
|
|
|
return OGRERR_UNSUPPORTED_OPERATION;
|
|
#endif
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRImportFromMICoordSys() */
|
|
/************************************************************************/
|
|
/**
|
|
* \brief Import Mapinfo style CoordSys definition.
|
|
*
|
|
* This method is the equivalent of the C++ method OGRSpatialReference::importFromMICoordSys
|
|
*/
|
|
|
|
OGRErr OSRImportFromMICoordSys( OGRSpatialReferenceH hSRS,
|
|
const char *pszCoordSys )
|
|
|
|
{
|
|
VALIDATE_POINTER1( hSRS, "OSRImportFromMICoordSys", CE_Failure );
|
|
|
|
return ((OGRSpatialReference *)hSRS)->importFromMICoordSys( pszCoordSys );
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* importFromMICoordSys() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Import Mapinfo style CoordSys definition.
|
|
*
|
|
* The OGRSpatialReference is initialized from the passed Mapinfo style CoordSys definition string.
|
|
*
|
|
* This method is the equivalent of the C function OSRImportFromMICoordSys().
|
|
*
|
|
* @param pszCoordSys Mapinfo style CoordSys definition string.
|
|
*
|
|
* @return OGRERR_NONE on success, OGRERR_FAILURE on failure,
|
|
* OGRERR_UNSUPPORTED_OPERATION if MITAB library was not linked in.
|
|
*/
|
|
|
|
OGRErr OGRSpatialReference::importFromMICoordSys( const char *pszCoordSys )
|
|
|
|
{
|
|
#ifdef HAVE_MITAB
|
|
OGRSpatialReference *poResult = MITABCoordSys2SpatialRef( pszCoordSys );
|
|
|
|
if( poResult == NULL )
|
|
return OGRERR_FAILURE;
|
|
|
|
*this = *poResult;
|
|
delete poResult;
|
|
|
|
return OGRERR_NONE;
|
|
#else
|
|
CPLError( CE_Failure, CPLE_NotSupported,
|
|
"MITAB not available, CoordSys support disabled." );
|
|
|
|
return OGRERR_UNSUPPORTED_OPERATION;
|
|
#endif
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRCalcInvFlattening() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Compute inverse flattening from semi-major and semi-minor axis
|
|
*
|
|
* @param dfSemiMajor Semi-major axis length.
|
|
* @param dfSemiMinor Semi-minor axis length.
|
|
*
|
|
* @return inverse flattening, or 0 if both axis are equal.
|
|
* @since GDAL 2.0
|
|
*/
|
|
|
|
double OSRCalcInvFlattening( double dfSemiMajor, double dfSemiMinor )
|
|
{
|
|
if( fabs(dfSemiMajor-dfSemiMinor) < 1e-1 )
|
|
return 0;
|
|
else if( dfSemiMajor <= 0 || dfSemiMinor <= 0 || dfSemiMinor > dfSemiMajor )
|
|
{
|
|
CPLError(CE_Failure, CPLE_IllegalArg,
|
|
"OSRCalcInvFlattening(): Wrong input values");
|
|
return 0;
|
|
}
|
|
else
|
|
return dfSemiMajor / (dfSemiMajor - dfSemiMinor);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* OSRCalcInvFlattening() */
|
|
/************************************************************************/
|
|
|
|
/**
|
|
* \brief Compute semi-minor axis from semi-major axis and inverse flattening.
|
|
*
|
|
* @param dfSemiMajor Semi-major axis length.
|
|
* @param dfInvFlattening Inverse flattening or 0 for sphere.
|
|
*
|
|
* @return semi-minor axis
|
|
* @since GDAL 2.0
|
|
*/
|
|
|
|
double OSRCalcSemiMinorFromInvFlattening( double dfSemiMajor, double dfInvFlattening )
|
|
{
|
|
if( fabs(dfInvFlattening) < 0.000000000001 )
|
|
return dfSemiMajor;
|
|
else if( dfSemiMajor <= 0.0 || dfInvFlattening <= 1.0 )
|
|
{
|
|
CPLError(CE_Failure, CPLE_IllegalArg,
|
|
"OSRCalcSemiMinorFromInvFlattening(): Wrong input values");
|
|
return dfSemiMajor;
|
|
}
|
|
else
|
|
return dfSemiMajor * (1.0 - 1.0/dfInvFlattening);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* GetWGS84SRS() */
|
|
/************************************************************************/
|
|
|
|
static OGRSpatialReference* poSRSWGS84 = NULL;
|
|
static CPLMutex* hMutex = NULL;
|
|
|
|
/**
|
|
* \brief Returns an instance of a SRS object with WGS84 WKT.
|
|
*
|
|
* The reference counter of the returned object is not increased by this operation.
|
|
*
|
|
* @return instance.
|
|
* @since GDAL 2.0
|
|
*/
|
|
|
|
OGRSpatialReference* OGRSpatialReference::GetWGS84SRS()
|
|
{
|
|
CPLMutexHolderD(&hMutex);
|
|
if( poSRSWGS84 == NULL )
|
|
poSRSWGS84 = new OGRSpatialReference(SRS_WKT_WGS84);
|
|
return poSRSWGS84;
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* CleanupSRSWGS84Thread() */
|
|
/************************************************************************/
|
|
|
|
static void CleanupSRSWGS84Thread()
|
|
{
|
|
if( hMutex != NULL )
|
|
{
|
|
poSRSWGS84->Release();
|
|
poSRSWGS84 = NULL;
|
|
CPLDestroyMutex(hMutex);
|
|
hMutex = NULL;
|
|
}
|
|
}
|