void TextureCompositorMultiTexture::applyLayerUpdate(osg::StateSet* stateSet, UID layerUID, const GeoImage& preparedImage, const TileKey& tileKey, const TextureLayout& layout, osg::StateSet* parentStateSet) const { osg::Texture2D* tex = s_getTexture( stateSet, layerUID, layout, parentStateSet, _minFilter, _magFilter); if ( tex ) { osg::Image* image = preparedImage.getImage(); image->dirty(); // required for ensure the texture recognizes the image as new data tex->setImage( image ); // set up proper mipmapping filters: if (_enableMipmapping && _enableMipmappingOnUpdatedTextures && ImageUtils::isPowerOfTwo( image ) && !(!image->isMipmap() && ImageUtils::isCompressed(image)) ) { if ( tex->getFilter(osg::Texture::MIN_FILTER) != _minFilter ) tex->setFilter( osg::Texture::MIN_FILTER, _minFilter ); } else if ( tex->getFilter(osg::Texture::MIN_FILTER) != osg::Texture::LINEAR ) { tex->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR ); } bool lodBlending = layout.getSlot(layerUID, 1) >= 0; if (_enableMipmapping && _enableMipmappingOnUpdatedTextures && lodBlending ) { int slot = layout.getSlot(layerUID, 0); // update the timestamp on the image layer to support 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 ); // set the texture matrix to properly position the blend (parent) texture osg::Matrix mat; if ( parentStateSet != 0L ) { unsigned tileX, tileY; tileKey.getTileXY(tileX, tileY); mat(0,0) = 0.5f; mat(1,1) = 0.5f; mat(3,0) = (float)(tileX % 2) * 0.5f; mat(3,1) = (float)(1 - tileY % 2) * 0.5f; } ArrayUniform texMatUniform( "osgearth_TexBlendMatrix", osg::Uniform::FLOAT_MAT4, stateSet, layout.getMaxUsedSlot() + 1 ); texMatUniform.setElement( slot, mat ); } } }
void CacheSeed::processKey(const MapFrame& mapf, const TileKey& key ) const { unsigned int x, y, lod; key.getTileXY(x, y); lod = key.getLevelOfDetail(); bool gotData = true; if ( _minLevel <= lod && _maxLevel >= lod ) { gotData = cacheTile( mapf, key ); if (gotData) { incrementCompleted( 1 ); } if ( _progress.valid() && _progress->isCanceled() ) return; // Task has been cancelled by user if ( _progress.valid() && gotData && _progress->reportProgress(_completed, _total, std::string("Cached tile: ") + key.str()) ) return; // Canceled } if ( gotData && lod <= _maxLevel ) { TileKey k0 = key.createChildKey(0); TileKey k1 = key.createChildKey(1); TileKey k2 = key.createChildKey(2); TileKey k3 = key.createChildKey(3); bool intersectsKey = false; if (_extents.empty()) intersectsKey = true; else { for (unsigned int i = 0; i < _extents.size(); ++i) { if (_extents[i].intersects( k0.getExtent() ) || _extents[i].intersects( k1.getExtent() ) || _extents[i].intersects( k2.getExtent() ) || _extents[i].intersects( k3.getExtent() )) { intersectsKey = true; } } } //Check to see if the bounds intersects ANY of the tile's children. If it does, then process all of the children //for this level if (intersectsKey) { processKey(mapf, k0); processKey(mapf, k1); processKey(mapf, k2); processKey(mapf, k3); } } }
std::string createURL( const TileKey& key ) const { unsigned int x, y; key.getTileXY(x, y); unsigned int lod = key.getLevelOfDetail()+1; //http://s0.tileservice.worldwindcentral.com/getTile?interface=map&version=1&dataset=bmng.topo.bathy.200401&level=0&x=0&y=0 return Stringify() << _options.url()->full() << "interface=map&version=1" << "&dataset=" << _options.dataset().value() << "&level=" << lod << "&x=" << x << "&y=" << y << "&." << _formatToUse; //Add this to trick osg into using the correct loader. }
void TileVisitor::processKey( const TileKey& key ) { // If we've been cancelled then just return. if (_progress && _progress->isCanceled()) { return; } unsigned int x, y, lod; key.getTileXY(x, y); lod = key.getLevelOfDetail(); // Only process this key if it has a chance of succeeding. if (_tileHandler && !_tileHandler->hasData(key)) { return; } bool traverseChildren = false; // If the key intersects the extent attempt to traverse if (intersects( key.getExtent() )) { // If the lod is less than the min level don't do anything but do traverse the children. if (lod < _minLevel) { traverseChildren = true; } else { // Process the key traverseChildren = handleTile( key ); } } // Traverse the children if (traverseChildren && lod < _maxLevel) { for (unsigned int i = 0; i < 4; i++) { TileKey k = key.createChildKey(i); processKey( k ); } } }
std::string TMSCache::getFilename( const TileKey& key,const CacheSpec& spec ) const { unsigned int x,y; key.getTileXY(x, y); unsigned int lod = key.getLevelOfDetail(); unsigned int numCols, numRows; key.getProfile()->getNumTiles(lod, numCols, numRows); if ( _options.invertY() == false ) { y = numRows - y - 1; } std::stringstream buf; buf << getPath() << "/" << spec.cacheId() << "/" << lod << "/" << x << "/" << y << "." << spec.format(); std::string bufStr; bufStr = buf.str(); return bufStr; }
std::string getQuadKey(const TileKey& key) { unsigned int tile_x, tile_y; key.getTileXY(tile_x, tile_y); unsigned int lod = key.getLevelOfDetail(); std::stringstream ss; for( unsigned i = (int)lod+1; i > 0; i-- ) { char digit = '0'; unsigned mask = 1 << (i-1); if ( (tile_x & mask) != 0 ) { digit++; } if ( (tile_y & mask) != 0 ) { digit += 2; } ss << digit; } return ss.str(); }
TileImage::TileImage(osg::Image* image, const TileKey& key) { _image = image; key.getExtent().getBounds(_minX, _minY, _maxX, _maxY); key.getTileXY(_tileX, _tileY); }