osgEarth 2.1.1
Public Member Functions | Protected Member Functions

seamless::QscSpatialReference Class Reference

Inheritance diagram for seamless::QscSpatialReference:
Collaboration diagram for seamless::QscSpatialReference:

List of all members.

Public Member Functions

 QscSpatialReference (void *handle)
virtual osgEarth::GeoLocatorcreateLocator (double xmin, double ymin, double xmax, double ymax, bool plate_carre=false) const
virtual bool isGeographic () const
virtual bool isProjected () const
virtual bool preTransform (double &x, double &y, void *context) const
virtual bool postTransform (double &x, double &y, void *context) 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) const

Protected Member Functions

void _init ()

Detailed Description

The QSC SRS represents a 6-face cube, each face being in unit coordinates (-1,-1=>1,1). The cube lays out the 4 equatorial faces in a row. The North Pole face is above face 0 and the South Pole face is below face 0. This results in a space measuring (0,0=>4,3).

Definition at line 113 of file QSC.


Constructor & Destructor Documentation

seamless::QscSpatialReference::QscSpatialReference ( void *  handle)

Definition at line 438 of file QSC.cpp.

    : SpatialReference(handle, "OSGEARTH", "qsc-cube",
                       "Quadralateralized Sphere Cube")
{
    //nop
}

Member Function Documentation

void seamless::QscSpatialReference::_init ( ) [protected, virtual]

Reimplemented from osgEarth::SpatialReference.

Definition at line 446 of file QSC.cpp.

{
    SpatialReference::_init();

    _is_user_defined = true;
    _is_cube = true;
    _is_contiguous = false;
    _is_geographic = false;
    _name = "Quadralateralized Sphere Cube";
}
GeoLocator * seamless::QscSpatialReference::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 from osgEarth::SpatialReference.

Definition at line 458 of file QSC.cpp.

{
    int face;
    cubeToFace(xmin, ymin, xmax, ymax, face);

    GeoLocator* result = new QscFaceLocator( face );

    osg::Matrixd transform;
    transform.set(
        xmax-xmin, 0.0,       0.0, 0.0,
        0.0,       ymax-ymin, 0.0, 0.0,
        0.0,       0.0,       1.0, 0.0,
        xmin,      ymin,      0.0, 1.0);
    result->setTransform( transform );

    return result;
}

Here is the call graph for this function:

virtual bool seamless::QscSpatialReference::isGeographic ( ) const [inline, virtual]

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

Reimplemented from osgEarth::SpatialReference.

Definition at line 123 of file QSC.

{ return false; }
virtual bool seamless::QscSpatialReference::isProjected ( ) const [inline, virtual]

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

Reimplemented from osgEarth::SpatialReference.

Definition at line 124 of file QSC.

{ return true; }
bool seamless::QscSpatialReference::postTransform ( double &  x,
double &  y,
void *  context 
) const [virtual]

Definition at line 502 of file QSC.cpp.

{
    //Convert the incoming points from lat/lon back to face coordinates
    int face;
    double out_x, out_y;

    // convert from lat/long to x/y/face
    bool success = latLonToFaceCoords(y, x, out_x, out_y, face);
    if (!success)
    {
        OE_WARN << LC << "Could not transform face coordinates to lat lon" << std::endl;
        return false;
    }

    //TODO: what to do about boundary points?

    if ( !faceToCube(out_x, out_y, face))
    {
        OE_WARN << LC << "fromFace(" << out_x << "," << out_y << "," << face << ") failed" << std::endl;
        return false;
    }

    x = out_x;
    y = out_y;

    return true;
}

Here is the call graph for this function:

bool seamless::QscSpatialReference::preTransform ( double &  x,
double &  y,
void *  context 
) const [virtual]

Definition at line 479 of file QSC.cpp.

{
    // Convert the incoming points from cube => face => lat/long.
    int face;
    if ( !cubeToFace(x, y, face) )
    {
        OE_WARN << LC << "Failed to convert (" << x << "," << y << ") into face coordinates." << std::endl;
        return false;
    }

    double lat_deg, lon_deg;
    bool success = faceCoordsToLatLon( x, y, face, lat_deg, lon_deg );
    if (!success)
    {
        OE_WARN << LC << "Could not transform face coordinates to lat lon" << std::endl;
        return false;
    }
    x = lon_deg;
    y = lat_deg;
    return true;
}

Here is the call graph for this function:

bool seamless::QscSpatialReference::transformExtent ( const SpatialReference to_srs,
double &  in_out_xmin,
double &  in_out_ymin,
double &  in_out_xmax,
double &  in_out_ymax,
void *  context 
) 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 from osgEarth::SpatialReference.

Definition at line 531 of file QSC.cpp.

{
    // note: this method only works when the extent is isolated to one
    // face of the cube. If you want to transform an arbitrary extent,
    // you need to break it up into separate extents for each cube face.
    bool ok = true;

    double face_xmin = in_out_xmin, face_ymin = in_out_ymin;
    double face_xmax = in_out_xmax, face_ymax = in_out_ymax;

    int face;
    if (!cubeToFace(face_xmin, face_ymin, face_xmax, face_ymax, face))
    {
        OE_WARN << LC << "extent (" << in_out_xmin << ", " << in_out_ymin
                << ")=>(" << in_out_xmax << ", " << in_out_ymax <<
            ") crosses faces\n";
        return false;
    }
    // The polar and equatorial faces behave the same way, except if
    // an extent crosses the pole.

    double lonmin, lonmax, latmin, latmax;
    // if the extent crosses the center axes of the face, then,
    // due to the curvy nature of the projection, the maximim /
    // minimum will be at the crossing. So we may need to sample
    // up to 8 points.
    double lats[8], lons[8];
    int numSamples = 4;
    faceCoordsToLatLon(face_xmin, face_ymin, face, lats[0], lons[0]);
    faceCoordsToLatLon(face_xmax, face_ymin, face, lats[1], lons[1]);
    faceCoordsToLatLon(face_xmin, face_ymax, face, lats[2], lons[2]);
    faceCoordsToLatLon(face_xmax, face_ymax, face, lats[3], lons[3]);

    if ((face_xmin < 0 && face_xmax > 0))
    {
        faceCoordsToLatLon(0.0, face_ymin, face,
                           lats[numSamples], lons[numSamples]);
        faceCoordsToLatLon(0.0, face_ymax, face,
                           lats[numSamples + 1], lons[numSamples + 1]);
        numSamples += 2;

    }
    if ((face_ymin < 0 && face_ymax > 0))
    {
        faceCoordsToLatLon(face_xmin, 0.0, face,
                           lats[numSamples], lons[numSamples]);
        faceCoordsToLatLon(face_xmax, 0.0, face,
                           lats[numSamples + 1], lons[numSamples + 1]);
        numSamples += 2;

    }
    lonmin = *min_element(&lons[0], &lons[numSamples]);
    latmin = *min_element(&lats[0], &lats[numSamples]);
    lonmax = *max_element(&lons[0], &lons[numSamples]);
    latmax = *max_element(&lats[0], &lats[numSamples]);
    // Does the extent cross one of the poles?
    if ((face == 4 || face == 5) && numSamples == 8)
    {
        lonmin = -180.0;
        lonmax = 180.0;
        if (face == 4)
            latmax = 90.0;
        else
            latmin = -90.0;
    }
    // Check for Date Line crossing
    else if (face_xmin < 0 && face_xmax > 0
             && (face == 2 || (face == 4 && face_ymin >= 0)
                 || (face == 5 && face_ymax <= 0)))
    {
        std::swap(lonmin, lonmax);
    }
    if (to_srs->isGeographic())
    {
        in_out_xmin = lonmin;
        in_out_xmax = lonmax;
        in_out_ymin = latmin;
        in_out_ymax = latmax;
    }
    else
    {
        bool ok1 = transform(lonmin, latmin, to_srs, in_out_xmin, in_out_ymin,
                             context);
        bool ok2 = transform(lonmax, latmax, to_srs, in_out_xmax, in_out_ymax,
                             context);
        ok = ok1 && ok2;
    }
    return ok;
}

Here is the call graph for this function:


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