osgEarth 2.1.1
|
Public Types | |
enum | ProfileType { TYPE_UNKNOWN, TYPE_GEODETIC, TYPE_MERCATOR, TYPE_LOCAL } |
Public Member Functions | |
bool | isOK () const |
const GeoExtent & | getExtent () const |
const GeoExtent & | getLatLongExtent () const |
const SpatialReference * | getSRS () const |
const VerticalSpatialReference * | getVerticalSRS () const |
void | setVerticalSRS (const VerticalSpatialReference *value) |
ProfileType | getProfileType () const |
unsigned int | getLevelOfDetailForHorizResolution (double resolution, int tileSize) const |
void | getRootKeys (std::vector< TileKey > &out_keys) const |
virtual GeoExtent | calculateExtent (unsigned int lod, unsigned int tileX, unsigned int tileY) |
bool | isEquivalentTo (const Profile *rhs) const |
void | getTileDimensions (unsigned int lod, double &out_width, double &out_height) const |
void | getNumTiles (unsigned int lod, unsigned int &out_tiles_wide, unsigned int &out_tiles_high) const |
void | getIntersectingTiles (const TileKey &key, std::vector< TileKey > &out_intersectingKeys) const |
virtual void | getIntersectingTiles (const GeoExtent &extent, std::vector< TileKey > &out_intersectingKeys) const |
GeoExtent | clampAndTransformExtent (const GeoExtent &input, bool *out_clamped=0L) const |
TileKey | createTileKey (double x, double y, unsigned int level) const |
std::string | toString () const |
Static Public Member Functions | |
static const Profile * | create (const std::string &srs_string, double xmin, double ymin, double xmax, double ymax, const std::string &vsrs_string="", unsigned int numTilesWideAtLod0=0, unsigned int numTilesHighAtLod0=0) |
static const Profile * | create (const SpatialReference *srs, double xmin, double ymin, double xmax, double ymax, double geoxmin, double geoymin, double geoxmax, double geoymax, const VerticalSpatialReference *vsrs=0L, unsigned int numTilesWideAtLod0=0, unsigned int numTilesHighAtLod0=0) |
static const Profile * | create (const SpatialReference *srs, double xmin, double ymin, double xmax, double ymax, const VerticalSpatialReference *vsrs=0L, unsigned int numTilesWideAtLod0=0, unsigned int numTilesHighAtLod0=0) |
static const Profile * | create (const std::string &srs_string, const std::string &vsrs_string="", unsigned int numTilesWideAtLod0=0, unsigned int numTilesHighAtLod0=0) |
static const Profile * | create (const ProfileOptions &options) |
static ProfileType | getProfileTypeFromSRS (const std::string &srs) |
Protected Member Functions | |
Profile (const SpatialReference *srs, double xmin, double ymin, double xmax, double ymax, const VerticalSpatialReference *vsrs, unsigned int x_tiles_at_lod0=0, unsigned int y_tiles_at_lod0=0) | |
Profile (const SpatialReference *srs, double xmin, double ymin, double xmax, double ymax, double geoxmin, double geoymin, double geoxmax, double geoymax, const VerticalSpatialReference *vsrs, unsigned int x_tiles_at_lod0=0, unsigned int y_tiles_at_lod0=0) | |
virtual void | addIntersectingTiles (const GeoExtent &key_ext, std::vector< TileKey > &out_intersectingKeys) const |
Private Attributes | |
GeoExtent | _extent |
GeoExtent | _latlong_extent |
osg::ref_ptr< const VerticalSpatialReference > | _vsrs |
unsigned int | _numTilesWideAtLod0 |
unsigned int | _numTilesHighAtLod0 |
A "profile" defines the layout of a data source. The profile conveys the spatial reference system (SRS), the geospatial extents within that SRS, and the tiling scheme.
Profile::Profile | ( | const SpatialReference * | srs, |
double | xmin, | ||
double | ymin, | ||
double | xmax, | ||
double | ymax, | ||
const VerticalSpatialReference * | vsrs, | ||
unsigned int | x_tiles_at_lod0 = 0 , |
||
unsigned int | y_tiles_at_lod0 = 0 |
||
) | [protected] |
Definition at line 255 of file Profile.cpp.
: osg::Referenced( true ), _vsrs( vsrs ) { _extent = GeoExtent( srs, xmin, ymin, xmax, ymax ); _numTilesWideAtLod0 = numTilesWideAtLod0 != 0? numTilesWideAtLod0 : srs->isGeographic()? 2 : 1; _numTilesHighAtLod0 = numTilesHighAtLod0 != 0? numTilesHighAtLod0 : 1; // automatically calculate the lat/long extents: _latlong_extent = srs->isGeographic()? _extent : _extent.transform( _extent.getSRS()->getGeographicSRS() ); if ( !_vsrs.valid() ) _vsrs = Registry::instance()->getDefaultVSRS(); }
Profile::Profile | ( | const SpatialReference * | srs, |
double | xmin, | ||
double | ymin, | ||
double | xmax, | ||
double | ymax, | ||
double | geoxmin, | ||
double | geoymin, | ||
double | geoxmax, | ||
double | geoymax, | ||
const VerticalSpatialReference * | vsrs, | ||
unsigned int | x_tiles_at_lod0 = 0 , |
||
unsigned int | y_tiles_at_lod0 = 0 |
||
) | [protected] |
Definition at line 277 of file Profile.cpp.
: osg::Referenced( true ), _vsrs( vsrs ) { _extent = GeoExtent( srs, xmin, ymin, xmax, ymax ); _numTilesWideAtLod0 = numTilesWideAtLod0 != 0? numTilesWideAtLod0 : srs->isGeographic()? 2 : 1; _numTilesHighAtLod0 = numTilesHighAtLod0 != 0? numTilesHighAtLod0 : 1; _latlong_extent = GeoExtent( srs->getGeographicSRS(), geo_xmin, geo_ymin, geo_xmax, geo_ymax ); if ( !_vsrs.valid() ) _vsrs = Registry::instance()->getDefaultVSRS(); }
void Profile::addIntersectingTiles | ( | const GeoExtent & | key_ext, |
std::vector< TileKey > & | out_intersectingKeys | ||
) | const [protected, virtual] |
Definition at line 502 of file Profile.cpp.
{ // assume a non-crossing extent here. if ( key_ext.crossesDateLine() ) { OE_WARN << "Profile::addIntersectingTiles cannot process date-line cross" << std::endl; return; } double keyWidth = key_ext.width(); double keyHeight = key_ext.height(); double keyArea = keyWidth * keyHeight; // bail out if the key has a null extent. This might happen is the original key represents an // area in one profile that is out of bounds in this profile. if ( keyArea <= 0.0 ) return; int destLOD = 1; double destTileWidth, destTileHeight; int currLOD = 0; destLOD = currLOD; getTileDimensions(destLOD, destTileWidth, destTileHeight); //Find the LOD that most closely matches the area of the incoming key without going under. while (true) { currLOD++; double w, h; getTileDimensions(currLOD, w,h); //OE_INFO << std::fixed << " " << currLOD << "(" << destTileWidth << ", " << destTileHeight << ")" << std::endl; double a = w * h; if (a < keyArea) break; destLOD = currLOD; destTileWidth = w; destTileHeight = h; } //OE_DEBUG << std::fixed << " Source Tile: " << key.getLevelOfDetail() << " (" << keyWidth << ", " << keyHeight << ")" << std::endl; OE_DEBUG << std::fixed << " Dest Size: " << destLOD << " (" << destTileWidth << ", " << destTileHeight << ")" << std::endl; int tileMinX = (int)((key_ext.xMin() - _extent.xMin()) / destTileWidth); int tileMaxX = (int)((key_ext.xMax() - _extent.xMin()) / destTileWidth); int tileMinY = (int)((_extent.yMax() - key_ext.yMax()) / destTileHeight); int tileMaxY = (int)((_extent.yMax() - key_ext.yMin()) / destTileHeight); unsigned int numWide, numHigh; getNumTiles(destLOD, numWide, numHigh); tileMinX = osg::clampBetween(tileMinX, 0, (int)numWide-1); tileMaxX = osg::clampBetween(tileMaxX, 0, (int)numWide-1); tileMinY = osg::clampBetween(tileMinY, 0, (int)numHigh-1); tileMaxY = osg::clampBetween(tileMaxY, 0, (int)numHigh-1); OE_DEBUG << std::fixed << " Dest Tiles: " << tileMinX << "," << tileMinY << " => " << tileMaxX << "," << tileMaxY << std::endl; for (int i = tileMinX; i <= tileMaxX; ++i) { for (int j = tileMinY; j <= tileMaxY; ++j) { //TODO: does not support multi-face destination keys. out_intersectingKeys.push_back( TileKey(destLOD, i, j, this) ); } } OE_DEBUG << " Found " << out_intersectingKeys.size() << " keys " << std::endl; }
GeoExtent Profile::calculateExtent | ( | unsigned int | lod, |
unsigned int | tileX, | ||
unsigned int | tileY | ||
) | [virtual] |
Calculates an extent given a tile location in this profile.
Definition at line 359 of file Profile.cpp.
{ double width, height; getTileDimensions(lod, width, height); double xmin = getExtent().xMin() + (width * (double)tileX); double ymax = getExtent().yMax() - (height * (double)tileY); double xmax = xmin + width; double ymin = ymax - height; return GeoExtent( getSRS(), xmin, ymin, xmax, ymax ); }
GeoExtent Profile::clampAndTransformExtent | ( | const GeoExtent & | input, |
bool * | out_clamped = 0L |
||
) | const |
Clamps the incoming extents to the extents of this profile, and then converts the clamped extents to this profile's SRS, and returns the result. Returned GeoExtent::INVALID if the transformation fails.
Definition at line 458 of file Profile.cpp.
{ if ( out_clamped ) *out_clamped = false; // do the clamping in LAT/LONG. const SpatialReference* geo_srs = getSRS()->getGeographicSRS(); // get the input in lat/long: GeoExtent gcs_input = input.getSRS()->isGeographic()? input : input.transform( geo_srs ); if ( !gcs_input.isValid() ) return GeoExtent::INVALID; // clamp it to the profile's extents: GeoExtent clamped_gcs_input = GeoExtent( gcs_input.getSRS(), osg::clampBetween( gcs_input.xMin(), _latlong_extent.xMin(), _latlong_extent.xMax() ), osg::clampBetween( gcs_input.yMin(), _latlong_extent.yMin(), _latlong_extent.yMax() ), osg::clampBetween( gcs_input.xMax(), _latlong_extent.xMin(), _latlong_extent.xMax() ), osg::clampBetween( gcs_input.yMax(), _latlong_extent.yMin(), _latlong_extent.yMax() ) ); if ( out_clamped ) *out_clamped = (clamped_gcs_input != gcs_input); // finally, transform the clamped extent into this profile's SRS and return it. GeoExtent result = clamped_gcs_input.getSRS()->isEquivalentTo( this->getSRS() )? clamped_gcs_input : clamped_gcs_input.transform( this->getSRS() ); if (result.isValid()) { OE_DEBUG << LC << "clamp&xform: input=" << input.toString() << ", output=" << result.toString() << std::endl; } return result; }
const Profile * Profile::create | ( | const std::string & | srs_string, |
const std::string & | vsrs_string = "" , |
||
unsigned int | numTilesWideAtLod0 = 0 , |
||
unsigned int | numTilesHighAtLod0 = 0 |
||
) | [static] |
Definition at line 165 of file Profile.cpp.
{ const Profile* named = osgEarth::Registry::instance()->getNamedProfile( srsInitString ); if ( named ) return const_cast<Profile*>( named ); osg::ref_ptr<const SpatialReference> srs = SpatialReference::create( srsInitString ); osg::ref_ptr<const VerticalSpatialReference> vsrs = VerticalSpatialReference::create( vsrsInitString ); if ( srs.valid() && srs->isGeographic() ) { return new Profile( srs.get(), -180.0, -90.0, 180.0, 90.0, vsrs.get(), numTilesWideAtLod0, numTilesHighAtLod0 ); } else if ( srs.valid() && srs->isMercator() ) { // automatically figure out proper mercator extents: GDAL_SCOPED_LOCK; double e, dummy; srs->getGeographicSRS()->transform2D( 180.0, 0.0, srs.get(), e, dummy ); return Profile::create( srs.get(), -e, -e, e, e, vsrs.get(), numTilesWideAtLod0, numTilesHighAtLod0 ); } else { OE_WARN << LC << "Failed to create profile; SRS spec requires addition information: \"" << srsInitString << std::endl; } return NULL; }
const Profile * Profile::create | ( | const SpatialReference * | srs, |
double | xmin, | ||
double | ymin, | ||
double | xmax, | ||
double | ymax, | ||
double | geoxmin, | ||
double | geoymin, | ||
double | geoxmax, | ||
double | geoymax, | ||
const VerticalSpatialReference * | vsrs = 0L , |
||
unsigned int | numTilesWideAtLod0 = 0 , |
||
unsigned int | numTilesHighAtLod0 = 0 |
||
) | [static] |
Definition at line 148 of file Profile.cpp.
{ return new Profile( srs, xmin, ymin, xmax, ymax, geoxmin, geoymin, geoxmax, geoymax, vsrs, numTilesWideAtLod0, numTilesHighAtLod0 ); }
const Profile * Profile::create | ( | const ProfileOptions & | options | ) | [static] |
Definition at line 204 of file Profile.cpp.
{ const Profile* result = 0L; // Check for a "well known named" profile: if ( options.namedProfile().isSet() ) { result = osgEarth::Registry::instance()->getNamedProfile( options.namedProfile().value() ); } // Next check for a user-defined extents: else if ( options.srsString().isSet() && options.bounds().isSet() ) { if ( options.numTilesWideAtLod0().isSet() && options.numTilesHighAtLod0().isSet() ) { result = Profile::create( options.srsString().value(), options.bounds()->xMin(), options.bounds()->yMin(), options.bounds()->xMax(), options.bounds()->yMax(), options.vsrsString().value(), options.numTilesWideAtLod0().value(), options.numTilesHighAtLod0().value() ); } else { result = Profile::create( options.srsString().value(), options.bounds()->xMin(), options.bounds()->yMin(), options.bounds()->xMax(), options.bounds()->yMax(), options.vsrsString().value() ); } } // Next try SRS with default extents else if ( options.srsString().isSet() ) { result = Profile::create( options.srsString().value(), options.vsrsString().value() ); } return result; }
const Profile * Profile::create | ( | const std::string & | srs_string, |
double | xmin, | ||
double | ymin, | ||
double | xmax, | ||
double | ymax, | ||
const std::string & | vsrs_string = "" , |
||
unsigned int | numTilesWideAtLod0 = 0 , |
||
unsigned int | numTilesHighAtLod0 = 0 |
||
) | [static] |
Definition at line 118 of file Profile.cpp.
{ return new Profile( SpatialReference::create( srsInitString ), xmin, ymin, xmax, ymax, VerticalSpatialReference::create( vsrsInitString ), numTilesWideAtLod0, numTilesHighAtLod0 ); }
const Profile * Profile::create | ( | const SpatialReference * | srs, |
double | xmin, | ||
double | ymin, | ||
double | xmax, | ||
double | ymax, | ||
const VerticalSpatialReference * | vsrs = 0L , |
||
unsigned int | numTilesWideAtLod0 = 0 , |
||
unsigned int | numTilesHighAtLod0 = 0 |
||
) | [static] |
Definition at line 133 of file Profile.cpp.
{ return new Profile( srs, xmin, ymin, xmax, ymax, vsrs, numTilesWideAtLod0, numTilesHighAtLod0 ); }
TileKey Profile::createTileKey | ( | double | x, |
double | y, | ||
unsigned int | level | ||
) | const |
Creates a tile key for a tile that contains the input location at the specified LOD. Express the coordinates in the profile's SRS. Returns NULL if the point lies outside the profile's extents.
Definition at line 437 of file Profile.cpp.
{ if ( _extent.contains( x, y ) ) { int tilesX = (int)_numTilesWideAtLod0 * (1 << (int)level); int tilesY = (int)_numTilesHighAtLod0 * (1 << (int)level); double rx = (x - _extent.xMin()) / _extent.width(); int tileX = osg::clampBelow( (int)(rx * (double)tilesX), tilesX-1 ); double ry = (y - _extent.yMin()) / _extent.height(); int tileY = osg::clampBelow( (int)((1.0-ry) * (double)tilesY), tilesY-1 ); return TileKey( level, tileX, tileY, this ); } else { return TileKey::INVALID; } }
const GeoExtent & Profile::getExtent | ( | ) | const |
Gets the extent of the profile (in the profile's SRS)
Definition at line 320 of file Profile.cpp.
{ return _extent; }
void Profile::getIntersectingTiles | ( | const GeoExtent & | extent, |
std::vector< TileKey > & | out_intersectingKeys | ||
) | const [virtual] |
Gets the intersecting tiles of this Profile with the given extents
Reimplemented in osgEarth::UnifiedCubeProfile.
Definition at line 591 of file Profile.cpp.
{ GeoExtent ext = extent; // reproject into the profile's SRS if necessary: if ( ! getSRS()->isEquivalentTo( extent.getSRS() ) ) { // localize the extents and clamp them to legal values ext = clampAndTransformExtent( extent ); if ( !ext.isValid() ) return; } if ( ext.crossesDateLine() ) { GeoExtent first, second; if (ext.splitAcrossDateLine( first, second )) { addIntersectingTiles( first, out_intersectingKeys ); addIntersectingTiles( second, out_intersectingKeys ); } } else { addIntersectingTiles( ext, out_intersectingKeys ); } }
void Profile::getIntersectingTiles | ( | const TileKey & | key, |
std::vector< TileKey > & | out_intersectingKeys | ||
) | const |
Gets the intersecting tiles of this Profile with the given TileKey.
Definition at line 574 of file Profile.cpp.
{ OE_DEBUG << "GET ISECTING TILES for key " << key.str() << " -----------------" << std::endl; //If the profiles are exactly equal, just add the given tile key. if ( isEquivalentTo( key.getProfile() ) ) { //Clear the incoming list out_intersectingKeys.clear(); out_intersectingKeys.push_back(key); return; } return getIntersectingTiles(key.getExtent(), out_intersectingKeys); }
const GeoExtent & Profile::getLatLongExtent | ( | ) | const |
Gets the extent of the profile (in lat/long.)
Definition at line 325 of file Profile.cpp.
{ return _latlong_extent; }
unsigned int Profile::getLevelOfDetailForHorizResolution | ( | double | resolution, |
int | tileSize | ||
) | const |
Given an x-resolution, specified in the profile's SRS units, calculates and returns the closest LOD level.
Definition at line 422 of file Profile.cpp.
{ if ( tileSize <= 0 || resolution <= 0.0 ) return 0; double tileRes = (_extent.width() / (double)_numTilesWideAtLod0) / (double)tileSize; unsigned int level = 0; while( tileRes > resolution ) { level++; tileRes *= 0.5; } return level; }
void Profile::getNumTiles | ( | unsigned int | lod, |
unsigned int & | out_tiles_wide, | ||
unsigned int & | out_tiles_high | ||
) | const |
Gets the number wide and high at the given lod
Definition at line 409 of file Profile.cpp.
{ out_tiles_wide = _numTilesWideAtLod0; out_tiles_high = _numTilesHighAtLod0; for (unsigned int i = 0; i < lod; ++i) { out_tiles_wide *= 2; out_tiles_high *= 2; } }
Profile::ProfileType Profile::getProfileType | ( | ) | const |
Gets the profile type
Definition at line 300 of file Profile.cpp.
{ return _extent.isValid() && _extent.getSRS()->isGeographic() ? TYPE_GEODETIC : _extent.isValid() && _extent.getSRS()->isMercator() ? TYPE_MERCATOR : _extent.isValid() && _extent.getSRS()->isProjected() ? TYPE_LOCAL : TYPE_UNKNOWN; }
Profile::ProfileType Profile::getProfileTypeFromSRS | ( | const std::string & | srs | ) | [static] |
Deduces a profile type given an SRS string.
Definition at line 374 of file Profile.cpp.
{ osg::ref_ptr<SpatialReference> srs = SpatialReference::create( srs_string ); return srs.valid() && srs->isGeographic()? Profile::TYPE_GEODETIC : srs.valid() && srs->isMercator()? Profile::TYPE_MERCATOR : srs.valid() && srs->isProjected()? Profile::TYPE_LOCAL : Profile::TYPE_UNKNOWN; }
void Profile::getRootKeys | ( | std::vector< TileKey > & | out_keys | ) | const |
Gets the tile keys that comprise the tiles at the root (LOD 0) of this profile.
Definition at line 344 of file Profile.cpp.
{ out_keys.clear(); for (unsigned int c = 0; c < _numTilesWideAtLod0; ++c) { for (unsigned int r = 0; r < _numTilesHighAtLod0; ++r) { //TODO: upgrade to support multi-face profile: out_keys.push_back( TileKey(0, c, r, this) ); // lod, x, y, profile } } }
const SpatialReference * Profile::getSRS | ( | ) | const |
Gets the spatial reference system underlying this profile.
Definition at line 315 of file Profile.cpp.
void Profile::getTileDimensions | ( | unsigned int | lod, |
double & | out_width, | ||
double & | out_height | ||
) | const |
Gets the tile dimensions at the given lod.
Definition at line 396 of file Profile.cpp.
{ out_width = (_extent.xMax() - _extent.xMin()) / (double)_numTilesWideAtLod0; out_height = (_extent.yMax() - _extent.yMin()) / (double)_numTilesHighAtLod0; for (unsigned int i = 0; i < lod; ++i) { out_width /= 2.0; out_height /= 2.0; } }
const VerticalSpatialReference* osgEarth::Profile::getVerticalSRS | ( | ) | const [inline] |
bool Profile::isEquivalentTo | ( | const Profile * | rhs | ) | const |
Gets whether the two profiles can be treated as equivalent.
Definition at line 385 of file Profile.cpp.
{ return rhs && _extent.isValid() && rhs->getExtent().isValid() && _extent == rhs->getExtent() && _numTilesWideAtLod0 == rhs->_numTilesWideAtLod0 && _numTilesHighAtLod0 == rhs->_numTilesHighAtLod0; }
bool Profile::isOK | ( | ) | const |
Returns true if the profile is properly initialized.
Definition at line 310 of file Profile.cpp.
void osgEarth::Profile::setVerticalSRS | ( | const VerticalSpatialReference * | value | ) | [inline] |
std::string Profile::toString | ( | ) | const |
Returns a readable description of the profile.
Definition at line 330 of file Profile.cpp.
{ std::stringstream buf; buf << "[srs=" << _extent.getSRS()->getName() << ", min=" << _extent.xMin() << "," << _extent.yMin() << " max=" << _extent.xMax() << "," << _extent.yMax() << " lod0=" << _numTilesWideAtLod0 << "," << _numTilesHighAtLod0 << " vsrs=" << ( _vsrs.valid() ? _vsrs->getName() : "default" ) << "]"; std::string bufStr; bufStr = buf.str(); return bufStr; }
GeoExtent osgEarth::Profile::_extent [private] |
GeoExtent osgEarth::Profile::_latlong_extent [private] |
unsigned int osgEarth::Profile::_numTilesHighAtLod0 [private] |
unsigned int osgEarth::Profile::_numTilesWideAtLod0 [private] |
osg::ref_ptr<const VerticalSpatialReference> osgEarth::Profile::_vsrs [private] |