本文整理汇总了C++中TileKey::createParentKey方法的典型用法代码示例。如果您正苦于以下问题:C++ TileKey::createParentKey方法的具体用法?C++ TileKey::createParentKey怎么用?C++ TileKey::createParentKey使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类TileKey
的用法示例。
在下文中一共展示了TileKey::createParentKey方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: while
bool
OSGTileFactory::createValidGeoImage(ImageLayer* layer,
const TileKey& key,
GeoImage& out_image,
TileKey& out_actualTileKey,
ProgressCallback* progress)
{
//TODO: Redo this to just grab images from the parent TerrainTiles
//Try to create the image with the given key
out_actualTileKey = key;
while (out_actualTileKey.valid())
{
if ( layer->isKeyValid(out_actualTileKey) )
{
out_image = layer->createImage( out_actualTileKey, progress );
if ( out_image.valid() )
{
return true;
}
}
out_actualTileKey = out_actualTileKey.createParentKey();
}
return false;
}
示例2:
void
TileModelFactory::buildElevation(const TileKey& key,
const MapFrame& frame,
bool accumulate,
TileModel* model,
ProgressCallback* progress)
{
const MapInfo& mapInfo = frame.getMapInfo();
const osgEarth::ElevationInterpolation& interp =
frame.getMapOptions().elevationInterpolation().get();
// Request a heightfield from the map, falling back on lower resolution tiles
// if necessary (fallback=true)
osg::ref_ptr<osg::HeightField> hf;
bool isFallback = false;
if (_hfCache->getOrCreateHeightField(frame, key, accumulate, hf, isFallback, SAMPLE_FIRST_VALID, interp, progress))
{
model->_elevationData = TileModel::ElevationData(
hf,
GeoLocator::createForKey( key, mapInfo ),
isFallback );
// Edge normalization: requires adjacency information
if ( _terrainOptions.normalizeEdges() == true )
{
for( int x=-1; x<=1; x++ )
{
for( int y=-1; y<=1; y++ )
{
if ( x != 0 || y != 0 )
{
TileKey nk = key.createNeighborKey(x, y);
if ( nk.valid() )
{
osg::ref_ptr<osg::HeightField> hf;
if (_hfCache->getOrCreateHeightField(frame, nk, accumulate, hf, isFallback, SAMPLE_FIRST_VALID, interp, progress) )
{
model->_elevationData.setNeighbor( x, y, hf.get() );
}
}
}
}
}
// parent too.
if ( key.getLOD() > 0 )
{
osg::ref_ptr<osg::HeightField> hf;
if ( _hfCache->getOrCreateHeightField(frame, key.createParentKey(), accumulate, hf, isFallback, SAMPLE_FIRST_VALID, interp, progress) )
{
model->_elevationData.setParent( hf.get() );
}
}
}
}
}
示例3: TileModel
osg::Node*
MPTerrainEngineNode::createTile( const TileKey& key )
{
osg::ref_ptr<TileModel> model = new TileModel( _update_mapf->getRevision(), _update_mapf->getMapInfo() );
model->_tileKey = key;
model->_tileLocator = GeoLocator::createForKey(key, _update_mapf->getMapInfo());
// Build the heightfield
const MapInfo& mapInfo = _update_mapf->getMapInfo();
const osgEarth::ElevationInterpolation& interp = _update_mapf->getMapOptions().elevationInterpolation().get();
// Request a heightfield from the map, falling back on lower resolution tiles
osg::ref_ptr<osg::HeightField> hf;
TileKey sampleKey = key;
bool populated = false;
if (_update_mapf->elevationLayers().size() > 0)
{
while (!populated)
{
populated = _update_mapf->populateHeightField(hf, sampleKey, true, SAMPLE_FIRST_VALID);
if (!populated)
{
// Fallback on the parent
sampleKey = sampleKey.createParentKey();
if (!sampleKey.valid())
{
return 0;
}
}
}
}
if (!populated)
{
// We have no heightfield so just create a reference heightfield.
hf = HeightFieldUtils::createReferenceHeightField( key.getExtent(), 15, 15 );
sampleKey = key;
}
model->_elevationData = TileModel::ElevationData(
hf,
GeoLocator::createForKey( sampleKey, mapInfo ),
false );
bool optimizeTriangleOrientation = getMap()->getMapOptions().elevationInterpolation() != INTERP_TRIANGULATE;
osg::ref_ptr<TileModelCompiler> compiler = new TileModelCompiler(
_update_mapf->terrainMaskLayers(),
_update_mapf->modelLayers(),
_primaryUnit,
optimizeTriangleOrientation,
_terrainOptions );
return compiler->compile(model.get(), *_update_mapf, 0L);
}
示例4: while
bool
ElevationPool::fetchTileFromMap(const TileKey& key, MapFrame& frame, Tile* tile)
{
tile->_loadTime = osg::Timer::instance()->tick();
osg::ref_ptr<osg::HeightField> hf = new osg::HeightField();
hf->allocate( _tileSize, _tileSize );
// Initialize the heightfield to nodata
hf->getFloatArray()->assign( hf->getFloatArray()->size(), NO_DATA_VALUE );
TileKey keyToUse = key;
while( !tile->_hf.valid() && keyToUse.valid() )
{
bool ok;
if (_layers.empty())
{
OE_TEST << LC << "Populating from FULL MAP (" << keyToUse.str() << ")\n";
ok = frame.populateHeightField(hf, keyToUse, false /*heightsAsHAE*/, 0L);
}
else
{
OE_TEST << LC << "Populating from layers (" << keyToUse.str() << ")\n";
ok = _layers.populateHeightFieldAndNormalMap(hf.get(), 0L, keyToUse, 0L, INTERP_BILINEAR, 0L);
}
if (ok)
{
tile->_hf = GeoHeightField( hf.get(), keyToUse.getExtent() );
tile->_bounds = keyToUse.getExtent().bounds();
}
else
{
keyToUse = keyToUse.createParentKey();
}
}
return tile->_hf.valid();
}
示例5: bestKey
bool
ElevationLayerVector::populateHeightFieldAndNormalMap(osg::HeightField* hf,
NormalMap* normalMap,
const TileKey& key,
const Profile* haeProfile,
ElevationInterpolation interpolation,
ProgressCallback* progress ) const
{
// heightfield must already exist.
if ( !hf )
return false;
METRIC_SCOPED("ElevationLayer.populateHeightField");
// if the caller provided an "HAE map profile", he wants an HAE elevation grid even if
// the map profile has a vertical datum. This is the usual case when building the 3D
// terrain, for example. Construct a temporary key that doesn't have the vertical
// datum info and use that to query the elevation data.
TileKey keyToUse = key;
if ( haeProfile )
{
keyToUse = TileKey(key.getLOD(), key.getTileX(), key.getTileY(), haeProfile );
}
// Collect the valid layers for this tile.
LayerDataVector contenders;
LayerDataVector offsets;
#ifdef ANALYZE
struct LayerAnalysis {
LayerAnalysis() : samples(0), used(false), failed(false), fallback(false), actualKeyValid(true) { }
int samples; bool used; bool failed; bool fallback; bool actualKeyValid; std::string message;
};
std::map<ElevationLayer*, LayerAnalysis> layerAnalysis;
#endif
// Track the number of layers that would return fallback data.
unsigned numFallbackLayers = 0;
// Check them in reverse order since the highest priority is last.
for (int i = size()-1; i>=0; --i)
//for(ElevationLayerVector::const_reverse_iterator i = this->rbegin(); i != this->rend(); ++i)
{
ElevationLayer* layer = (*this)[i].get(); //i->get();
if ( layer->getEnabled() && layer->getVisible() )
{
// calculate the resolution-mapped key (adjusted for tile resolution differential).
TileKey mappedKey = keyToUse.mapResolution(
hf->getNumColumns(),
layer->getTileSize() );
bool useLayer = true;
TileKey bestKey( mappedKey );
// Check whether the non-mapped key is valid according to the user's min/max level settings:
if ( !layer->isKeyInLegalRange(key) )
{
useLayer = false;
}
// Find the "best available" mapped key from the tile source:
else
{
bestKey = layer->getBestAvailableTileKey(mappedKey);
if (bestKey.valid())
{
// If the bestKey is not the mappedKey, this layer is providing
// fallback data (data at a lower resolution than requested)
if ( mappedKey != bestKey )
{
numFallbackLayers++;
}
}
else
{
useLayer = false;
}
}
if ( useLayer )
{
if ( layer->isOffset() )
{
offsets.push_back(LayerData());
LayerData& ld = offsets.back();
ld.layer = layer;
ld.key = bestKey;
ld.index = i;
}
else
{
contenders.push_back(LayerData());
LayerData& ld = contenders.back();
ld.layer = layer;
ld.key = bestKey;
ld.index = i;
}
#ifdef ANALYZE
//.........这里部分代码省略.........
示例6: getProfile
GeoImage
ImageLayer::assembleImageFromTileSource(const TileKey& key,
ProgressCallback* progress)
{
GeoImage mosaicedImage, result;
// Scale the extent if necessary to apply an "edge buffer"
GeoExtent ext = key.getExtent();
if ( _runtimeOptions.edgeBufferRatio().isSet() )
{
double ratio = _runtimeOptions.edgeBufferRatio().get();
ext.scale(ratio, ratio);
}
// Get a set of layer tiles that intersect the requested extent.
std::vector<TileKey> intersectingKeys;
getProfile()->getIntersectingTiles( key, intersectingKeys );
if ( intersectingKeys.size() > 0 )
{
double dst_minx, dst_miny, dst_maxx, dst_maxy;
key.getExtent().getBounds(dst_minx, dst_miny, dst_maxx, dst_maxy);
// if we find at least one "real" tile in the mosaic, then the whole result tile is
// "real" (i.e. not a fallback tile)
bool retry = false;
ImageMosaic mosaic;
// keep track of failed tiles.
std::vector<TileKey> failedKeys;
for( std::vector<TileKey>::iterator k = intersectingKeys.begin(); k != intersectingKeys.end(); ++k )
{
GeoImage image = createImageFromTileSource( *k, progress );
if ( image.valid() )
{
if ( !isCoverage() )
{
ImageUtils::fixInternalFormat(image.getImage());
// Make sure all images in mosaic are based on "RGBA - unsigned byte" pixels.
// This is not the smarter choice (in some case RGB would be sufficient) but
// it ensure consistency between all images / layers.
//
// The main drawback is probably the CPU memory foot-print which would be reduced by allocating RGB instead of RGBA images.
// On GPU side, this should not change anything because of data alignements : often RGB and RGBA textures have the same memory footprint
//
if ( (image.getImage()->getDataType() != GL_UNSIGNED_BYTE)
|| (image.getImage()->getPixelFormat() != GL_RGBA) )
{
osg::ref_ptr<osg::Image> convertedImg = ImageUtils::convertToRGBA8(image.getImage());
if (convertedImg.valid())
{
image = GeoImage(convertedImg, image.getExtent());
}
}
}
mosaic.getImages().push_back( TileImage(image.getImage(), *k) );
}
else
{
// the tile source did not return a tile, so make a note of it.
failedKeys.push_back( *k );
if (progress && (progress->isCanceled() || progress->needsRetry()))
{
retry = true;
break;
}
}
}
if ( mosaic.getImages().empty() || retry )
{
// if we didn't get any data, fail.
OE_DEBUG << LC << "Couldn't create image for ImageMosaic " << std::endl;
return GeoImage::INVALID;
}
// We got at least one good tile, so go through the bad ones and try to fall back on
// lower resolution data to fill in the gaps. The entire mosaic must be populated or
// this qualifies as a bad tile.
for(std::vector<TileKey>::iterator k = failedKeys.begin(); k != failedKeys.end(); ++k)
{
GeoImage image;
for(TileKey parentKey = k->createParentKey();
parentKey.valid() && !image.valid();
parentKey = parentKey.createParentKey())
{
image = createImageFromTileSource( parentKey, progress );
if ( image.valid() )
{
GeoImage cropped;
if ( !isCoverage() )
{
ImageUtils::fixInternalFormat(image.getImage());
//.........这里部分代码省略.........
示例7: assembleImageFromTileSource
GeoImage
ImageLayer::createImageFromTileSource(const TileKey& key,
ProgressCallback* progress,
bool forceFallback,
bool& out_isFallback)
{
// Results:
//
// * return an osg::Image matching the key extent is all goes well;
//
// * return NULL to indicate that the key exceeds the maximum LOD of the source data,
// and that the engine may need to generate a "fallback" tile if necessary;
//
// deprecated:
// * return an "empty image" if the LOD is valid BUT the key does not intersect the
// source's data extents.
out_isFallback = false;
TileSource* source = getTileSource();
if ( !source )
return GeoImage::INVALID;
// If the profiles are different, use a compositing method to assemble the tile.
if ( !key.getProfile()->isEquivalentTo( getProfile() ) )
{
return assembleImageFromTileSource( key, progress, out_isFallback );
}
// Good to go, ask the tile source for an image:
osg::ref_ptr<TileSource::ImageOperation> op = _preCacheOp;
osg::ref_ptr<osg::Image> result;
if ( forceFallback )
{
// check if the tile source has any data coverage for the requested key.
// the LOD is ignore here and checked later
if ( !source->hasDataInExtent( key.getExtent() ) )
{
OE_DEBUG << LC << "createImageFromTileSource: hasDataInExtent(" << key.str() << ") == false" << std::endl;
return GeoImage::INVALID;
}
TileKey finalKey = key;
while( !result.valid() && finalKey.valid() )
{
if ( !source->getBlacklist()->contains( finalKey.getTileId() ) &&
source->hasDataForFallback(finalKey))
{
result = source->createImage( finalKey, op.get(), progress );
if ( result.valid() )
{
if ( finalKey.getLevelOfDetail() != key.getLevelOfDetail() )
{
// crop the fallback image to match the input key, and ensure that it remains the
// same pixel size; because chances are if we're requesting a fallback that we're
// planning to mosaic it later, and the mosaicer requires same-size images.
GeoImage raw( result.get(), finalKey.getExtent() );
GeoImage cropped = raw.crop( key.getExtent(), true, raw.getImage()->s(), raw.getImage()->t(), *_runtimeOptions.driver()->bilinearReprojection() );
result = cropped.takeImage();
}
}
}
if ( !result.valid() )
{
finalKey = finalKey.createParentKey();
out_isFallback = true;
}
}
if ( !result.valid() )
{
result = 0L;
//result = _emptyImage.get();
finalKey = key;
}
}
else
{
// Fail is the image is blacklisted.
if ( source->getBlacklist()->contains( key.getTileId() ) )
{
OE_DEBUG << LC << "createImageFromTileSource: blacklisted(" << key.str() << ")" << std::endl;
return GeoImage::INVALID;
}
if ( !source->hasData( key ) )
{
OE_DEBUG << LC << "createImageFromTileSource: hasData(" << key.str() << ") == false" << std::endl;
return GeoImage::INVALID;
}
result = source->createImage( key, op.get(), progress );
}
// Process images with full alpha to properly support MP blending.
if ( result != 0L && *_runtimeOptions.featherPixels())
{
ImageUtils::featherAlphaRegions( result.get() );
}
//.........这里部分代码省略.........
示例8: createImageInKeyProfile
GeoImage
ImageLayer::createImageInNativeProfile( const TileKey& key, ProgressCallback* progress, bool forceFallback, bool& out_isFallback)
{
out_isFallback = false;
const Profile* nativeProfile = getProfile();
if ( !nativeProfile )
{
OE_WARN << LC << "Could not establish the profile" << std::endl;
return GeoImage::INVALID;
}
if ( key.getProfile()->isEquivalentTo(nativeProfile) )
{
// requested profile matches native profile, move along.
return createImageInKeyProfile( key, progress, forceFallback, out_isFallback );
}
else
{
// find the intersection of keys.
std::vector<TileKey> nativeKeys;
nativeProfile->getIntersectingTiles(key.getExtent(), nativeKeys);
//OE_INFO << "KEY = " << key.str() << ":" << std::endl;
//for(int i=0; i<nativeKeys.size(); ++i)
// OE_INFO << " " << nativeKeys[i].str() << std::endl;
// build a mosaic of the images from the native profile keys:
bool foundAtLeastOneRealTile = false;
ImageMosaic mosaic;
for( std::vector<TileKey>::iterator k = nativeKeys.begin(); k != nativeKeys.end(); ++k )
{
bool isFallback = false;
GeoImage image = createImageInKeyProfile( *k, progress, true, isFallback );
if ( image.valid() )
{
mosaic.getImages().push_back( TileImage(image.getImage(), *k) );
if ( !isFallback )
foundAtLeastOneRealTile = true;
}
else
{
// if we get EVEN ONE invalid tile, we have to abort because there will be
// empty spots in the mosaic. (By "invalid" we mean a tile that could not
// even be resolved through the fallback procedure.)
return GeoImage::INVALID;
}
}
// bail out if we got nothing.
if ( mosaic.getImages().size() == 0 )
return GeoImage::INVALID;
// if the mosaic is ALL fallback data, this tile is fallback data.
if ( foundAtLeastOneRealTile )
{
// assemble new GeoImage from the mosaic.
double rxmin, rymin, rxmax, rymax;
mosaic.getExtents( rxmin, rymin, rxmax, rymax );
GeoImage result(
mosaic.createImage(),
GeoExtent( nativeProfile->getSRS(), rxmin, rymin, rxmax, rymax ) );
#if 1
return result;
#else // let's try this. why crop? Just leave it. Faster and more compatible with NPOT
// systems (like iOS)
// calculate a tigher extent that matches the original input key:
GeoExtent tightExtent = nativeProfile->clampAndTransformExtent( key.getExtent() );
// a non-exact crop is critical here to avoid resampling the data
return result.crop( tightExtent, false, 0, 0, *_runtimeOptions.driver()->bilinearReprojection() );
#endif
}
else // all fallback data
{
GeoImage result;
if ( forceFallback && key.getLevelOfDetail() > 0 )
{
result = createImageInNativeProfile(
key.createParentKey(),
progress,
forceFallback,
out_isFallback );
}
out_isFallback = true;
return result;
}
//if ( !foundAtLeastOneRealTile )
// out_isFallback = true;
//.........这里部分代码省略.........
示例9: bestKey
//.........这里部分代码省略.........
bool realData = false;
//unsigned int numFallback = 0;
unsigned int total = numColumns * numRows;
unsigned int completed = 0;
for (unsigned c = 0; c < numColumns; ++c)
{
double x = xmin + (dx * (double)c);
for (unsigned r = 0; r < numRows; ++r)
{
double y = ymin + (dy * (double)r);
// Collect elevations from each layer as necessary.
bool resolved = false;
for(int i=0; i<contenders.size() && !resolved; ++i)
{
if ( heightFailed[i] )
continue;
ElevationLayer* layer = contenders[i].first.get();
GeoHeightField& layerHF = heightFields[i];
if ( !layerHF.valid() )
{
layerHF = layer->createHeightField(contenders[i].second, progress);
if ( !layerHF.valid() )
{
// This layer potentially has data or it wouldn't have ended up in the contendors list, so try falling back on the parent
TileKey parentKey = contenders[i].second.createParentKey();
while (!layerHF.valid() && parentKey.valid())
{
//numFallback++;
//osg::Timer_t fbStartTime = osg::Timer::instance()->tick();
GeoHeightField parentHF = layer->createHeightField(parentKey, progress);
//osg::Timer_t fbEndTime = osg::Timer::instance()->tick();
// Only penalize time wasted actually falling back.
//if (!parentHF.valid())
// {
// fallBackTime += osg::Timer::instance()->delta_m(fbStartTime, fbEndTime);
//}
if (parentHF.valid())
{
layerHF = parentHF;
break;
}
else
{
parentKey = parentKey.createParentKey();
}
}
if (!layerHF.valid())
{
heightFailed[i] = true;
continue;
}
}
else
示例10: TileModel
void
TileModelFactory::createTileModel(const TileKey& key,
const MapFrame& frame,
bool accumulate,
osg::ref_ptr<TileModel>& out_model,
ProgressCallback* progress)
{
osg::ref_ptr<TileModel> model = new TileModel( frame.getRevision(), frame.getMapInfo() );
model->_useParentData = _terrainReqs->parentTexturesRequired();
model->_tileKey = key;
model->_tileLocator = GeoLocator::createForKey(key, frame.getMapInfo());
OE_START_TIMER(fetch_imagery);
// Fetch the image data and make color layers.
unsigned index = 0;
unsigned order = 0;
for( ImageLayerVector::const_iterator i = frame.imageLayers().begin(); i != frame.imageLayers().end(); ++i )
{
ImageLayer* layer = i->get();
if ( layer->getEnabled() && layer->isKeyInRange(key) )
{
BuildColorData build;
build.init( key, layer, order, frame.getMapInfo(), _terrainOptions, _liveTiles.get(), model.get() );
bool addedToModel = build.execute(progress);
if ( addedToModel )
{
// only bump the order if we added something to the data model.
order++;
}
}
}
if (progress)
progress->stats()["fetch_imagery_time"] += OE_STOP_TIMER(fetch_imagery);
// make an elevation layer.
OE_START_TIMER(fetch_elevation);
buildElevation(key, frame, accumulate, _terrainReqs->elevationTexturesRequired(), model.get(), progress);
if (progress)
progress->stats()["fetch_elevation_time"] += OE_STOP_TIMER(fetch_elevation);
// make a normal map layer (if necessary)
if ( _terrainReqs->normalTexturesRequired() )
{
OE_START_TIMER(fetch_normalmap);
buildNormalMap(key, frame, accumulate, model.get(), progress);
if (progress)
progress->stats()["fetch_normalmap_time"] += OE_STOP_TIMER(fetch_normalmap);
}
// If nothing was added, not even a fallback heightfield, something went
// horribly wrong. Leave without a tile model. Chances are that a parent tile
// not not found in the live-tile registry.
if ( model->_colorData.size() == 0 && !model->_elevationData.getHeightField() )
{
return;
}
// OK we are making a tile, so if there's no heightfield yet, make an empty one (and mark it
// as fallback data of course)
if ( !model->_elevationData.getHeightField() )
{
osg::HeightField* hf = HeightFieldUtils::createReferenceHeightField( key.getExtent(), 15, 15 );
model->_elevationData = TileModel::ElevationData(
hf,
GeoLocator::createForKey(key, frame.getMapInfo()),
true );
}
// look up the parent model and cache it.
osg::ref_ptr<TileNode> parentTile;
if ( _liveTiles->get(key.createParentKey(), parentTile) )
{
model->_parentModel = parentTile->getTileModel();
}
out_model = model.release();
}
示例11:
void
TileModelFactory::buildElevation(const TileKey& key,
const MapFrame& frame,
bool accumulate,
bool buildTexture,
TileModel* model,
ProgressCallback* progress)
{
const MapInfo& mapInfo = frame.getMapInfo();
const osgEarth::ElevationInterpolation& interp =
frame.getMapOptions().elevationInterpolation().get();
// Request a heightfield from the map, falling back on lower resolution tiles
// if necessary (fallback=true)
osg::ref_ptr<osg::HeightField> hf;
bool isFallback = false;
// look up the parent's heightfield to use as a template
osg::ref_ptr<osg::HeightField> parentHF;
TileKey parentKey = key.createParentKey();
if ( accumulate )
{
osg::ref_ptr<TileNode> parentNode;
if (_liveTiles->get(parentKey, parentNode))
{
parentHF = parentNode->getTileModel()->_elevationData.getHeightField();
if ( _debug && key.getLOD() > 0 && !parentHF.valid() )
{
OE_NOTICE << LC << "Could not find a parent tile HF for " << key.str() << "\n";
}
}
}
// Make a new heightfield:
if (_meshHFCache->getOrCreateHeightField(frame, key, parentHF.get(), hf, isFallback, SAMPLE_FIRST_VALID, interp, progress))
{
model->_elevationData = TileModel::ElevationData(
hf,
GeoLocator::createForKey( key, mapInfo ),
isFallback );
// Edge normalization: requires adjacency information
if ( _terrainOptions.normalizeEdges() == true )
{
for( int x=-1; x<=1; x++ )
{
for( int y=-1; y<=1; y++ )
{
if ( x != 0 || y != 0 )
{
TileKey neighborKey = key.createNeighborKey(x, y);
if ( neighborKey.valid() )
{
osg::ref_ptr<osg::HeightField> neighborParentHF;
if ( accumulate )
{
TileKey neighborParentKey = neighborKey.createParentKey();
if (neighborParentKey == parentKey)
{
neighborParentHF = parentHF;
}
else
{
osg::ref_ptr<TileNode> neighborParentNode;
if (_liveTiles->get(neighborParentKey, neighborParentNode))
{
neighborParentHF = neighborParentNode->getTileModel()->_elevationData.getHeightField();
}
}
}
// only pull the tile if we have a valid parent HF for it -- otherwise
// you might get a flat tile when upsampling data.
if ( neighborParentHF.valid() )
{
osg::ref_ptr<osg::HeightField> hf;
if (_meshHFCache->getOrCreateHeightField(frame, neighborKey, neighborParentHF.get(), hf, isFallback, SAMPLE_FIRST_VALID, interp, progress) )
{
model->_elevationData.setNeighbor( x, y, hf.get() );
}
}
}
}
}
}
// parent too.
if ( parentHF.valid() )
{
model->_elevationData.setParent( parentHF.get() );
}
}
if ( buildTexture )
{
model->generateElevationTexture();
}
}
//.........这里部分代码省略.........
示例12: getMaxLevel
bool
ElevationQuery::getElevationImpl(const GeoPoint& point,
double& out_elevation,
double desiredResolution,
double* out_actualResolution)
{
osg::Timer_t start = osg::Timer::instance()->tick();
if ( _mapf.elevationLayers().empty() )
{
// this means there are no heightfields.
out_elevation = 0.0;
return true;
}
// tile size (resolution of elevation tiles)
unsigned tileSize = std::max(_mapf.getMapOptions().elevationTileSize().get(), 2u);
//This is the max resolution that we actually have data at this point
unsigned int bestAvailLevel = getMaxLevel( point.x(), point.y(), point.getSRS(), _mapf.getProfile());
if (desiredResolution > 0.0)
{
unsigned int desiredLevel = _mapf.getProfile()->getLevelOfDetailForHorizResolution( desiredResolution, tileSize );
if (desiredLevel < bestAvailLevel) bestAvailLevel = desiredLevel;
}
OE_DEBUG << LC << "Best available data level " << point.x() << ", " << point.y() << " = " << bestAvailLevel << std::endl;
// transform the input coords to map coords:
GeoPoint mapPoint = point;
if ( point.isValid() && !point.getSRS()->isHorizEquivalentTo( _mapf.getProfile()->getSRS() ) )
{
mapPoint = point.transform(_mapf.getProfile()->getSRS());
if ( !mapPoint.isValid() )
{
OE_WARN << LC << "Fail: coord transform failed" << std::endl;
return false;
}
}
// get the tilekey corresponding to the tile we need:
TileKey key = _mapf.getProfile()->createTileKey( mapPoint.x(), mapPoint.y(), bestAvailLevel );
if ( !key.valid() )
{
OE_WARN << LC << "Fail: coords fall outside map" << std::endl;
return false;
}
bool result = false;
while (!result)
{
GeoHeightField geoHF;
TileCache::Record record;
// Try to get the hf from the cache
if ( _cache.get( key, record ) )
{
geoHF = record.value();
}
else
{
// Create it
osg::ref_ptr<osg::HeightField> hf = new osg::HeightField();
hf->allocate( tileSize, tileSize );
// Initialize the heightfield to nodata
for (unsigned int i = 0; i < hf->getFloatArray()->size(); i++)
{
hf->getFloatArray()->at( i ) = NO_DATA_VALUE;
}
if (_mapf.populateHeightField( hf, key ) )
{
geoHF = GeoHeightField( hf.get(), key.getExtent() );
_cache.insert( key, geoHF );
}
}
if (geoHF.valid())
{
float elevation = 0.0f;
result = geoHF.getElevation( mapPoint.getSRS(), mapPoint.x(), mapPoint.y(), _mapf.getMapInfo().getElevationInterpolation(), mapPoint.getSRS(), elevation);
if (result && elevation != NO_DATA_VALUE)
{
// see what the actual resolution of the heightfield is.
if ( out_actualResolution )
*out_actualResolution = geoHF.getXInterval();
out_elevation = (double)elevation;
break;
}
else
{
result = false;
}
}
if (!result)
{
key = key.createParentKey();
if (!key.valid())
//.........这里部分代码省略.........
示例13: if
bool
ElevationLayerVector::createHeightField(const TileKey& key,
bool fallback,
const Profile* haeProfile,
ElevationInterpolation interpolation,
ElevationSamplePolicy samplePolicy,
osg::ref_ptr<osg::HeightField>& out_result,
bool* out_isFallback,
ProgressCallback* progress ) const
{
unsigned lowestLOD = key.getLevelOfDetail();
bool hfInitialized = false;
//Get a HeightField for each of the enabled layers
GeoHeightFieldVector heightFields;
//The number of fallback heightfields we have
int numFallbacks = 0;
//Default to being fallback data.
if ( out_isFallback )
{
*out_isFallback = true;
}
// if the caller provided an "HAE map profile", he wants an HAE elevation grid even if
// the map profile has a vertical datum. This is the usual case when building the 3D
// terrain, for example. Construct a temporary key that doesn't have the vertical
// datum info and use that to query the elevation data.
TileKey keyToUse = key;
if ( haeProfile )
{
keyToUse = TileKey(key.getLevelOfDetail(), key.getTileX(), key.getTileY(), haeProfile );
}
// Generate a heightfield for each elevation layer.
unsigned defElevSize = 8;
for( ElevationLayerVector::const_iterator i = this->begin(); i != this->end(); i++ )
{
ElevationLayer* layer = i->get();
if ( layer->getVisible() )
{
GeoHeightField geoHF = layer->createHeightField( keyToUse, progress );
// if "fallback" is set, try to fall back on lower LODs.
if ( !geoHF.valid() && fallback )
{
TileKey hf_key = keyToUse.createParentKey();
while ( hf_key.valid() && !geoHF.valid() )
{
geoHF = layer->createHeightField( hf_key, progress );
if ( !geoHF.valid() )
hf_key = hf_key.createParentKey();
}
if ( geoHF.valid() )
{
if ( hf_key.getLevelOfDetail() < lowestLOD )
lowestLOD = hf_key.getLevelOfDetail();
//This HeightField is fallback data, so increment the count.
numFallbacks++;
}
}
if ( geoHF.valid() )
{
heightFields.push_back( geoHF );
}
}
}
//If any of the layers produced valid data then it's not considered a fallback
if ( out_isFallback )
{
*out_isFallback = (numFallbacks == heightFields.size());
//OE_NOTICE << "Num fallbacks=" << numFallbacks << " numHeightFields=" << heightFields.size() << " is fallback " << *out_isFallback << std::endl;
}
if ( heightFields.size() == 0 )
{
//If we got no heightfields but were requested to fallback, create an empty heightfield.
if ( fallback )
{
out_result = HeightFieldUtils::createReferenceHeightField( keyToUse.getExtent(), defElevSize, defElevSize );
return true;
}
else
{
//We weren't requested to fallback so just return.
return false;
}
}
else if (heightFields.size() == 1)
{
if ( lowestLOD == key.getLevelOfDetail() )
//.........这里部分代码省略.........
示例14: getProfile
osg::HeightField*
ElevationLayer::assembleHeightFieldFromTileSource(const TileKey& key,
ProgressCallback* progress)
{
osg::HeightField* result = 0L;
// Collect the heightfields for each of the intersecting tiles.
GeoHeightFieldVector heightFields;
//Determine the intersecting keys
std::vector< TileKey > intersectingTiles;
getProfile()->getIntersectingTiles( key, intersectingTiles );
// collect heightfield for each intersecting key. Note, we're hitting the
// underlying tile source here, so there's no vetical datum shifts happening yet.
// we will do that later.
if ( intersectingTiles.size() > 0 )
{
for (unsigned int i = 0; i < intersectingTiles.size(); ++i)
{
const TileKey& layerKey = intersectingTiles[i];
if ( isKeyValid(layerKey) )
{
osg::HeightField* hf = createHeightFieldFromTileSource( layerKey, progress );
if ( hf )
{
heightFields.push_back( GeoHeightField(hf, layerKey.getExtent()) );
}
else
{
//We couldn't get a heightfield at the given key so fall back on parent tiles
TileKey parentKey = layerKey.createParentKey();
while (!hf && parentKey.valid())
{
hf = createHeightFieldFromTileSource( parentKey, progress );
if (hf)
{
heightFields.push_back( GeoHeightField(hf, parentKey.getExtent()) );
break;
}
parentKey = parentKey.createParentKey();
}
}
}
}
}
// 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 x = minx + (dx * (double)c);
for (unsigned r = 0; r < height; ++r)
{
double y = 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)
{
// get the elevation value, at the same time transforming it vertically into the
// requesting key's vertical datum.
float e = 0.0;
if (itr->getElevation(key.getExtent().getSRS(), x, y, INTERP_BILINEAR, key.getExtent().getSRS(), e))
{
elevation = e;
break;
}
}
result->setHeight( c, r, elevation );
}
}
}
return result;
}
示例15: mapf
void
TileModelFactory::createTileModel(const TileKey& key,
osg::ref_ptr<TileModel>& out_model,
bool& out_hasRealData,
bool& out_hasLodBlendedLayers )
{
MapFrame mapf( _map, Map::MASKED_TERRAIN_LAYERS );
const MapInfo& mapInfo = mapf.getMapInfo();
osg::ref_ptr<TileModel> model = new TileModel();
model->_tileKey = key;
model->_tileLocator = GeoLocator::createForKey(key, mapInfo);
// 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;
// Fetch the image data and make color layers.
for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i )
{
ImageLayer* layer = i->get();
if ( layer->getEnabled() )
{
BuildColorData build;
build.init( key, layer, mapInfo, _terrainOptions, model.get() );
build.execute();
if ( layer->getImageLayerOptions().lodBlending() == true )
{
out_hasLodBlendedLayers = true;
}
}
}
// make an elevation layer.
BuildElevationData build;
build.init( key, mapf, _terrainOptions, model.get(), _hfCache );
build.execute();
// Bail out now if there's no data to be had.
if ( model->_colorData.size() == 0 && !model->_elevationData.getHFLayer() )
{
return;
}
// OK we are making a tile, so if there's no heightfield yet, make an empty one.
if ( !model->_elevationData.getHFLayer() )
{
osg::HeightField* hf = HeightFieldUtils::createReferenceHeightField( key.getExtent(), 8, 8 );
osgTerrain::HeightFieldLayer* hfLayer = new osgTerrain::HeightFieldLayer( hf );
hfLayer->setLocator( GeoLocator::createForKey(key, mapInfo) );
model->_elevationData = TileModel::ElevationData( 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 = model->_elevationData.getHFLayer()->getLocator();
for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); ++i )
{
ImageLayer* layer = i->get();
if ( layer->getEnabled() && !layer->isKeyValid(key) )
{
if ( !emptyImage.valid() )
emptyImage = ImageUtils::createEmptyImage();
model->_colorData[i->get()->getUID()] = TileModel::ColorData(
layer,
emptyImage.get(),
locator,
key.getLevelOfDetail(),
key,
true );
}
}
// Ready to create the actual tile.
//AssembleTile assemble;
//assemble.init( key, mapInfo, _terrainOptions, model.get(), mapf.terrainMaskLayers() );
//assemble.execute();
// if we're using LOD blending, find and add the parent's state set.
if ( out_hasLodBlendedLayers && key.getLevelOfDetail() > 0 && _liveTiles.valid() )
{
osg::ref_ptr<TileNode> parent;
if ( _liveTiles->get( key.createParentKey(), parent ) )
{
model->_parentStateSet = parent->getPublicStateSet();
}
}
if (!out_hasRealData)
{
//.........这里部分代码省略.........