osgEarth 2.1.1
|
A map terrain layer containing elevation grid heightfields.
Definition at line 73 of file ElevationLayer.
ElevationLayer::ElevationLayer | ( | const ElevationLayerOptions & | options | ) |
Constructs a new elevation layer with the specified options. It expects the layer options to contain a reference to the neccesary driver options.
Definition at line 99 of file ElevationLayer.cpp.
: TerrainLayer ( &_runtimeOptions ), _runtimeOptions( options ) { init(); }
ElevationLayer::ElevationLayer | ( | const std::string & | name, |
const TileSourceOptions & | driverOptions | ||
) |
Constructs a new elevation layer with the specific name and driver options. The layer will load its driver by using the tilesource options.
Definition at line 106 of file ElevationLayer.cpp.
: TerrainLayer ( &_runtimeOptions ), _runtimeOptions( ElevationLayerOptions(name, driverOptions) ) { init(); }
ElevationLayer::ElevationLayer | ( | const ElevationLayerOptions & | options, |
TileSource * | tileSource | ||
) |
Constructs a new elevation layer with the specified layer options and with a custom TileSource instance created by the user.
Definition at line 113 of file ElevationLayer.cpp.
: TerrainLayer ( &_runtimeOptions, tileSource ), _runtimeOptions( options ) { init(); }
void ElevationLayer::addCallback | ( | ElevationLayerCallback * | cb | ) |
Adds a property notification callback to this layer
Definition at line 139 of file ElevationLayer.cpp.
{ _callbacks.push_back( cb ); }
GeoHeightField ElevationLayer::createGeoHeightField | ( | const TileKey & | key, |
ProgressCallback * | progress | ||
) | [protected, virtual] |
Definition at line 183 of file ElevationLayer.cpp.
{ osg::HeightField* hf = 0L; //osg::ref_ptr<osg::HeightField> hf; TileSource* source = getTileSource(); //Only try to get the tile if it isn't blacklisted if (!source->getBlacklist()->contains( key.getTileId() )) { //Only try to get data if the source actually has data if (source->hasData( key ) ) { hf = source->createHeightField( key, _preCacheOp.get(), progress ); //Blacklist the tile if we can't get it and it wasn't cancelled if ( !hf && (!progress || !progress->isCanceled())) { source->getBlacklist()->add(key.getTileId()); } } else { OE_DEBUG << LC << "Source for layer \"" << getName() << "\" has no data at " << key.str() << std::endl; } } else { OE_DEBUG << LC << "Tile " << key.str() << " is blacklisted " << std::endl; } return hf ? GeoHeightField( hf, key.getExtent(), getProfile()->getVerticalSRS() ) : GeoHeightField::INVALID; }
osg::HeightField * ElevationLayer::createHeightField | ( | const TileKey & | key, |
ProgressCallback * | progress = 0L |
||
) |
Creates a GeoHeightField for this layer that corresponds to the extents and LOD in the specified TileKey. The returned HeightField will always match the geospatial extents of that TileKey.
Definition at line 220 of file ElevationLayer.cpp.
{ osg::HeightField* result = 0L; //osg::ref_ptr<osg::HeightField> result; const Profile* layerProfile = getProfile(); const Profile* mapProfile = key.getProfile(); if ( !layerProfile ) { OE_WARN << LC << "Could not get a valid profile for Layer \"" << getName() << "\"" << std::endl; return 0L; } if ( !isCacheOnly() && !getTileSource() ) { OE_WARN << LC << "Error: ElevationLayer does not have a valid TileSource, cannot create heightfield " << std::endl; return 0L; } //Write the layer properties if they haven't been written yet. Heightfields are always stored in the map profile. if (!_cacheProfile.valid() && _cache.valid() && _runtimeOptions.cacheEnabled() == true && _tileSource.valid()) { _cacheProfile = mapProfile; if ( _tileSource->isOK() ) { _cache->storeProperties( _cacheSpec, _cacheProfile.get(), _tileSource->getPixelsPerTile() ); } } //See if we can get it from the cache. if (_cache.valid() && _runtimeOptions.cacheEnabled() == true ) { osg::ref_ptr<const osg::HeightField> cachedHF; if ( _cache->getHeightField( key, _cacheSpec, cachedHF ) ) { OE_DEBUG << LC << "ElevationLayer::createHeightField got tile " << key.str() << " from layer \"" << getName() << "\" from cache " << std::endl; // make a copy: result = new osg::HeightField( *cachedHF.get() ); } } //in cache-only mode, if the cache fetch failed, bail out. if ( result == 0L && isCacheOnly() ) { return 0L; } if ( result == 0L && getTileSource() && getTileSource()->isOK() ) { //If the profiles are equivalent, get the HF from the TileSource. if (key.getProfile()->isEquivalentTo( getProfile() )) { if (isKeyValid( key ) ) { GeoHeightField hf = createGeoHeightField( key, progress ); if (hf.valid()) { result = hf.takeHeightField(); } } } else { //Collect the heightfields for each of the intersecting tiles. //typedef std::vector< GeoHeightField > HeightFields; GeoHeightFieldVector heightFields; //Determine the intersecting keys std::vector< TileKey > intersectingTiles; getProfile()->getIntersectingTiles(key, intersectingTiles); if (intersectingTiles.size() > 0) { for (unsigned int i = 0; i < intersectingTiles.size(); ++i) { if (isKeyValid( intersectingTiles[i] ) ) { GeoHeightField hf = createGeoHeightField( intersectingTiles[i], progress ); if (hf.valid()) { heightFields.push_back(hf); } } } } //If we actually got a HeightField, resample/reproject it to match the incoming TileKey's extents. if (heightFields.size() > 0) { unsigned int width = 0; unsigned int height = 0; for (GeoHeightFieldVector::iterator itr = heightFields.begin(); itr != heightFields.end(); ++itr) { if (itr->getHeightField()->getNumColumns() > width) width = itr->getHeightField()->getNumColumns(); if (itr->getHeightField()->getNumRows() > height) height = itr->getHeightField()->getNumRows(); } result = new osg::HeightField(); result->allocate(width, height); //Go ahead and set up the heightfield so we don't have to worry about it later double minx, miny, maxx, maxy; key.getExtent().getBounds(minx, miny, maxx, maxy); double dx = (maxx - minx)/(double)(width-1); double dy = (maxy - miny)/(double)(height-1); //Create the new heightfield by sampling all of them. for (unsigned int c = 0; c < width; ++c) { double geoX = minx + (dx * (double)c); for (unsigned r = 0; r < height; ++r) { double geoY = miny + (dy * (double)r); //For each sample point, try each heightfield. The first one with a valid elevation wins. float elevation = NO_DATA_VALUE; for (GeoHeightFieldVector::iterator itr = heightFields.begin(); itr != heightFields.end(); ++itr) { float e = 0.0; if (itr->getElevation(key.getExtent().getSRS(), geoX, geoY, INTERP_BILINEAR, _profile->getVerticalSRS(), e)) { elevation = e; break; } } result->setHeight( c, r, elevation ); } } } } //Write the result to the cache. if (result && _cache.valid() && _runtimeOptions.cacheEnabled() == true ) { _cache->setHeightField( key, _cacheSpec, result ); } } //Initialize the HF values for osgTerrain if ( result ) { //Go ahead and set up the heightfield so we don't have to worry about it later double minx, miny, maxx, maxy; key.getExtent().getBounds(minx, miny, maxx, maxy); result->setOrigin( osg::Vec3d( minx, miny, 0.0 ) ); double dx = (maxx - minx)/(double)(result->getNumColumns()-1); double dy = (maxy - miny)/(double)(result->getNumRows()-1); result->setXInterval( dx ); result->setYInterval( dy ); result->setBorderWidth( 0 ); } return result; }
void ElevationLayer::fireCallback | ( | TerrainLayerCallbackMethodPtr | method | ) | [private, virtual] |
Implements osgEarth::TerrainLayer.
Definition at line 153 of file ElevationLayer.cpp.
{ for( ElevationLayerCallbackList::const_iterator i = _callbacks.begin(); i != _callbacks.end(); ++i ) { ElevationLayerCallback* cb = i->get(); (cb->*method)( this ); } }
void ElevationLayer::fireCallback | ( | ElevationLayerCallbackMethodPtr | method | ) | [private, virtual] |
Definition at line 163 of file ElevationLayer.cpp.
{ for( ElevationLayerCallbackList::const_iterator i = _callbacks.begin(); i != _callbacks.end(); ++i ) { ElevationLayerCallback* cb = i->get(); (cb->*method)( this ); } }
const ElevationLayerOptions& osgEarth::ElevationLayer::getElevationLayerOptions | ( | ) | const [inline] |
Gets the initialization options with which the layer was created.
Definition at line 95 of file ElevationLayer.
{ return _runtimeOptions; }
virtual const TerrainLayerOptions& osgEarth::ElevationLayer::getTerrainLayerOptions | ( | ) | const [inline, virtual] |
The options data connected to this layer.
Reimplemented from osgEarth::TerrainLayer.
Definition at line 96 of file ElevationLayer.
{ return _runtimeOptions; }
void ElevationLayer::init | ( | ) | [private] |
Reimplemented from osgEarth::TerrainLayer.
Definition at line 121 of file ElevationLayer.cpp.
{ _tileSize = 32; }
void ElevationLayer::initTileSource | ( | ) | [protected, virtual] |
Reimplemented from osgEarth::TerrainLayer.
Definition at line 173 of file ElevationLayer.cpp.
{ // call superclass first. TerrainLayer::initTileSource(); if ( _tileSource.valid() ) _preCacheOp = new ElevationLayerPreCacheOperation( _tileSource.get() ); }
void ElevationLayer::removeCallback | ( | ElevationLayerCallback * | cb | ) |
Removes a property notification callback from this layer
Definition at line 145 of file ElevationLayer.cpp.
{ ElevationLayerCallbackList::iterator i = std::find( _callbacks.begin(), _callbacks.end(), cb ); if ( i != _callbacks.end() ) _callbacks.erase( i ); }
std::string ElevationLayer::suggestCacheFormat | ( | ) | const [protected, virtual] |
Reimplemented from osgEarth::TerrainLayer.
Definition at line 127 of file ElevationLayer.cpp.
{ #if OSG_MIN_VERSION_REQUIRED(2,8,0) //OSG 2.8 onwards should use TIF for heightfields return "tif"; #else //OSG 2.8 and below should use DDS return "dds"; #endif }
Definition at line 126 of file ElevationLayer.
osg::ref_ptr<TileSource::HeightFieldOperation> osgEarth::ElevationLayer::_preCacheOp [private] |
Definition at line 130 of file ElevationLayer.
Reimplemented from osgEarth::TerrainLayer.
Definition at line 124 of file ElevationLayer.