|
osgEarth 2.1.1
|
Inheritance diagram for TileBuilder:
Collaboration diagram for TileBuilder:Classes | |
| struct | Job |
| struct | SourceRepo |
Public Member Functions | |
| TileBuilder (const Map *map, const OSGTerrainOptions &terrainOptions, TaskService *service) | |
| void | createTile (const TileKey &key, bool parallelize, osg::ref_ptr< Tile > &out_tile, bool &out_hasRealData, bool &out_hasLodBlendedLayers) |
| Job * | createJob (const TileKey &key, Threading::MultiEvent &semaphore) |
| void | runJob (Job *job) |
| void | finalizeJob (Job *job, osg::ref_ptr< Tile > &out_tile, bool &out_hasRealData, bool &out_hasLodBlending) |
| TaskService * | getTaskService () const |
Private Attributes | |
| const Map * | _map |
| TaskService * | _service |
| const OSGTerrainOptions & | _terrainOptions |
Definition at line 30 of file TileBuilder.
| TileBuilder::TileBuilder | ( | const Map * | map, |
| const OSGTerrainOptions & | terrainOptions, | ||
| TaskService * | service | ||
| ) |
Definition at line 182 of file TileBuilder.cpp.
: _map( map ), _terrainOptions( terrainOptions ), _service( service ) { //nop }
| TileBuilder::Job * TileBuilder::createJob | ( | const TileKey & | key, |
| Threading::MultiEvent & | semaphore | ||
| ) |
Definition at line 191 of file TileBuilder.cpp.
{
Job* job = new Job( key, _map );
// create the image layer tasks:
for( ImageLayerVector::const_iterator i = job->_mapf.imageLayers().begin(); i != job->_mapf.imageLayers().end(); ++i )
{
ImageLayer* layer = i->get();
if ( layer->isKeyValid(key) )
{
ParallelTask<BuildColorLayer>* j = new ParallelTask<BuildColorLayer>( &semaphore );
j->init( key, layer, job->_mapf.getMapInfo(), _terrainOptions, job->_repo );
j->setPriority( -(float)key.getLevelOfDetail() );
job->_tasks.push_back( j );
}
}
// If we have elevation layers, start an elevation job as well. Otherwise just create an
// empty one while we're waiting for the images to load.
if ( job->_mapf.elevationLayers().size() > 0 )
{
ParallelTask<BuildElevLayer>* ej = new ParallelTask<BuildElevLayer>( &semaphore );
ej->init( key, job->_mapf, _terrainOptions, job->_repo );
ej->setPriority( -(float)key.getLevelOfDetail() );
job->_tasks.push_back( ej );
}
return job;
}
Here is the call graph for this function:
Here is the caller graph for this function:| void TileBuilder::createTile | ( | const TileKey & | key, |
| bool | parallelize, | ||
| osg::ref_ptr< Tile > & | out_tile, | ||
| bool & | out_hasRealData, | ||
| bool & | out_hasLodBlendedLayers | ||
| ) |
Definition at line 304 of file TileBuilder.cpp.
{
MapFrame mapf( _map, Map::MASKED_TERRAIN_LAYERS );
SourceRepo repo;
// init this to false, then search for real data. "Real data" is data corresponding
// directly to the key, as opposed to fallback data, which is derived from a lower
// LOD key.
out_hasRealData = false;
out_hasLodBlendedLayers = false;
const MapInfo& mapInfo = mapf.getMapInfo();
// If we need more than one layer, fetch them in parallel.
// TODO: change the test based on isKeyValid total.
if ( parallelize && (mapf.imageLayers().size() + mapf.elevationLayers().size() > 1) )
{
// count the valid layers.
int jobCount = 0;
for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i )
{
if ( i->get()->isKeyValid( key ) )
++jobCount;
if ( i->get()->getImageLayerOptions().lodBlending() == true )
out_hasLodBlendedLayers = true;
}
if ( mapf.elevationLayers().size() > 0 )
++jobCount;
// A thread job monitoring event:
Threading::MultiEvent semaphore( jobCount );
// Start the image layer jobs:
for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i )
{
ImageLayer* layer = i->get();
if ( layer->isKeyValid(key) )
{
ParallelTask<BuildColorLayer>* j = new ParallelTask<BuildColorLayer>( &semaphore );
j->init( key, layer, mapInfo, _terrainOptions, repo );
j->setPriority( -(float)key.getLevelOfDetail() );
_service->add( j );
}
}
// If we have elevation layers, start an elevation job as well. Otherwise just create an
// empty one while we're waiting for the images to load.
if ( mapf.elevationLayers().size() > 0 )
{
ParallelTask<BuildElevLayer>* ej = new ParallelTask<BuildElevLayer>( &semaphore );
ej->init( key, mapf, _terrainOptions, repo );
ej->setPriority( -(float)key.getLevelOfDetail() );
_service->add( ej );
}
else
{
BuildElevLayer build;
build.init( key, mapf, _terrainOptions, repo );
build.execute();
}
// Wait for all the jobs to finish.
semaphore.wait();
}
// Fetch the image data serially:
else
{
// gather all the image layers serially.
for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i )
{
ImageLayer* layer = i->get();
if ( layer->isKeyValid(key) )
{
BuildColorLayer build;
build.init( key, layer, mapInfo, _terrainOptions, repo );
build.execute();
}
if ( layer->getImageLayerOptions().lodBlending() == true )
out_hasLodBlendedLayers = true;
}
// make an elevation layer.
BuildElevLayer build;
build.init( key, mapf, _terrainOptions, repo );
build.execute();
}
// Bail out now if there's no data to be had.
if ( repo._colorLayers.size() == 0 && !repo._elevLayer.getHFLayer() )
{
return;
}
// OK we are making a tile, so if there's no heightfield yet, make an empty one.
if ( !repo._elevLayer.getHFLayer() )
{
osg::HeightField* hf = key.getProfile()->getVerticalSRS()->createReferenceHeightField( key.getExtent(), 8, 8 );
osgTerrain::HeightFieldLayer* hfLayer = new osgTerrain::HeightFieldLayer( hf );
hfLayer->setLocator( GeoLocator::createForKey(key, mapInfo) );
repo._elevLayer = CustomElevLayer( hfLayer, true );
}
// Now, if there are any color layers that did not get built, create them with an empty
// image so the shaders have something to draw.
osg::ref_ptr<osg::Image> emptyImage;
osgTerrain::Locator* locator = repo._elevLayer.getHFLayer()->getLocator();
for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i )
{
if ( !i->get()->isKeyValid(key) )
{
if ( !emptyImage.valid() )
emptyImage = ImageUtils::createEmptyImage();
repo.add( CustomColorLayer(
i->get(), emptyImage.get(),
locator,
key.getLevelOfDetail(),
key,
true ) );
}
}
//osg::Vec3dArray* maskBounds = 0L;
//osgEarth::MaskLayer* mask = mapf.getTerrainMaskLayer();
//if (mask)
// maskBounds = mask->getOrCreateBoundary();
// Ready to create the actual tile.
AssembleTile assemble;
assemble.init( key, mapInfo, _terrainOptions, repo, mapf.terrainMaskLayers() );
assemble.execute();
if (!out_hasRealData)
{
// Check the results and see if we have any real data.
for( ColorLayersByUID::const_iterator i = repo._colorLayers.begin(); i != repo._colorLayers.end(); ++i )
{
if ( !i->second.isFallbackData() )
{
out_hasRealData = true;
break;
}
}
}
if ( !out_hasRealData && !repo._elevLayer.isFallbackData() )
{
out_hasRealData = true;
}
out_tile = assemble._tile;
}
Here is the call graph for this function:
Here is the caller graph for this function:| void TileBuilder::finalizeJob | ( | TileBuilder::Job * | job, |
| osg::ref_ptr< Tile > & | out_tile, | ||
| bool & | out_hasRealData, | ||
| bool & | out_hasLodBlending | ||
| ) |
Definition at line 229 of file TileBuilder.cpp.
{
SourceRepo& repo = job->_repo;
out_hasRealData = false;
out_hasLodBlending = false;
// Bail out now if there's no data to be had.
if ( repo._colorLayers.size() == 0 && !repo._elevLayer.getHFLayer() )
{
return;
}
const TileKey& key = job->_key;
const MapInfo& mapInfo = job->_mapf.getMapInfo();
// OK we are making a tile, so if there's no heightfield yet, make an empty one.
if ( !repo._elevLayer.getHFLayer() )
{
osg::HeightField* hf = key.getProfile()->getVerticalSRS()->createReferenceHeightField( key.getExtent(), 8, 8 );
osgTerrain::HeightFieldLayer* hfLayer = new osgTerrain::HeightFieldLayer( hf );
hfLayer->setLocator( GeoLocator::createForKey(key, mapInfo) );
repo._elevLayer = CustomElevLayer( hfLayer, true );
}
// Now, if there are any color layers that did not get built, create them with an empty
// image so the shaders have something to draw.
osg::ref_ptr<osg::Image> emptyImage;
osgTerrain::Locator* locator = repo._elevLayer.getHFLayer()->getLocator();
for( ImageLayerVector::const_iterator i = job->_mapf.imageLayers().begin(); i != job->_mapf.imageLayers().end(); ++i )
{
if ( !i->get()->isKeyValid(key) )
{
if ( !emptyImage.valid() )
emptyImage = ImageUtils::createEmptyImage();
repo.add( CustomColorLayer(
i->get(), emptyImage.get(),
locator,
key.getLevelOfDetail(),
key,
true ) );
}
if ( i->get()->getImageLayerOptions().lodBlending() == true )
out_hasLodBlending = true;
}
// Ready to create the actual tile.
AssembleTile assemble;
assemble.init( key, mapInfo, _terrainOptions, repo );
assemble.execute();
// Check the results and see if we have any real data.
for( ColorLayersByUID::const_iterator i = repo._colorLayers.begin(); i != repo._colorLayers.end(); ++i )
{
if ( !i->second.isFallbackData() )
{
out_hasRealData = true;
break;
}
}
if ( !out_hasRealData && !repo._elevLayer.isFallbackData() )
{
out_hasRealData = true;
}
out_tile = assemble._tile;
}
Here is the call graph for this function:
Here is the caller graph for this function:| TaskService* TileBuilder::getTaskService | ( | ) | const [inline] |
Definition at line 87 of file TileBuilder.
{ return _service; }
| void TileBuilder::runJob | ( | TileBuilder::Job * | job | ) |
const Map* TileBuilder::_map [private] |
Definition at line 90 of file TileBuilder.
TaskService* TileBuilder::_service [private] |
Definition at line 91 of file TileBuilder.
const OSGTerrainOptions& TileBuilder::_terrainOptions [private] |
Definition at line 92 of file TileBuilder.
1.7.3