Skip to content

Commit

Permalink
Fix: assembleTiles could leave gaps of unitializited imagery in a mos…
Browse files Browse the repository at this point in the history
…aic.
  • Loading branch information
gwaldron committed Feb 13, 2015
1 parent 3300e40 commit 450a575
Showing 1 changed file with 48 additions and 3 deletions.
51 changes: 48 additions & 3 deletions src/osgEarth/ImageLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -723,11 +723,11 @@ ImageLayer::assembleImageFromTileSource(const TileKey& key,
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 )
{
double minX, minY, maxX, maxY;
k->getExtent().getBounds(minX, minY, maxX, maxY);

GeoImage image = createImageFromTileSource( *k, progress );
if ( image.valid() )
{
Expand Down Expand Up @@ -755,6 +755,8 @@ ImageLayer::assembleImageFromTileSource(const TileKey& key,
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;
Expand All @@ -770,6 +772,49 @@ ImageLayer::assembleImageFromTileSource(const TileKey& key,
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() )
{
ImageUtils::normalizeImage(image.getImage());
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());
}
}

OE_DEBUG << LC << "Tile " << k->str() << " fell back on " << parentKey.str() << "\n";

// cut out the piece we need:
GeoImage croppedImage = image.crop( k->getExtent(), true, image.getImage()->s(), image.getImage()->t() );

// and queue it.
mosaic.getImages().push_back( TileImage(croppedImage.getImage(), *k) );
}
}

if ( !image.valid() )
{
// a tile completely failed, even with fallback. Eject.
OE_DEBUG << LC << "Couldn't fallback on tiles 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 );
Expand Down

0 comments on commit 450a575

Please sign in to comment.