osgEarth 2.1.1
|
Public Member Functions | |
QscSpatialReference (void *handle) | |
virtual osgEarth::GeoLocator * | createLocator (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 () |
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).
seamless::QscSpatialReference::QscSpatialReference | ( | void * | handle | ) |
Definition at line 438 of file QSC.cpp.
: SpatialReference(handle, "OSGEARTH", "qsc-cube", "Quadralateralized Sphere Cube") { //nop }
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.
xmin,ymin,xmax,ymax | Extents of the tile for which to create a locator. These should be in degrees for a geographic/geocentric scene. |
plate_carre | Set 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; }
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; }
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; }
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; }