osgEarth 2.1.1
Public Member Functions | Static Public Member Functions | Protected Types | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Private Member Functions | Static Private Member Functions

osgEarth::SpatialReference Class Reference

Inheritance diagram for osgEarth::SpatialReference:
Collaboration diagram for osgEarth::SpatialReference:

List of all members.

Public Member Functions

virtual bool transform (double x, double y, double z, const SpatialReference *to_srs, double &out_x, double &out_y, double &out_z, void *context=0L) const
bool transform (const osg::Vec3d &input, const SpatialReference *to_srs, osg::Vec3d &output, void *context=0L) const
bool transform2D (double x, double y, const SpatialReference *to_srs, double &out_x, double &out_y, void *context=0L) const
virtual bool transformPoints (const SpatialReference *to_srs, double *x, double *y, double *z, unsigned int numPoints, void *context=0L, bool ignore_errors=false) const
virtual bool transformPoints (const SpatialReference *to_srs, std::vector< osg::Vec3d > &points, void *context=0L, bool ignore_errors=false) const
bool transformToECEF (const osg::Vec3d &input, osg::Vec3d &output) const
bool transformToECEF (std::vector< osg::Vec3d > &points, bool ignore_errors=false) const
bool transformFromECEF (const osg::Vec3d &input, osg::Vec3d &output) const
bool transformFromECEF (std::vector< osg::Vec3d > &points, bool ignoreErrors=false) const
virtual bool transformExtent (const SpatialReference *to_srs, double &in_out_xmin, double &in_out_ymin, double &in_out_xmax, double &in_out_ymax, void *context=0L) const
virtual bool transformExtentPoints (const SpatialReference *to_srs, double in_xmin, double in_ymin, double in_xmax, double in_ymax, double *x, double *y, unsigned int numx, unsigned int numy, void *context=0L, bool ignore_errors=false) const
virtual bool isGeographic () const
virtual bool isProjected () const
bool isMercator () const
bool isNorthPolar () const
bool isSouthPolar () const
virtual bool isUserDefined () const
virtual bool isContiguous () const
virtual bool isCube () const
virtual bool isLTP () const
const std::string & getName () const
const osg::EllipsoidModel * getEllipsoid () const
const std::string & getWKT () const
const std::string & getInitType () const
const std::string & getInitString () const
const std::string & getDatumName () const
virtual bool isEquivalentTo (const SpatialReference *rhs) const
const SpatialReferencegetGeographicSRS () const
SpatialReferencecreateTangentPlaneSRS (const osg::Vec3d &refPos) const
SpatialReferencecreateTransMercFromLongitude (const Angular &lon) const
SpatialReferencecreateUTMFromLongitude (const Angular &lon) const
osg::CoordinateSystemNode * createCoordinateSystemNode () const
bool populateCoordinateSystemNode (osg::CoordinateSystemNode *csn) const
virtual GeoLocatorcreateLocator (double xmin, double ymin, double xmax, double ymax, bool plate_carre=false) const

Static Public Member Functions

static SpatialReferencecreate (const std::string &init)
static SpatialReferencecreate (osg::CoordinateSystemNode *csn)
static SpatialReferencecreateFromHandle (void *ogrHandle, bool xferOwnership=false)

Protected Types

typedef std::map< std::string,
void * > 
TransformHandleCache
typedef std::map< std::string,
osg::ref_ptr< SpatialReference > > 
SpatialReferenceCache

Protected Member Functions

virtual ~SpatialReference ()
 SpatialReference (void *handle, const std::string &type, const std::string &init_str, const std::string &name)
 SpatialReference (void *handle, bool ownsHandle=true)
void init ()
virtual void _init ()
virtual bool _isEquivalentTo (const SpatialReference *srs) const
virtual bool preTransform (double &x, double &y, double &z, void *context) const
virtual bool postTransform (double &x, double &y, double &z, void *context) const

Static Protected Member Functions

static SpatialReferenceCachegetSpatialReferenceCache ()

Protected Attributes

bool _initialized
void * _handle
bool _owns_handle
bool _is_geographic
bool _is_mercator
bool _is_north_polar
bool _is_south_polar
bool _is_cube
bool _is_contiguous
bool _is_user_defined
bool _is_ltp
std::string _name
std::string _wkt
std::string _proj4
std::string _init_type
std::string _init_str
std::string _init_str_lc
std::string _datum
osg::ref_ptr< osg::EllipsoidModel > _ellipsoid
osg::ref_ptr< SpatialReference_geo_srs
TransformHandleCache _transformHandleCache

Private Member Functions

SpatialReferencevalidate ()

Static Private Member Functions

static SpatialReferencecreateFromWKT (const std::string &wkt, const std::string &alias, const std::string &name="")
static SpatialReferencecreateFromPROJ4 (const std::string &proj4, const std::string &alias, const std::string &name="")
static SpatialReferencecreateCube ()

Detailed Description

SpatialReference holds information describing the reference ellipsoid/datum and the projection of geospatial data.

Definition at line 46 of file SpatialReference.


Member Typedef Documentation

typedef std::map< std::string, osg::ref_ptr<SpatialReference> > osgEarth::SpatialReference::SpatialReferenceCache [protected]

Definition at line 300 of file SpatialReference.

typedef std::map<std::string,void*> osgEarth::SpatialReference::TransformHandleCache [protected]

Definition at line 287 of file SpatialReference.


Constructor & Destructor Documentation

SpatialReference::~SpatialReference ( ) [protected, virtual]

Definition at line 360 of file SpatialReference.cpp.

{
    if ( _handle )
    {
        GDAL_SCOPED_LOCK;

        for (TransformHandleCache::iterator itr = _transformHandleCache.begin(); itr != _transformHandleCache.end(); ++itr)
        {
            OCTDestroyCoordinateTransformation(itr->second);
        }

        if ( _owns_handle )
        {
            OSRDestroySpatialReference( _handle );
        }

        _handle = NULL;
    }
}
SpatialReference::SpatialReference ( void *  handle,
const std::string &  type,
const std::string &  init_str,
const std::string &  name 
) [protected]

Definition at line 327 of file SpatialReference.cpp.

                                                           :
osg::Referenced( true ),
_initialized( false ),
_handle( handle ),
_owns_handle( true ),
_name( name ),
_init_type( init_type ),
_init_str( init_str ),
_is_geographic( false ),
_is_mercator( false ),
_is_north_polar( false ), 
_is_south_polar( false ),
_is_cube( false ),
_is_contiguous( false ),
_is_user_defined( false ),
_is_ltp( false )
{
    _init_str_lc = init_str;
    std::transform( _init_str_lc.begin(), _init_str_lc.end(), _init_str_lc.begin(), ::tolower );
}

Here is the call graph for this function:

Here is the caller graph for this function:

SpatialReference::SpatialReference ( void *  handle,
bool  ownsHandle = true 
) [protected]

Definition at line 351 of file SpatialReference.cpp.

                                                                :
osg::Referenced( true ),
_initialized( false ),
_handle( handle ),
_owns_handle( ownsHandle )
{
    //nop
}

Member Function Documentation

void SpatialReference::_init ( ) [protected, virtual]

Reimplemented in osgEarth::CubeSpatialReference, osgEarth::LTPSpatialReference, seamless::EulerSpatialReference, and seamless::QscSpatialReference.

Definition at line 1090 of file SpatialReference.cpp.

{
    // set defaults:
    _is_user_defined = false; 
    _is_contiguous = true;   
    _is_cube = false;
    _is_geographic = OSRIsGeographic( _handle ) != 0;

    // extract the ellipsoid parameters:
    int err;
    double semi_major_axis = OSRGetSemiMajor( _handle, &err );
    double semi_minor_axis = OSRGetSemiMinor( _handle, &err );
    _ellipsoid = new osg::EllipsoidModel( semi_major_axis, semi_minor_axis );

    // try to get an ellipsoid name:
    _ellipsoid->setName( getOGRAttrValue(_handle, "SPHEROID", 0, true) );

    // extract the projection:
    if ( _name.empty() || _name == "unnamed" )
    {
        _name = _is_geographic? 
            getOGRAttrValue( _handle, "GEOGCS", 0 ) : 
            getOGRAttrValue( _handle, "PROJCS", 0 );
    }
    std::string proj = getOGRAttrValue( _handle, "PROJECTION", 0, true );

    // check for the Mercator projection:
    _is_mercator = !proj.empty() && proj.find("mercator")==0;

    // check for the Polar projection:
    if ( !proj.empty() && proj.find("polar_stereographic") != std::string::npos )
    {
        double lat = as<double>( getOGRAttrValue( _handle, "latitude_of_origin", 0, true ), -90.0 );
        _is_north_polar = lat > 0.0;
        _is_south_polar = lat < 0.0;
    }
        else
        {
                _is_north_polar = false;
                _is_south_polar = false;
        }

    // Give the SRS a name if it doesn't have one:
    if ( _name == "unnamed" || _name.empty() )
    {
        _name =
            _is_geographic? "Geographic CS" :
            _is_mercator? "Mercator CS" :
            ( !proj.empty()? proj : "Projected CS" );
    }

    // Try to extract the OGC well-known-text (WKT) string:
    char* wktbuf;
    if ( OSRExportToWkt( _handle, &wktbuf ) == OGRERR_NONE )
    {
        _wkt = wktbuf;
        OGRFree( wktbuf );
    }

    // If the user did not specify and initialization string, use the WKT.
    if ( _init_str.empty() )
    {
        _init_str = _wkt;
        _init_type = "WKT";
    }
    
    // Try to extract the PROJ4 initialization string:
    char* proj4buf;
    if ( OSRExportToProj4( _handle, &proj4buf ) == OGRERR_NONE )
    {
        _proj4 = proj4buf;
        OGRFree( proj4buf );
    }

    // Try to extract the datum
    _datum = getOGRAttrValue( _handle, "DATUM", 0, true );

    _initialized = true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool SpatialReference::_isEquivalentTo ( const SpatialReference srs) const [protected, virtual]

Reimplemented in osgEarth::LTPSpatialReference.

Definition at line 454 of file SpatialReference.cpp.

{
    if ( !rhs )
        return false;

    if ( this == rhs )
        return true;

    if (isGeographic()  != rhs->isGeographic()  ||
        isMercator()    != rhs->isMercator()    ||
        isNorthPolar()  != rhs->isNorthPolar()  ||
        isSouthPolar()  != rhs->isSouthPolar()  ||
        isContiguous()  != rhs->isContiguous()  ||
        isUserDefined() != rhs->isUserDefined() ||
        isCube()        != rhs->isCube()        ||
        isLTP()         != rhs->isLTP() )
    {
        return false;
    }

    if ( _init_str_lc == rhs->_init_str_lc )
        return true;

    if ( this->getWKT() == rhs->getWKT() )
        return true;

    if (this->isGeographic() && rhs->isGeographic() &&
        this->getEllipsoid()->getRadiusEquator() == rhs->getEllipsoid()->getRadiusEquator() &&
        this->getEllipsoid()->getRadiusPolar() == rhs->getEllipsoid()->getRadiusPolar())
    {
        return true;
    }

    // last resort, since it requires the lock
    GDAL_SCOPED_LOCK;
    return TRUE == ::OSRIsSame( _handle, rhs->_handle );
}

Here is the call graph for this function:

Here is the caller graph for this function:

SpatialReference * SpatialReference::create ( osg::CoordinateSystemNode *  csn) [static]

Attempts to create a spatial reference def from a pre-existing CSN, returning NULL if there is not enough information.

Definition at line 262 of file SpatialReference.cpp.

{
    SpatialReference* result = NULL;
    if ( csn && !csn->getCoordinateSystem().empty() )
    {
        result = create( csn->getCoordinateSystem() );
    }
    return result;
}

Here is the call graph for this function:

SpatialReference * SpatialReference::create ( const std::string &  init) [static]

Creates an SRS from an initialization string. This can be a variety of things, including a WKT spec, a PROJ4 init string, or a "well-known" idenfitier (e.g., "WGS84" or "spherical-mercator").

Definition at line 186 of file SpatialReference.cpp.

{
    static OpenThreads::Mutex s_mutex;
    OpenThreads::ScopedLock<OpenThreads::Mutex> exclusiveLock(s_mutex);

    std::string low = init;
    std::transform( low.begin(), low.end(), low.begin(), ::tolower );

    SpatialReferenceCache::iterator itr = getSpatialReferenceCache().find(init);
    if (itr != getSpatialReferenceCache().end())
    {
        //OE_NOTICE << "Returning cached SRS" << std::endl;
        return itr->second.get();
    }

    osg::ref_ptr<SpatialReference> srs;

    // shortcut for spherical-mercator:
    if (low == "spherical-mercator" || low == "epsg:900913" || low == "epsg:3785" ||
        low == "epsg:41001" || low == "epsg:102113" || low == "epsg:102100")
    {
        // note the use of nadgrids=@null (see http://proj.maptools.org/faq.html)
        // adjusted +a by ONE to work around osg manipulator error until we can figure out why.. GW
        srs = createFromPROJ4(
            "+proj=merc +a=6378137 +b=6378137 +lon_0=0 +k=1 +x_0=0 +y_0=0 +nadgrids=@null +units=m +no_defs",
            init,
            "Spherical Mercator" );
    }

    // ellipsoidal ("world") mercator:
    else if (low == "epsg:54004" || low == "epsg:9804" || low == "epsg:3832")
    {
        srs = createFromPROJ4(
            "+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs",
            init,
            "World Mercator" );
    }

    // common WGS84:
    else if (low == "epsg:4326" || low == "wgs84")
    {
        srs = createFromPROJ4(
            "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs",
            init,
            "WGS84" );
    }

    // custom srs for the unified cube
    else if ( low == "unified-cube" )
    {
        srs = createCube();
    }

    else if ( low.find( "+" ) == 0 )
    {
        srs = createFromPROJ4( low, init );
    }
    else if ( low.find( "epsg:" ) == 0 || low.find( "osgeo:" ) == 0 )
    {
        srs = createFromPROJ4( std::string("+init=") + low, init );
    }
    else if ( low.find( "projcs" ) == 0 || low.find( "geogcs" ) == 0 )
    {
        srs = createFromWKT( init, init );
    }
    else
    {
        return NULL;
    }

    getSpatialReferenceCache()[init] = srs;
    return srs.get();
}

Here is the call graph for this function:

Here is the caller graph for this function:

osg::CoordinateSystemNode * SpatialReference::createCoordinateSystemNode ( ) const

Creates a new CSN based on this spatial reference.

Definition at line 616 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();

    osg::CoordinateSystemNode* csn = new osg::CoordinateSystemNode();
    populateCoordinateSystemNode( csn );
    return csn;
}

Here is the call graph for this function:

SpatialReference * SpatialReference::createCube ( ) [static, private]

Definition at line 104 of file SpatialReference.cpp.

{
    // root the cube srs with a WGS84 intermediate ellipsoid.
    std::string init = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs";

    SpatialReference* result = NULL;
    GDAL_SCOPED_LOCK;
        void* handle = OSRNewSpatialReference( NULL );
    if ( OSRImportFromProj4( handle, init.c_str() ) == OGRERR_NONE )
        {
        result = new CubeSpatialReference( handle );
        }
        else 
        {
        OE_WARN << LC << "Unable to create SRS: " << init << std::endl;
                OSRDestroySpatialReference( handle );
        }
    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SpatialReference * SpatialReference::createFromHandle ( void *  ogrHandle,
bool  xferOwnership = false 
) [static]

Creates an SRS around a pre-existing OGR spatial reference handle. The new SpatialReference object takes ownership of the handle.

Parameters:
xferOwnershipIf true, the SpatialReference object is responsible for releasing the handle upon destruction.

Definition at line 274 of file SpatialReference.cpp.

{
    SpatialReference* srs = new SpatialReference( ogrHandle, xferOwnership );
    return srs;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SpatialReference * SpatialReference::createFromPROJ4 ( const std::string &  proj4,
const std::string &  alias,
const std::string &  name = "" 
) [static, private]

Definition at line 86 of file SpatialReference.cpp.

{
    SpatialReference* result = NULL;
    GDAL_SCOPED_LOCK;
        void* handle = OSRNewSpatialReference( NULL );
    if ( OSRImportFromProj4( handle, init.c_str() ) == OGRERR_NONE )
        {
        result = new SpatialReference( handle, "PROJ4", init_alias, name );
        }
        else 
        {
        OE_WARN << LC << "Unable to create spatial reference from PROJ4: " << init << std::endl;
                OSRDestroySpatialReference( handle );
        }
    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SpatialReference * SpatialReference::createFromWKT ( const std::string &  wkt,
const std::string &  alias,
const std::string &  name = "" 
) [static, private]

Definition at line 164 of file SpatialReference.cpp.

{
    osg::ref_ptr<SpatialReference> result;
    GDAL_SCOPED_LOCK;
        void* handle = OSRNewSpatialReference( NULL );
    char buf[4096];
    char* buf_ptr = &buf[0];
        strcpy( buf, init.c_str() );
        if ( OSRImportFromWkt( handle, &buf_ptr ) == OGRERR_NONE )
        {
        result = new SpatialReference( handle, "WKT", init_alias, name );
        result = result->validate();
        }
        else 
        {
                OE_WARN << LC << "Unable to create spatial reference from WKT: " << init << std::endl;
                OSRDestroySpatialReference( handle );
        }
    return result.release();
}

Here is the call graph for this function:

Here is the caller graph for this function:

GeoLocator * SpatialReference::createLocator ( double  xmin,
double  ymin,
double  xmax,
double  ymax,
bool  plate_carre = false 
) const [virtual]

Creates a new Locator object based on this spatial reference.

Parameters:
xmin,ymin,xmax,ymaxExtents of the tile for which to create a locator. These should be in degrees for a geographic/geocentric scene.
plate_carreSet this to true for the special case in which you are using a geographic SRS with a PROJECTED map (like flat-earth lat/long).

Reimplemented in osgEarth::CubeSpatialReference, seamless::EulerSpatialReference, and seamless::QscSpatialReference.

Definition at line 672 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();

    GeoLocator* locator = new GeoLocator( GeoExtent(this, xmin, ymin, xmax, ymax) );
    locator->setEllipsoidModel( (osg::EllipsoidModel*)getEllipsoid() );
    locator->setCoordinateSystemType( isGeographic()? osgTerrain::Locator::GEOGRAPHIC : osgTerrain::Locator::PROJECTED );
    // note: not setting the format/cs on purpose.

    if ( isGeographic() && !plate_carre )
    {
        locator->setTransform( getTransformFromExtents(
            osg::DegreesToRadians( xmin ),
            osg::DegreesToRadians( ymin ),
            osg::DegreesToRadians( xmax ),
            osg::DegreesToRadians( ymax ) ) );
    }
    else
    {
        locator->setTransform( getTransformFromExtents( xmin, ymin, xmax, ymax ) );
    }
    return locator;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SpatialReference * SpatialReference::createTangentPlaneSRS ( const osg::Vec3d &  refPos) const

Creates and returns a local trangent plane SRS at the given reference location. The reference location is expressed in this object's SRS, but it tangent to the globe at getGeographicSRS(). LTP units are in meters.

Definition at line 524 of file SpatialReference.cpp.

{
    SpatialReference* result = 0L;
    osg::Vec3d lla;
    if ( this->transform(pos, this->getGeographicSRS(), lla) )
    {
        result = new LTPSpatialReference( this->getGeographicSRS()->_handle, lla );
    }
    else
    {
        OE_WARN << LC << "Unable to create LTP SRS" << std::endl;
    }
    return result;
}

Here is the call graph for this function:

SpatialReference * SpatialReference::createTransMercFromLongitude ( const Angular lon) const

Creates a transverse mercator projection centered at the specified longitude.

Definition at line 540 of file SpatialReference.cpp.

{
    // note. using tmerc with +lat_0 <> 0 is sloooooow.
    std::string datum = getDatumName();
    std::stringstream buf;
    buf << "+proj=tmerc +lat_0=0"
        << " +lon_0=" << lon.as(Units::DEGREES)
        << " +datum=" << (!datum.empty() ? "wgs84" : datum);
    std::string projstr;
    projstr = buf.str();
    return create( projstr );
}

Here is the call graph for this function:

SpatialReference * SpatialReference::createUTMFromLongitude ( const Angular lon) const

Creates a UTM (universal transverse mercator) projection in the UTM zone containing the specified longitude. NOTE: this is slightly faster than using basic tmerc (transverse mercator) above.

Definition at line 554 of file SpatialReference.cpp.

{
    // note. UTM is up to 10% faster than TMERC for the same meridian.
    unsigned zone = 1 + (unsigned)floor((lon.as(Units::DEGREES)+180.0)/6.0);
    std::string datum = getDatumName();
    std::stringstream buf;
    buf << "+proj=utm +zone=" << zone
        << " +datum=" << (!datum.empty() ? "wgs84" : datum);
    std::string projstr;
    projstr = buf.str();
    return create( projstr );
}

Here is the call graph for this function:

Here is the caller graph for this function:

const std::string & SpatialReference::getDatumName ( ) const

Gets the datum identifier of this SRS (or empty string if not available)

Definition at line 413 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();
    return _datum;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const osg::EllipsoidModel * SpatialReference::getEllipsoid ( ) const

Gets the underlying reference ellipsoid of this SRS

Definition at line 405 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();
    return _ellipsoid.get();
}

Here is the call graph for this function:

Here is the caller graph for this function:

const SpatialReference * SpatialReference::getGeographicSRS ( ) const

Gets a reference to this SRS's underlying geographic SRS.

Definition at line 493 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();

    if ( _is_geographic )
        return this;

    if ( !_geo_srs.valid() )
    {
        GDAL_SCOPED_LOCK;

        if ( !_geo_srs.valid() ) // double-check pattern
        {
            void* new_handle = OSRNewSpatialReference( NULL );
            int err = OSRCopyGeogCSFrom( new_handle, _handle );
            if ( err == OGRERR_NONE )
            {
                const_cast<SpatialReference*>(this)->_geo_srs = new SpatialReference( new_handle );
            }
            else
            {
                OSRDestroySpatialReference( new_handle );
            }
        }
    }

    return _geo_srs.get();
}

Here is the call graph for this function:

Here is the caller graph for this function:

const std::string & SpatialReference::getInitString ( ) const

Gets the string that was used to initialize this SRS

Definition at line 429 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();
    return _init_str;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const std::string & SpatialReference::getInitType ( ) const

Gets the initialization type (PROJ4, WKT, etc.)

Definition at line 437 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();
    return _init_type;
}

Here is the call graph for this function:

const std::string & SpatialReference::getName ( ) const

Gets the readable name of this SRS.

Definition at line 397 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();
    return _name;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SpatialReference::SpatialReferenceCache & SpatialReference::getSpatialReferenceCache ( ) [static, protected]

Definition at line 76 of file SpatialReference.cpp.

{
    //Make sure the registry is created before the cache
    osgEarth::Registry::instance();
    static SpatialReferenceCache s_cache;
    return s_cache;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const std::string & SpatialReference::getWKT ( ) const

Gets the WKT string

Definition at line 421 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();
    return _wkt;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void SpatialReference::init ( ) [protected]

Definition at line 1076 of file SpatialReference.cpp.

{
    GDAL_SCOPED_LOCK;

    // always double-check the _initialized flag after obtaining the lock.
    if ( !_initialized )
    {
        // calls the internal version, which can be overriden by the developer.
        // therefore do not call init() from the constructor!
        _init();
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool SpatialReference::isContiguous ( ) const [virtual]

Tests whether coordinates in this SRS form a contiguous space. A non-contiguous SRS is one in which adjacent coordinates may not necessarily represent adjacent map locations.

Definition at line 592 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();
    return _is_contiguous;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool SpatialReference::isCube ( ) const [virtual]

Tests whether this SRS is a Unified Cube projection (osgEarth-internal)

Definition at line 608 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();
    return _is_cube;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool SpatialReference::isEquivalentTo ( const SpatialReference rhs) const [virtual]

Tests this SRS for equivalence with another.

Definition at line 445 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();

    return _isEquivalentTo( rhs );
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool SpatialReference::isGeographic ( ) const [virtual]

True is this is a geographic SRS (i.e. unprojected lat/long)

Reimplemented in osgEarth::CubeSpatialReference, osgEarth::LTPSpatialReference, seamless::EulerSpatialReference, and seamless::QscSpatialReference.

Definition at line 381 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();
    return _is_geographic;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual bool osgEarth::SpatialReference::isLTP ( ) const [inline, virtual]

Tests whether this SRS is a Local Tangent Plane projection (osgEarth-internal)

Definition at line 198 of file SpatialReference.

{ return _is_ltp; }

Here is the caller graph for this function:

bool SpatialReference::isMercator ( ) const

Tests whether this SRS represents a Mercator projection.

Definition at line 568 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();
    return _is_mercator;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool SpatialReference::isNorthPolar ( ) const

Tests whether this SRS represents a polar sterographic projection.

Definition at line 576 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();
    return _is_north_polar;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool SpatialReference::isProjected ( ) const [virtual]

True if this is a projected SRS (i.e. local coordinate system)

Reimplemented in osgEarth::CubeSpatialReference, osgEarth::LTPSpatialReference, seamless::EulerSpatialReference, and seamless::QscSpatialReference.

Definition at line 389 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();
    return !_is_geographic;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool SpatialReference::isSouthPolar ( ) const

Definition at line 584 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();
    return _is_south_polar;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool SpatialReference::isUserDefined ( ) const [virtual]

Tests whether this SRS is user-defined; i.e. whether it is other than a well-known SRS. (i.e. whether the SRS is unsupported by GDAL)

Definition at line 600 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();
    return _is_user_defined;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool SpatialReference::populateCoordinateSystemNode ( osg::CoordinateSystemNode *  csn) const

Populates the provided CSN with information from this SRS.

Definition at line 627 of file SpatialReference.cpp.

{
    if ( !csn )
        return false;

    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();

    if ( !_wkt.empty() )
    {
        csn->setFormat( "WKT" );
        csn->setCoordinateSystem( _wkt );
    }
    else if ( !_proj4.empty() )
    {
        csn->setFormat( "PROJ4" );
        csn->setCoordinateSystem( _proj4 );
    }
    else
    {
        csn->setFormat( _init_type );
        csn->setCoordinateSystem( _init_str );
    }
    
    csn->setEllipsoidModel( _ellipsoid.get() );
    
    return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual bool osgEarth::SpatialReference::postTransform ( double &  x,
double &  y,
double &  z,
void *  context 
) const [inline, protected, virtual]

Reimplemented in osgEarth::CubeSpatialReference, and osgEarth::LTPSpatialReference.

Definition at line 296 of file SpatialReference.

{ return true;}

Here is the caller graph for this function:

virtual bool osgEarth::SpatialReference::preTransform ( double &  x,
double &  y,
double &  z,
void *  context 
) const [inline, protected, virtual]

Reimplemented in osgEarth::CubeSpatialReference, and osgEarth::LTPSpatialReference.

Definition at line 295 of file SpatialReference.

{ return true; }

Here is the caller graph for this function:

bool SpatialReference::transform ( double  x,
double  y,
double  z,
const SpatialReference to_srs,
double &  out_x,
double &  out_y,
double &  out_z,
void *  context = 0L 
) const [virtual]

Transform a point to another SRS.

Definition at line 699 of file SpatialReference.cpp.

{        
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();

    //Check for equivalence and return if the coordinate systems are the same.
    if (isEquivalentTo(out_srs))
    {
        out_x = x;
        out_y = y;
        out_z = z;
        return true;
    }

    out_x = x;
    out_y = y;
    out_z = z;
    bool result = transformPoints(out_srs, &out_x, &out_y, &out_z, 1, context);

    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool osgEarth::SpatialReference::transform ( const osg::Vec3d &  input,
const SpatialReference to_srs,
osg::Vec3d &  output,
void *  context = 0L 
) const [inline]

Definition at line 82 of file SpatialReference.

        {
            return transform(input.x(), input.y(), input.z(), to_srs, output.x(), output.y(), output.z(), context);
        }
bool osgEarth::SpatialReference::transform2D ( double  x,
double  y,
const SpatialReference to_srs,
double &  out_x,
double &  out_y,
void *  context = 0L 
) const [inline]

Definition at line 91 of file SpatialReference.

        {
            double dummyZ;
            return transform(x, y, dummyZ, to_srs, out_x, out_y, dummyZ, context);
        }

Here is the caller graph for this function:

bool SpatialReference::transformExtent ( const SpatialReference to_srs,
double &  in_out_xmin,
double &  in_out_ymin,
double &  in_out_xmax,
double &  in_out_ymax,
void *  context = 0L 
) const [virtual]

Transforms a spatial extent to another SRS.

TODO: Update this method to work for: a) Geographic extents that cross the date line; and b) Polar extents.

Reimplemented in osgEarth::CubeSpatialReference, seamless::EulerSpatialReference, and seamless::QscSpatialReference.

Definition at line 1004 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();

    int oks = 0;

    //Transform all points and take the maximum bounding rectangle the resulting points
    double llx, lly;
    double ulx, uly;
    double urx, ury;
    double lrx, lry;
    double dummyZ = 0;

    //Lower Left
    oks += transform( in_out_xmin, in_out_ymin, 0, to_srs, llx, lly, dummyZ, context ) == true;

    //Upper Left
    oks += transform( in_out_xmin, in_out_ymax, 0, to_srs, ulx, uly, dummyZ, context ) == true;

    //Upper Right
    oks += transform( in_out_xmax, in_out_ymax, 0, to_srs, urx, ury, dummyZ, context ) == true;

    //Lower Right
    oks += transform( in_out_xmax, in_out_ymin, 0, to_srs, lrx, lry, dummyZ, context ) == true;


    if (oks == 4)
    {
        in_out_xmin = osg::minimum(llx, ulx);
        in_out_xmax = osg::maximum(lrx, urx);
        in_out_ymin = osg::minimum(lly, lry);
        in_out_ymax = osg::maximum(uly, ury);
        return true;
    }
    return false;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool SpatialReference::transformExtentPoints ( const SpatialReference to_srs,
double  in_xmin,
double  in_ymin,
double  in_xmax,
double  in_ymax,
double *  x,
double *  y,
unsigned int  numx,
unsigned int  numy,
void *  context = 0L,
bool  ignore_errors = false 
) const [virtual]

Reimplemented in seamless::EulerSpatialReference.

Definition at line 1047 of file SpatialReference.cpp.

{
    const double dx = (in_xmax - in_xmin) / (numx - 1);
    const double dy = (in_ymax - in_ymin) / (numy - 1);

    unsigned int pixel = 0;
    double fc = 0.0;
    for (unsigned int c = 0; c < numx; ++c, ++fc)
    {
        const double dest_x = in_xmin + fc * dx;
        double fr = 0.0;
        for (unsigned int r = 0; r < numy; ++r, ++fr)
        {
            const double dest_y = in_ymin + fr * dy;

            x[pixel] = dest_x;
            y[pixel] = dest_y;
            pixel++;     
        }
    }
    return transformPoints(to_srs, x, y, 0L, numx * numy, context, ignore_errors);
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool SpatialReference::transformFromECEF ( const osg::Vec3d &  input,
osg::Vec3d &  output 
) const

Transforms a point from geocentric/ECEF coordinates into this SRS (with a height above ellipsoid).

Definition at line 948 of file SpatialReference.cpp.

{
    // transform to lat/long:
    osg::Vec3d geo;

    getGeographicSRS()->getEllipsoid()->convertXYZToLatLongHeight(
        input.x(), input.y(), input.z(),
        geo.y(), geo.x(), geo.z() );

    // then convert to the local SRS.
    if ( isGeographic() )
    {
        output.set( osg::RadiansToDegrees(geo.x()), osg::RadiansToDegrees(geo.y()), geo.z() );
    }
    else
    {
        getGeographicSRS()->transform( 
            osg::RadiansToDegrees(geo.x()), osg::RadiansToDegrees(geo.y()), geo.z(),
            this,
            output.x(), output.y(), output.z() );
        //output.z() = geo.z();
    }

    return true;
}

Here is the call graph for this function:

bool SpatialReference::transformFromECEF ( std::vector< osg::Vec3d > &  points,
bool  ignoreErrors = false 
) const

Transforms an array of points from geocentric/ECEF coordinates into this SRS (with a height-above-ellipoid). The points are transformed in place.

Definition at line 976 of file SpatialReference.cpp.

{
    bool ok = true;

    // first convert all the points to lat/long (in place):
    for( unsigned i=0; i<points.size(); ++i )
    {
        osg::Vec3d& p = points[i];
        osg::Vec3d geo;
        getGeographicSRS()->getEllipsoid()->convertXYZToLatLongHeight(
            p.x(), p.y(), p.z(),
            geo.y(), geo.x(), geo.z() );
        geo.x() = osg::RadiansToDegrees( geo.x() );
        geo.y() = osg::RadiansToDegrees( geo.y() );
        p = geo;
    }

    // then convert them all to the local SRS if necessary.
    if ( !isGeographic() )
    {
        ok = getGeographicSRS()->transformPoints( this, points, 0L, ignoreErrors );
    }

    return ok;
}

Here is the call graph for this function:

bool SpatialReference::transformPoints ( const SpatialReference to_srs,
double *  x,
double *  y,
double *  z,
unsigned int  numPoints,
void *  context = 0L,
bool  ignore_errors = false 
) const [virtual]

Transforms an array of 3D points from this SRS to another SRS.

Definition at line 760 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();

    //Check for equivalence and return if the coordinate systems are the same.
    if (isEquivalentTo(out_srs))
        return true;

    if ( z )
    {
        for (unsigned int i = 0; i < numPoints; ++i)
            preTransform(x[i], y[i], z[i], context);
    }
    else
    {
        double dummyZ = 0.0;
        for (unsigned int i = 0; i < numPoints; ++i)
            preTransform(x[i], y[i], dummyZ, context);
    }
    
    bool success = false;

#ifdef USE_CUSTOM_MERCATOR_TRANSFORM

    if ( isGeographic() && out_srs->isMercator() )
    {
        success = geographicToMercator( x, y, z, numPoints );
    }

    else if ( isMercator() && out_srs->isGeographic() )
    {
        success = mercatorToGeographic( x, y, z, numPoints );
    }

    else
#endif

    {    
        GDAL_SCOPED_LOCK;

        void* xform_handle = NULL;
        TransformHandleCache::const_iterator itr = _transformHandleCache.find(out_srs->getWKT());
        if (itr != _transformHandleCache.end())
        {
            //OE_DEBUG << "SpatialRefernece: using cached transform handle" << std::endl;
            xform_handle = itr->second;
        }
        else
        {
            xform_handle = OCTNewCoordinateTransformation( _handle, out_srs->_handle);
            const_cast<SpatialReference*>(this)->_transformHandleCache[out_srs->getWKT()] = xform_handle;
        }

        if ( !xform_handle )
        {
            OE_WARN << LC
                << "SRS xform not possible" << std::endl
                << "    From => " << getName() << std::endl
                << "    To   => " << out_srs->getName() << std::endl;
            return false;
        }

        //double* temp_z = new double[numPoints];
        //success = OCTTransform( xform_handle, numPoints, x, y, temp_z ) > 0;
        //delete[] temp_z;
        
        success = OCTTransform( xform_handle, numPoints, x, y, z ) > 0;

        // END GDAL_SCOPE_LOCK
    }

    if ( success || ignore_errors )
    {
        if ( z )
        {
            for (unsigned int i = 0; i < numPoints; ++i)
                out_srs->postTransform(x[i], y[i], z[i], context);
        }
        else
        {
            double dummyZ = 0.0;
            for (unsigned int i = 0; i < numPoints; ++i)
                out_srs->postTransform(x[i], y[i], dummyZ, context);
        }
    }
    else
    {
        OE_WARN << LC << "Failed to xform a point from "
            << getName() << " to " << out_srs->getName()
            << std::endl;
    }
    return success;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool SpatialReference::transformPoints ( const SpatialReference to_srs,
std::vector< osg::Vec3d > &  points,
void *  context = 0L,
bool  ignore_errors = false 
) const [virtual]

Transforms an array of points from this SRS to another SRS.

Definition at line 860 of file SpatialReference.cpp.

{
    if ( !_initialized )
        const_cast<SpatialReference*>(this)->init();

    //Check for equivalence and return if the coordinate systems are the same.
    if (isEquivalentTo(out_srs)) 
        return true;

    int numPoints = points.size();
    double* x = new double[numPoints];
    double* y = new double[numPoints];
    double* z = new double[numPoints];

    for( int i=0; i<numPoints; i++ )
    {
        x[i] = points[i].x();
        y[i] = points[i].y();
        z[i] = points[i].z();
    }

    bool success = transformPoints( out_srs, x, y, z, numPoints, context, ignore_errors );

    if ( success )
    {
        for( int i=0; i<numPoints; i++ )
        {
            points[i].x() = x[i];
            points[i].y() = y[i];
            points[i].z() = z[i];
        }
    }

    delete[] x;
    delete[] y;
    delete[] z;

    return success;
}

Here is the call graph for this function:

bool SpatialReference::transformToECEF ( std::vector< osg::Vec3d > &  points,
bool  ignore_errors = false 
) const

Transforms an array of points to geocentric/ECEF coordinates. The points are transformed in place.

Definition at line 923 of file SpatialReference.cpp.

{
    if ( points.size() == 0 )
        return false;

    const SpatialReference*    geoSRS    = getGeographicSRS();
    const osg::EllipsoidModel* ellipsoid = geoSRS->getEllipsoid();

    for( unsigned i=0; i<points.size(); ++i )
    {
        osg::Vec3d& p = points[i];

        if ( !isGeographic() )
            transform( p.x(), p.y(), p.z(), geoSRS, p.x(), p.y(), p.z() );

        ellipsoid->convertLatLongHeightToXYZ(
            osg::DegreesToRadians( p.y() ), osg::DegreesToRadians( p.x() ), p.z(),
            p.x(), p.y(), p.z() );
    }

    return true;
}

Here is the call graph for this function:

bool SpatialReference::transformToECEF ( const osg::Vec3d &  input,
osg::Vec3d &  output 
) const

Transforms a point to geocentric/ECEF coordinates.

Definition at line 904 of file SpatialReference.cpp.

{
    double lat = input.y(), lon = input.x(), alt = input.z();
    
    // first convert to lat/long if necessary:
    if ( !isGeographic() )
        transform( input.x(), input.y(), input.z(), getGeographicSRS(), lon, lat, alt );

    // then convert to ECEF.
    //double z = input.z();
    getGeographicSRS()->getEllipsoid()->convertLatLongHeightToXYZ(
        osg::DegreesToRadians( lat ), osg::DegreesToRadians( lon ), alt,
        output.x(), output.y(), output.z() );

    return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SpatialReference * SpatialReference::validate ( ) [private]

Definition at line 281 of file SpatialReference.cpp.

{
    std::string proj = getOGRAttrValue( _handle, "PROJECTION", 0 );

    // fix invalid ESRI LCC projections:
    if ( proj == "Lambert_Conformal_Conic" )
    {
        bool has_2_sps =
            !getOGRAttrValue( _handle, "Standard_Parallel_2", 0 ).empty() ||
            !getOGRAttrValue( _handle, "standard_parallel_2", 0 ).empty();

        std::string new_wkt = getWKT();
        if ( has_2_sps )
            replaceIn( new_wkt, "Lambert_Conformal_Conic", "Lambert_Conformal_Conic_2SP" );
        else
            replaceIn( new_wkt, "Lambert_Conformal_Conic", "Lambert_Conformal_Conic_1SP" );

        OE_INFO << LC << "Morphing Lambert_Conformal_Conic to 1SP/2SP" << std::endl;
        
        return createFromWKT( new_wkt, _init_str, _name );
    }

    // fixes for ESRI Plate_Carree and Equidistant_Cylindrical projections:
    else if ( proj == "Plate_Carree" )
    {
        std::string new_wkt = getWKT();
        replaceIn( new_wkt, "Plate_Carree", "Equirectangular" );
        OE_INFO << LC << "Morphing Plate_Carree to Equirectangular" << std::endl;
        return createFromWKT( new_wkt, _init_str, _name ); //, input->getReferenceFrame() );
    }
    else if ( proj == "Equidistant_Cylindrical" )
    {
        std::string new_wkt = getWKT();
        OE_INFO << LC << "Morphing Equidistant_Cylindrical to Equirectangular" << std::endl;
        replaceIn( new_wkt, "Equidistant_Cylindrical", "Equirectangular" );
        return createFromWKT( new_wkt, _init_str, _name );
    }

    // no changes.
    return this;
}

Here is the call graph for this function:


Member Data Documentation

std::string osgEarth::SpatialReference::_datum [protected]

Definition at line 283 of file SpatialReference.

osg::ref_ptr<osg::EllipsoidModel> osgEarth::SpatialReference::_ellipsoid [protected]

Definition at line 284 of file SpatialReference.

Definition at line 285 of file SpatialReference.

Definition at line 268 of file SpatialReference.

std::string osgEarth::SpatialReference::_init_str [protected]

Definition at line 281 of file SpatialReference.

Definition at line 282 of file SpatialReference.

std::string osgEarth::SpatialReference::_init_type [protected]

Definition at line 280 of file SpatialReference.

Definition at line 267 of file SpatialReference.

Definition at line 274 of file SpatialReference.

Definition at line 273 of file SpatialReference.

Definition at line 270 of file SpatialReference.

Definition at line 276 of file SpatialReference.

Definition at line 271 of file SpatialReference.

Definition at line 272 of file SpatialReference.

Definition at line 272 of file SpatialReference.

Definition at line 275 of file SpatialReference.

std::string osgEarth::SpatialReference::_name [protected]

Definition at line 277 of file SpatialReference.

Definition at line 269 of file SpatialReference.

std::string osgEarth::SpatialReference::_proj4 [protected]

Definition at line 279 of file SpatialReference.

Definition at line 288 of file SpatialReference.

std::string osgEarth::SpatialReference::_wkt [protected]

Definition at line 278 of file SpatialReference.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines