本文整理汇总了C++中GeoImage::getImage方法的典型用法代码示例。如果您正苦于以下问题:C++ GeoImage::getImage方法的具体用法?C++ GeoImage::getImage怎么用?C++ GeoImage::getImage使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GeoImage
的用法示例。
在下文中一共展示了GeoImage::getImage方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: GeoImage
GeoImage
ImageLayer::createImageInKeyProfile( const TileKey& key, ProgressCallback* progress, bool forceFallback, bool& out_isFallback )
{
GeoImage result;
out_isFallback = false;
// If the layer is disabled, bail out.
if ( !getEnabled() )
{
return GeoImage::INVALID;
}
// Check the max data level, which limits the LOD of available data.
if ( _runtimeOptions.maxDataLevel().isSet() && key.getLOD() > _runtimeOptions.maxDataLevel().value() )
{
return GeoImage::INVALID;
}
// Check for a "Minumum level" setting on this layer. If we are before the
// min level, just return the empty image. Do not cache empties
if ( _runtimeOptions.minLevel().isSet() && key.getLOD() < _runtimeOptions.minLevel().value() )
{
return GeoImage( _emptyImage.get(), key.getExtent() );
}
// Check for a "Minimum resolution" setting on the layer. If we are before the
// min resolution, return the empty image. Do not cache empties.
if ( _runtimeOptions.minResolution().isSet() )
{
double keyres = key.getExtent().width() / getTileSize();
double keyresInLayerProfile = key.getProfile()->getSRS()->transformUnits(keyres, getProfile()->getSRS());
if ( keyresInLayerProfile > _runtimeOptions.minResolution().value() )
{
return GeoImage( _emptyImage.get(), key.getExtent() );
}
}
OE_DEBUG << LC << "create image for \"" << key.str() << "\", ext= "
<< key.getExtent().toString() << std::endl;
// locate the cache bin for the target profile for this layer:
CacheBin* cacheBin = getCacheBin( key.getProfile() );
// validate that we have either a valid tile source, or we're cache-only.
if ( ! (getTileSource() || (isCacheOnly() && cacheBin) ) )
{
OE_WARN << LC << "Error: layer does not have a valid TileSource, cannot create image " << std::endl;
_runtimeOptions.enabled() = false;
return GeoImage::INVALID;
}
// validate the existance of a valid layer profile (unless we're in cache-only mode, in which
// case there is no layer profile)
if ( !isCacheOnly() && !getProfile() )
{
OE_WARN << LC << "Could not establish a valid profile" << std::endl;
_runtimeOptions.enabled() = false;
return GeoImage::INVALID;
}
// First, attempt to read from the cache. Since the cached data is stored in the
// map profile, we can try this first.
if ( cacheBin && getCachePolicy().isCacheReadable() )
{
ReadResult r = cacheBin->readImage( key.str(), getCachePolicy().getMinAcceptTime() );
if ( r.succeeded() )
{
ImageUtils::normalizeImage( r.getImage() );
return GeoImage( r.releaseImage(), key.getExtent() );
}
}
// The data was not in the cache. If we are cache-only, fail sliently
if ( isCacheOnly() )
{
return GeoImage::INVALID;
}
// Get an image from the underlying TileSource.
result = createImageFromTileSource( key, progress, forceFallback, out_isFallback );
// Normalize the image if necessary
if ( result.valid() )
{
ImageUtils::normalizeImage( result.getImage() );
}
// If we got a result, the cache is valid and we are caching in the map profile, write to the map cache.
if (result.valid() &&
//JB: Removed the check to not write out fallback data. If you have a low resolution base dataset (max lod 3) and a high resolution insert (max lod 22)
// then the low res data needs to "fallback" from LOD 4 - 22 so you can display the high res inset. If you don't cache these intermediate tiles then
// performance can suffer generating all those fallback tiles, especially if you have to do reprojection or mosaicing.
//!out_isFallback &&
cacheBin &&
getCachePolicy().isCacheWriteable() )
{
if ( key.getExtent() != result.getExtent() )
//.........这里部分代码省略.........
示例2: refresh
void
OSGTerrainEngineNode::addImageLayer( ImageLayer* layerAdded )
{
if ( !layerAdded )
return;
if (!_isStreaming)
{
refresh();
}
else
{
// visit all existing terrain tiles and inform each one of the new image layer:
TileVector tiles;
_terrain->getTiles( tiles );
for( TileVector::iterator itr = tiles.begin(); itr != tiles.end(); ++itr )
{
Tile* tile = itr->get();
StreamingTile* streamingTile = 0L;
GeoImage geoImage;
bool needToUpdateImagery = false;
int imageLOD = -1;
if ( !_isStreaming || tile->getKey().getLevelOfDetail() == 1 )
{
// in standard mode, or at the first LOD in seq/pre mode, fetch the image immediately.
TileKey geoImageKey = tile->getKey();
_tileFactory->createValidGeoImage( layerAdded, tile->getKey(), geoImage, geoImageKey );
imageLOD = tile->getKey().getLevelOfDetail();
}
else
{
// in seq/pre mode, set up a placeholder and mark the tile as dirty.
geoImage = GeoImage(ImageUtils::createEmptyImage(), tile->getKey().getExtent() );
needToUpdateImagery = true;
streamingTile = static_cast<StreamingTile*>(tile);
}
if (geoImage.valid())
{
const MapInfo& mapInfo = _update_mapf->getMapInfo();
double img_min_lon, img_min_lat, img_max_lon, img_max_lat;
geoImage.getExtent().getBounds(img_min_lon, img_min_lat, img_max_lon, img_max_lat);
//Specify a new locator for the color with the coordinates of the TileKey that was actually used to create the image
osg::ref_ptr<GeoLocator> img_locator = tile->getKey().getProfile()->getSRS()->createLocator(
img_min_lon, img_min_lat, img_max_lon, img_max_lat,
!mapInfo.isGeocentric() );
//Set the CS to geocentric if we are dealing with a geocentric map
if ( mapInfo.isGeocentric() )
{
img_locator->setCoordinateSystemType( osgTerrain::Locator::GEOCENTRIC );
}
tile->setCustomColorLayer( CustomColorLayer(
layerAdded,
geoImage.getImage(),
img_locator.get(), imageLOD, tile->getKey() ) );
// if necessary, tell the tile to queue up a new imagery request (since we
// just installed a placeholder)
if ( needToUpdateImagery )
{
streamingTile->updateImagery( layerAdded, *_update_mapf, _tileFactory.get() );
}
}
else
{
// this can happen if there's no data in the new layer for the given tile.
// we will rely on the driver to dump out a warning if this is an error.
}
tile->applyImmediateTileUpdate( TileUpdate::ADD_IMAGE_LAYER, layerAdded->getUID() );
}
updateTextureCombining();
}
}
示例3: 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;
//.........这里部分代码省略.........
示例4: 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;
for( std::vector<TileKey>::iterator k = intersectingKeys.begin(); k != intersectingKeys.end(); ++k )
{
double minX, minY, maxX, maxY;
k->getExtent().getBounds(minX, minY, maxX, maxY);
GeoImage image = createImageFromTileSource( *k, progress );
if ( image.valid() )
{
ImageUtils::normalizeImage(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.
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;
}
// all set. Mosaic all the images together.
double rxmin, rymin, rxmax, rymax;
mosaic.getExtents( rxmin, rymin, rxmax, rymax );
mosaicedImage = GeoImage(
mosaic.createImage(),
GeoExtent( getProfile()->getSRS(), rxmin, rymin, rxmax, rymax ) );
}
else
{
OE_DEBUG << LC << "assembleImageFromTileSource: no intersections (" << key.str() << ")" << std::endl;
}
// Final step: transform the mosaic into the requesting key's extent.
if ( mosaicedImage.valid() )
{
// GeoImage::reproject() will automatically crop the image to the correct extents.
// so there is no need to crop after reprojection. Also note that if the SRS's are the
// same (even though extents are different), then this operation is technically not a
// reprojection but merely a resampling.
result = mosaicedImage.reproject(
key.getProfile()->getSRS(),
&key.getExtent(),
*_runtimeOptions.reprojectedTileSize(),
//.........这里部分代码省略.........
示例5: tileExtent
void
TextureCompositorTexArray::applyLayerUpdate(osg::StateSet* stateSet,
UID layerUID,
const GeoImage& preparedImage,
const TileKey& tileKey,
const TextureLayout& layout,
osg::StateSet* parentStateSet) const
{
GeoExtent tileExtent(tileKey.getExtent());
int slot = layout.getSlot( layerUID );
if ( slot < 0 )
return; // means the layer no longer exists
// access the texture array, creating or growing it if necessary:
osg::Texture2DArray* texture = s_getTexture( stateSet, layout, 0,
textureSize() );
ensureSampler( stateSet, 0 );
// assign the new image at the proper position in the texture array.
osg::Image* image = preparedImage.getImage();
assignImage(texture, slot, image);
// update the region uniform to reflect the geo extent of the image:
const GeoExtent& imageExtent = preparedImage.getExtent();
osg::Vec4 tileTransform;
getImageTransform(tileExtent, imageExtent, tileTransform);
// access the region uniform, creating or growing it if necessary:
ArrayUniform regionUni( "region", osg::Uniform::FLOAT, stateSet, layout.getMaxUsedSlot()+1 );
if ( regionUni.isValid() )
{
int layerOffset = slot * 8;
for (int i = 0; i < 4; ++i)
regionUni.setElement( layerOffset + i, tileTransform[i]);
//region->dirty();
}
if ( layout.isBlendingEnabled( layerUID ) && regionUni.isValid() )
{
osg::Uniform* secondarySampler = ensureSampler( stateSet, 1 );
osg::Texture2DArray* parentTexture = 0;
const unsigned parentLayerOffset = slot * 8 + 4;
if ( parentStateSet )
{
ArrayUniform parentRegion( "region", osg::Uniform::FLOAT, parentStateSet, layout.getMaxUsedSlot()+1 );
//osg::Uniform* parentRegion = s_getRegionUniform( parentStateSet,
// layout );
GeoExtent parentExtent(tileKey.createParentKey().getExtent());
float widthRatio, heightRatio;
parentRegion.getElement(slot * 8 + 2, widthRatio);
parentRegion.getElement(slot * 8 + 3, heightRatio);
float parentImageWidth = parentExtent.width() / widthRatio;
float parentImageHeight = parentExtent.height() / heightRatio;
float xRatio, yRatio;
parentRegion.getElement(slot * 8, xRatio);
parentRegion.getElement(slot * 8 + 1, yRatio);
float ParentImageXmin = parentExtent.xMin() - xRatio * parentImageWidth;
float ParentImageYmin = parentExtent.yMin() - yRatio * parentImageHeight;
regionUni.setElement(parentLayerOffset,
static_cast<float>((tileExtent.xMin() - ParentImageXmin) / parentImageWidth));
regionUni.setElement(parentLayerOffset + 1,
static_cast<float>((tileExtent.yMin() - ParentImageYmin) / parentImageHeight));
regionUni.setElement(parentLayerOffset + 2,
static_cast<float>(tileExtent.width() / parentImageWidth));
regionUni.setElement(parentLayerOffset + 3,
static_cast<float>(tileExtent.height() / parentImageHeight));
//regionUni.dirty();
parentTexture = static_cast<osg::Texture2DArray*>(parentStateSet->getTextureAttribute(0, osg::StateAttribute::TEXTURE));
}
else
{
// setting the parent transform values to -1 disabled blending for this layer. #hack -gw
for (int i = 0; i < 4; ++i)
regionUni.setElement(parentLayerOffset + i, tileTransform[i]);
}
if (parentTexture)
stateSet->setTextureAttribute(1, parentTexture, osg::StateAttribute::ON);
else
secondarySampler->set(0);
// update the timestamp on the image layer to support fade-in blending.
float now = (float)osg::Timer::instance()->delta_s( osg::Timer::instance()->getStartTick(), osg::Timer::instance()->tick() );
ArrayUniform stampUniform( "osgearth_SlotStamp", osg::Uniform::FLOAT, stateSet, layout.getMaxUsedSlot()+1 );
stampUniform.setElement( slot, now );
}
}
示例6: GeoImage
GeoImage
ImageLayer::createImageInKeyProfile(const TileKey& key,
ProgressCallback* progress)
{
GeoImage result;
// If the layer is disabled, bail out.
if ( !getEnabled() )
{
return GeoImage::INVALID;
}
// Make sure the request is in range.
if ( !isKeyInRange(key) )
{
return GeoImage::INVALID;
}
OE_DEBUG << LC << "create image for \"" << key.str() << "\", ext= "
<< key.getExtent().toString() << std::endl;
// Check the layer L2 cache first
if ( _memCache.valid() )
{
CacheBin* bin = _memCache->getOrCreateBin( key.getProfile()->getFullSignature() );
ReadResult result = bin->readObject(key.str() );
if ( result.succeeded() )
return GeoImage(static_cast<osg::Image*>(result.releaseObject()), key.getExtent());
//_memCache->dumpStats(key.getProfile()->getFullSignature());
}
// locate the cache bin for the target profile for this layer:
CacheBin* cacheBin = getCacheBin( key.getProfile() );
// validate that we have either a valid tile source, or we're cache-only.
if ( ! (getTileSource() || (isCacheOnly() && cacheBin) ) )
{
OE_WARN << LC << "Error: layer does not have a valid TileSource, cannot create image " << std::endl;
_runtimeOptions.enabled() = false;
return GeoImage::INVALID;
}
// validate the existance of a valid layer profile (unless we're in cache-only mode, in which
// case there is no layer profile)
if ( !isCacheOnly() && !getProfile() )
{
OE_WARN << LC << "Could not establish a valid profile" << std::endl;
_runtimeOptions.enabled() = false;
return GeoImage::INVALID;
}
osg::ref_ptr< osg::Image > cachedImage;
// First, attempt to read from the cache. Since the cached data is stored in the
// map profile, we can try this first.
if ( cacheBin && getCachePolicy().isCacheReadable() )
{
ReadResult r = cacheBin->readImage( key.str() );
if ( r.succeeded() )
{
cachedImage = r.releaseImage();
ImageUtils::normalizeImage( cachedImage.get() );
bool expired = getCachePolicy().isExpired(r.lastModifiedTime());
if (!expired)
{
OE_DEBUG << "Got cached image for " << key.str() << std::endl;
return GeoImage( cachedImage.get(), key.getExtent() );
}
else
{
OE_DEBUG << "Expired image for " << key.str() << std::endl;
}
}
}
// The data was not in the cache. If we are cache-only, fail sliently
if ( isCacheOnly() )
{
// If it's cache only and we have an expired but cached image, just return it.
if (cachedImage.valid())
{
return GeoImage( cachedImage.get(), key.getExtent() );
}
else
{
return GeoImage::INVALID;
}
}
// Get an image from the underlying TileSource.
result = createImageFromTileSource( key, progress );
// Normalize the image if necessary
if ( result.valid() )
{
ImageUtils::normalizeImage( result.getImage() );
}
// memory cache first:
if ( result.valid() && _memCache.valid() )
//.........这里部分代码省略.........
示例7: getProfile
GeoImage
ImageLayer::assembleImageFromTileSource(const TileKey& key,
ProgressCallback* progress,
bool& out_isFallback)
{
GeoImage mosaicedImage, result;
out_isFallback = false;
// 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( ext, 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 foundAtLeastOneRealTile = false;
bool retry = false;
ImageMosaic mosaic;
for( std::vector<TileKey>::iterator k = intersectingKeys.begin(); k != intersectingKeys.end(); ++k )
{
double minX, minY, maxX, maxY;
k->getExtent().getBounds(minX, minY, maxX, maxY);
bool isFallback = false;
GeoImage image = createImageFromTileSource( *k, progress, true, isFallback );
if ( image.valid() )
{
// make sure the image is RGBA.
// (TODO: investigate whether we still need this -gw 6/25/2012)
if (image.getImage()->getPixelFormat() != GL_RGBA || image.getImage()->getDataType() != GL_UNSIGNED_BYTE || image.getImage()->getInternalTextureFormat() != GL_RGBA8 )
{
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) );
if ( !isFallback )
foundAtLeastOneRealTile = true;
}
else
{
// the tile source did not return a tile, so make a note of it.
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;
}
// all set. Mosaic all the images together.
double rxmin, rymin, rxmax, rymax;
mosaic.getExtents( rxmin, rymin, rxmax, rymax );
mosaicedImage = GeoImage(
mosaic.createImage(),
GeoExtent( getProfile()->getSRS(), rxmin, rymin, rxmax, rymax ) );
if ( !foundAtLeastOneRealTile )
out_isFallback = true;
}
else
{
OE_DEBUG << LC << "assembleImageFromTileSource: no intersections (" << key.str() << ")" << std::endl;
}
// Final step: transform the mosaic into the requesting key's extent.
if ( mosaicedImage.valid() )
{
// GeoImage::reproject() will automatically crop the image to the correct extents.
// so there is no need to crop after reprojection. Also note that if the SRS's are the
// same (even though extents are different), then this operation is technically not a
// reprojection but merely a resampling.
result = mosaicedImage.reproject(
key.getProfile()->getSRS(),
//.........这里部分代码省略.........
示例8: if
//.........这里部分代码省略.........
numValidImages++;
}
}
//Try to fallback on any empty images if we have some valid images but not valid images for ALL layers
if (numValidImages > 0 && numValidImages < images.size())
{
for (unsigned int i = 0; i < images.size(); i++)
{
ImageInfo& info = images[i];
if (!info.image.valid() && info.dataInExtents)
{
TileKey parentKey = key.createParentKey();
TileSource* source = _options._components[i]._tileSourceInstance;
if (source)
{
osg::ref_ptr< ImageLayerPreCacheOperation > preCacheOp;
if ( _options._components[i]._imageLayerOptions.isSet() )
{
preCacheOp = new ImageLayerPreCacheOperation();
preCacheOp->_processor.init( _options._components[i]._imageLayerOptions.value(), _dbOptions.get(), true );
}
osg::ref_ptr< osg::Image > image;
while (!image.valid() && parentKey.valid())
{
image = source->createImage( parentKey, preCacheOp.get(), progress );
if (image.valid())
{
break;
}
parentKey = parentKey.createParentKey();
}
if (image.valid())
{
//We got an image, but now we need to crop it to match the incoming key's extents
GeoImage geoImage( image.get(), parentKey.getExtent());
GeoImage cropped = geoImage.crop( key.getExtent(), true, textureSize.x(), textureSize.y());
image = cropped.getImage();
}
info.image = image.get();
}
}
}
}
//Recompute the number of valid images
numValidImages = 0;
for (unsigned int i = 0; i < images.size(); i++)
{
ImageInfo& info = images[i];
if (info.image.valid()) numValidImages++;
}
if ( progress && progress->isCanceled() )
{
return 0L;
}
else if ( numValidImages == 0 )
{
return 0L;
}
else if ( numValidImages == 1 )
{
//We only have one valid image, so just return it and don't bother with compositing
for (unsigned int i = 0; i < images.size(); i++)
{
ImageInfo& info = images[i];
if (info.image.valid())
return info.image.release();
}
return 0L;
}
else
{
osg::Image* result = 0;
for (unsigned int i = 0; i < images.size(); i++)
{
ImageInfo& imageInfo = images[i];
if (!result)
{
if (imageInfo.image.valid())
{
result = new osg::Image( *imageInfo.image.get());
}
}
else
{
if (imageInfo.image.valid())
{
ImageUtils::mix( result, imageInfo.image, imageInfo.opacity );
}
}
}
return result;
}
}
示例9: createFeatureCursor
FeatureCursor* createFeatureCursor( const Symbology::Query& query )
{
unsigned w, h;
query.tileKey()->getProfile()->getNumTiles( query.tileKey()->getLevelOfDetail(), w, h );
TileKey key = TileKey(query.tileKey()->getLevelOfDetail(), query.tileKey()->getTileX(), h - query.tileKey()->getTileY() -1, query.tileKey()->getProfile() );
#if 0
// Debug
Polygon* poly = new Polygon();
poly->push_back(key.getExtent().xMin(), key.getExtent().yMin());
poly->push_back(key.getExtent().xMax(), key.getExtent().yMin());
poly->push_back(key.getExtent().xMax(), key.getExtent().yMax());
poly->push_back(key.getExtent().xMin(), key.getExtent().yMax());
FeatureList features;
Feature* feature = new Feature(poly, SpatialReference::create("wgs84"));
features.push_back( feature );
return new FeatureListCursor( features );
#else
osg::ref_ptr< osgEarth::ImageLayer > layer = query.getMap()->getImageLayerByName(*_options.layer());
if (layer.valid())
{
GeoImage image = layer->createImage( key );
FeatureList features;
if (image.valid())
{
double pixWidth = key.getExtent().width() / (double)image.getImage()->s();
double pixHeight = key.getExtent().height() / (double)image.getImage()->t();
ImageUtils::PixelReader reader(image.getImage());
for (unsigned int r = 0; r < image.getImage()->t(); r++)
{
double y = key.getExtent().yMin() + (double)r * pixHeight;
double minX = 0;
double maxX = 0;
float value = 0.0;
for (unsigned int c = 0; c < image.getImage()->s(); c++)
{
double x = key.getExtent().xMin() + (double)c * pixWidth;
osg::Vec4f color = reader(c, r);
// Starting a new row. Initialize the values.
if (c == 0)
{
minX = x;
maxX = x + pixWidth;
value = color.r();
}
// Ending a row, finish the polygon.
else if (c == image.getImage()->s() -1)
{
// Increment the maxX to finish the row.
maxX = x + pixWidth;
Polygon* poly = new Polygon();
poly->push_back(minX, y);
poly->push_back(maxX, y);
poly->push_back(maxX, y+pixHeight);
poly->push_back(minX, y+pixHeight);
Feature* feature = new Feature(poly, SpatialReference::create("wgs84"));
feature->set(*_options.attribute(), value);
features.push_back( feature );
minX = x;
maxX = x + pixWidth;
value = color.r();
}
// The value is different, so complete the polygon and start a new one.
else if (color.r() != value)
{
Polygon* poly = new Polygon();
poly->push_back(minX, y);
poly->push_back(maxX, y);
poly->push_back(maxX, y+pixHeight);
poly->push_back(minX, y+pixHeight);
Feature* feature = new Feature(poly, SpatialReference::create("wgs84"));
feature->set(*_options.attribute(), value);
features.push_back( feature );
minX = x;
maxX = x + pixWidth;
value = color.r();
}
// The value is the same as the previous value, continue the polygon by increasing the maxX.
else if (color.r() == value)
{
maxX = x + pixWidth;
}
}
}
if (!features.empty())
{
//OE_NOTICE << LC << "Returning " << features.size() << " features" << std::endl;
return new FeatureListCursor( features );
}
//.........这里部分代码省略.........
示例10: if
osg::Image*
CompositeTileSource::createImage(const TileKey& key,
ProgressCallback* progress )
{
ImageMixVector images;
images.reserve(_imageLayers.size());
// Try to get an image from each of the layers for the given key.
for (ImageLayerVector::const_iterator itr = _imageLayers.begin(); itr != _imageLayers.end(); ++itr)
{
ImageLayer* layer = itr->get();
ImageInfo imageInfo;
imageInfo.dataInExtents = layer->getTileSource()->hasDataInExtent( key.getExtent() );
imageInfo.opacity = layer->getOpacity();
if (imageInfo.dataInExtents)
{
GeoImage image = layer->createImage(key, progress);
if (image.valid())
{
imageInfo.image = image.getImage();
}
}
images.push_back(imageInfo);
}
// Determine the output texture size to use based on the image that were creatd.
unsigned numValidImages = 0;
osg::Vec2s textureSize;
for (unsigned int i = 0; i < images.size(); i++)
{
ImageInfo& info = images[i];
if (info.image.valid())
{
if (numValidImages == 0)
{
textureSize.set( info.image->s(), info.image->t());
}
numValidImages++;
}
}
// Create fallback images if we have some valid data but not for all the layers
if (numValidImages > 0 && numValidImages < images.size())
{
for (unsigned int i = 0; i < images.size(); i++)
{
ImageInfo& info = images[i];
ImageLayer* layer = _imageLayers[i].get();
if (!info.image.valid() && info.dataInExtents)
{
TileKey parentKey = key.createParentKey();
GeoImage image;
while (!image.valid() && parentKey.valid())
{
image = layer->createImage(parentKey, progress);
if (image.valid())
{
break;
}
parentKey = parentKey.createParentKey();
}
if (image.valid())
{
// TODO: Bilinear options?
bool bilinear = layer->isCoverage() ? false : true;
GeoImage cropped = image.crop( key.getExtent(), true, textureSize.x(), textureSize.y(), bilinear);
info.image = cropped.getImage();
}
}
}
}
// Now finally create the output image.
//Recompute the number of valid images
numValidImages = 0;
for (unsigned int i = 0; i < images.size(); i++)
{
ImageInfo& info = images[i];
if (info.image.valid()) numValidImages++;
}
if ( progress && progress->isCanceled() )
{
return 0L;
}
else if ( numValidImages == 0 )
{
return 0L;
}
else if ( numValidImages == 1 )
{
//We only have one valid image, so just return it and don't bother with compositing
for (unsigned int i = 0; i < images.size(); i++)
{
ImageInfo& info = images[i];
if (info.image.valid())
//.........这里部分代码省略.........
示例11: setStatus
GeoImage
ImageLayer::assembleImage(const TileKey& key, ProgressCallback* progress)
{
// If we got here, asset that there's a non-null layer profile.
if (!getProfile())
{
setStatus(Status::Error(Status::AssertionFailure, "assembleImage with undefined profile"));
return GeoImage::INVALID;
}
GeoImage mosaicedImage, result;
// Scale the extent if necessary to apply an "edge buffer"
GeoExtent ext = key.getExtent();
if ( options().edgeBufferRatio().isSet() )
{
double ratio = options().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 = createImageImplementation( *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 = createImageImplementation( parentKey, progress );
if ( image.valid() )
//.........这里部分代码省略.........
示例12: GeoImage
//.........这里部分代码省略.........
// validate the existance of a valid layer profile (unless we're in cache-only mode, in which
// case there is no layer profile)
if ( !policy.isCacheOnly() && !getProfile() )
{
disable("Could not establish a valid profile");
return GeoImage::INVALID;
}
osg::ref_ptr< osg::Image > cachedImage;
// First, attempt to read from the cache. Since the cached data is stored in the
// map profile, we can try this first.
if ( cacheBin && policy.isCacheReadable() )
{
ReadResult r = cacheBin->readImage(cacheKey, 0L);
if ( r.succeeded() )
{
cachedImage = r.releaseImage();
ImageUtils::fixInternalFormat( cachedImage.get() );
bool expired = policy.isExpired(r.lastModifiedTime());
if (!expired)
{
OE_DEBUG << "Got cached image for " << key.str() << std::endl;
return GeoImage( cachedImage.get(), key.getExtent() );
}
else
{
OE_DEBUG << "Expired image for " << key.str() << std::endl;
}
}
}
// The data was not in the cache. If we are cache-only, fail sliently
if ( policy.isCacheOnly() )
{
// If it's cache only and we have an expired but cached image, just return it.
if (cachedImage.valid())
{
return GeoImage( cachedImage.get(), key.getExtent() );
}
else
{
return GeoImage::INVALID;
}
}
if (key.getProfile()->isHorizEquivalentTo(getProfile()))
{
result = createImageImplementation(key, progress);
}
else
{
// If the profiles are different, use a compositing method to assemble the tile.
result = assembleImage( key, progress );
}
// Normalize the image if necessary
if ( result.valid() )
{
ImageUtils::fixInternalFormat( result.getImage() );
}
// memory cache first:
if ( result.valid() && _memCache.valid() )
{
CacheBin* bin = _memCache->getOrCreateDefaultBin();
bin->write(cacheKey, result.getImage(), 0L);
}
// If we got a result, the cache is valid and we are caching in the map profile,
// write to the map cache.
if (result.valid() &&
cacheBin &&
policy.isCacheWriteable())
{
if ( key.getExtent() != result.getExtent() )
{
OE_INFO << LC << "WARNING! mismatched extents." << std::endl;
}
cacheBin->write(cacheKey, result.getImage(), 0L);
}
if ( result.valid() )
{
OE_DEBUG << LC << key.str() << " result OK" << std::endl;
}
else
{
OE_DEBUG << LC << key.str() << "result INVALID" << std::endl;
// We couldn't get an image from the source. So see if we have an expired cached image
if (cachedImage.valid())
{
OE_DEBUG << LC << "Using cached but expired image for " << key.str() << std::endl;
result = GeoImage( cachedImage.get(), key.getExtent());
}
}
return result;
}
示例13: getProfile
GeoImage
ImageLayer::createImageInNativeProfile(const TileKey& key,
ProgressCallback* progress)
{
if (getStatus().isError())
{
return GeoImage::INVALID;
}
const Profile* nativeProfile = getProfile();
if ( !nativeProfile )
{
OE_WARN << LC << "Could not establish the profile" << std::endl;
return GeoImage::INVALID;
}
GeoImage result;
if ( key.getProfile()->isHorizEquivalentTo(nativeProfile) )
{
// requested profile matches native profile, move along.
result = createImageInKeyProfile( key, progress );
}
else
{
// find the intersection of keys.
std::vector<TileKey> nativeKeys;
nativeProfile->getIntersectingTiles(key, nativeKeys);
// 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 )
{
GeoImage image = createImageInKeyProfile( *k, progress );
if ( image.valid() )
{
foundAtLeastOneRealTile = true;
mosaic.getImages().push_back( TileImage(image.getImage(), *k) );
}
else
{
// We didn't get an image so pad the mosaic with a transparent image.
mosaic.getImages().push_back( TileImage(ImageUtils::createEmptyImage(getTileSize(), getTileSize()), *k));
}
}
// bail out if we got nothing.
if ( foundAtLeastOneRealTile )
{
// assemble new GeoImage from the mosaic.
double rxmin, rymin, rxmax, rymax;
mosaic.getExtents( rxmin, rymin, rxmax, rymax );
result = GeoImage(
mosaic.createImage(),
GeoExtent( nativeProfile->getSRS(), rxmin, rymin, rxmax, rymax ) );
}
}
return result;
}