void CompositeTileSource::initialize( const std::string& referenceURI, const Profile* overrideProfile ) { osg::ref_ptr<const Profile> profile = overrideProfile; for(CompositeTileSourceOptions::ComponentVector::iterator i = _options._components.begin(); i != _options._components.end(); ++i) { TileSource* source = i->_tileSourceInstance.get(); if ( source ) { osg::ref_ptr<const Profile> localOverrideProfile = overrideProfile; const TileSourceOptions& opt = source->getOptions(); if ( opt.profile().isSet() ) localOverrideProfile = Profile::create( opt.profile().value() ); source->initialize( referenceURI, localOverrideProfile.get() ); if ( !profile.valid() ) { // assume the profile of the first source to be the overall profile. profile = source->getProfile(); } else if ( !profile->isEquivalentTo( source->getProfile() ) ) { // if sub-sources have different profiles, print a warning because this is // not supported! OE_WARN << LC << "Components with differing profiles are not supported. " << "Visual anomalies may result." << std::endl; } _dynamic = _dynamic || source->isDynamic(); // gather extents const DataExtentList& extents = source->getDataExtents(); for( DataExtentList::const_iterator j = extents.begin(); j != extents.end(); ++j ) { getDataExtents().push_back( *j ); } } } setProfile( profile.get() ); _initialized = true; }
Status CompositeTileSource::initialize(const osgDB::Options* dbOptions) { _dbOptions = Registry::instance()->cloneOrCreateOptions(dbOptions); osg::ref_ptr<const Profile> profile = getProfile(); for(CompositeTileSourceOptions::ComponentVector::iterator i = _options._components.begin(); i != _options._components.end(); ) { if ( i->_imageLayerOptions.isSet() && !i->_layer.valid() ) { // Disable the l2 cache for composite layers so that we don't get run out of memory on very large datasets. i->_imageLayerOptions->driver()->L2CacheSize() = 0; osg::ref_ptr< ImageLayer > layer = new ImageLayer(*i->_imageLayerOptions); layer->setReadOptions(_dbOptions.get()); Status status = layer->open(); if (status.isOK()) { i->_layer = layer; _imageLayers.push_back( layer ); OE_INFO << LC << " .. added image layer " << layer->getName() << " (" << i->_imageLayerOptions->driver()->getDriver() << ")\n"; } else { OE_WARN << LC << "Could not open image layer (" << layer->getName() << ") ... " << status.message() << std::endl; } } else if (i->_elevationLayerOptions.isSet() && !i->_layer.valid()) { // Disable the l2 cache for composite layers so that we don't get run out of memory on very large datasets. i->_elevationLayerOptions->driver()->L2CacheSize() = 0; osg::ref_ptr< ElevationLayer > layer = new ElevationLayer(*i->_elevationLayerOptions); layer->setReadOptions(_dbOptions.get()); Status status = layer->open(); if (status.isOK()) { i->_layer = layer; _elevationLayers.push_back( layer.get() ); } else { OE_WARN << LC << "Could not open elevation layer (" << layer->getName() << ") ... " << status.message() << std::endl; } } if ( !i->_layer.valid() ) { OE_WARN << LC << "A component has no valid TerrainLayer ... removing." << std::endl; i = _options._components.erase( i ); } else { TileSource* source = i->_layer->getTileSource(); // If no profile is specified assume they want to use the profile of the first layer in the list. if (!profile.valid()) { profile = source->getProfile(); } _dynamic = _dynamic || source->isDynamic(); // gather extents const DataExtentList& extents = source->getDataExtents(); for( DataExtentList::const_iterator j = extents.begin(); j != extents.end(); ++j ) { // Convert the data extent to the profile that is actually used by this TileSource DataExtent dataExtent = *j; GeoExtent ext = dataExtent.transform(profile->getSRS()); unsigned int minLevel = 0; unsigned int maxLevel = profile->getEquivalentLOD( source->getProfile(), *dataExtent.maxLevel() ); dataExtent = DataExtent(ext, minLevel, maxLevel); getDataExtents().push_back( dataExtent ); } } ++i; } // set the new profile that was derived from the components setProfile( profile.get() ); _initialized = true; return STATUS_OK; }
void CacheSeed::seed( Map* map ) { if ( !map->getCache() ) { OE_WARN << LC << "Warning: No cache defined; aborting." << std::endl; return; } std::vector<TileKey> keys; map->getProfile()->getRootKeys(keys); //Add the map's entire extent if we don't have one specified. if (_extents.empty()) { addExtent( map->getProfile()->getExtent() ); } bool hasCaches = false; int src_min_level = INT_MAX; unsigned int src_max_level = 0; MapFrame mapf( map, Map::TERRAIN_LAYERS, "CacheSeed::seed" ); //Assumes the the TileSource will perform the caching for us when we call createImage for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); i++ ) { ImageLayer* layer = i->get(); TileSource* src = layer->getTileSource(); const ImageLayerOptions& opt = layer->getImageLayerOptions(); if ( layer->isCacheOnly() ) { OE_WARN << LC << "Warning: Layer \"" << layer->getName() << "\" is set to cache-only; skipping." << std::endl; } else if ( !src ) { OE_WARN << "Warning: Layer \"" << layer->getName() << "\" could not create TileSource; skipping." << std::endl; } else if ( src->getCachePolicyHint() == CachePolicy::NO_CACHE ) { OE_WARN << LC << "Warning: Layer \"" << layer->getName() << "\" does not support seeding; skipping." << std::endl; } else if ( !layer->getCache() ) { OE_WARN << LC << "Notice: Layer \"" << layer->getName() << "\" has no cache defined; skipping." << std::endl; } else { hasCaches = true; if (opt.minLevel().isSet() && (int)opt.minLevel().get() < src_min_level) src_min_level = opt.minLevel().get(); if (opt.maxLevel().isSet() && opt.maxLevel().get() > src_max_level) src_max_level = opt.maxLevel().get(); } } for( ElevationLayerVector::const_iterator i = mapf.elevationLayers().begin(); i != mapf.elevationLayers().end(); i++ ) { ElevationLayer* layer = i->get(); TileSource* src = layer->getTileSource(); const ElevationLayerOptions& opt = layer->getElevationLayerOptions(); if ( layer->isCacheOnly() ) { OE_WARN << LC << "Warning: Layer \"" << layer->getName() << "\" is set to cache-only; skipping." << std::endl; } else if (!src) { OE_WARN << "Warning: Layer \"" << layer->getName() << "\" could not create TileSource; skipping." << std::endl; } else if ( src->getCachePolicyHint() == CachePolicy::NO_CACHE ) { OE_WARN << LC << "Warning: Layer \"" << layer->getName() << "\" does not support seeding; skipping." << std::endl; } else if ( !layer->getCache() ) { OE_WARN << LC << "Notice: Layer \"" << layer->getName() << "\" has no cache defined; skipping." << std::endl; } else { hasCaches = true; if (opt.minLevel().isSet() && (int)opt.minLevel().get() < src_min_level) src_min_level = opt.minLevel().get(); if (opt.maxLevel().isSet() && opt.maxLevel().get() > src_max_level) src_max_level = opt.maxLevel().get(); } } if ( !hasCaches ) { OE_WARN << LC << "There are either no caches defined in the map, or no sources to cache; aborting." << std::endl; return; } if ( src_max_level > 0 && src_max_level < _maxLevel ) { _maxLevel = src_max_level; } OE_NOTICE << LC << "Maximum cache level will be " << _maxLevel << std::endl; osg::Timer_t startTime = osg::Timer::instance()->tick(); //Estimate the number of tiles _total = 0; for (unsigned int level = _minLevel; level <= _maxLevel; level++) { double coverageRatio = 0.0; if (_extents.empty()) { unsigned int wide, high; map->getProfile()->getNumTiles( level, wide, high ); _total += (wide * high); } else { for (std::vector< GeoExtent >::const_iterator itr = _extents.begin(); itr != _extents.end(); itr++) { const GeoExtent& extent = *itr; double boundsArea = extent.area(); TileKey ll = map->getProfile()->createTileKey(extent.xMin(), extent.yMin(), level); TileKey ur = map->getProfile()->createTileKey(extent.xMax(), extent.yMax(), level); int tilesWide = ur.getTileX() - ll.getTileX() + 1; int tilesHigh = ll.getTileY() - ur.getTileY() + 1; int tilesAtLevel = tilesWide * tilesHigh; //OE_NOTICE << "Tiles at level " << level << "=" << tilesAtLevel << std::endl; bool hasData = false; for (ImageLayerVector::const_iterator itr = mapf.imageLayers().begin(); itr != mapf.imageLayers().end(); itr++) { TileSource* src = itr->get()->getTileSource(); if (src) { if (src->hasDataAtLOD( level )) { //Compute the percent coverage of this dataset on the current extent if (src->getDataExtents().size() > 0) { double cov = 0.0; for (unsigned int j = 0; j < src->getDataExtents().size(); j++) { GeoExtent b = src->getDataExtents()[j].transform( extent.getSRS()); GeoExtent intersection = b.intersectionSameSRS( extent ); if (intersection.isValid()) { double coverage = intersection.area() / boundsArea; cov += coverage; //Assumes the extents aren't overlapping } } if (coverageRatio < cov) coverageRatio = cov; } else { //We have no way of knowing how much coverage we have coverageRatio = 1.0; } hasData = true; break; } } } for (ElevationLayerVector::const_iterator itr = mapf.elevationLayers().begin(); itr != mapf.elevationLayers().end(); itr++) { TileSource* src = itr->get()->getTileSource(); if (src) { if (src->hasDataAtLOD( level )) { //Compute the percent coverage of this dataset on the current extent if (src->getDataExtents().size() > 0) { double cov = 0.0; for (unsigned int j = 0; j < src->getDataExtents().size(); j++) { GeoExtent b = src->getDataExtents()[j].transform( extent.getSRS()); GeoExtent intersection = b.intersectionSameSRS( extent ); if (intersection.isValid()) { double coverage = intersection.area() / boundsArea; cov += coverage; //Assumes the extents aren't overlapping } } if (coverageRatio < cov) coverageRatio = cov; } else { //We have no way of knowing how much coverage we have coverageRatio = 1.0; } hasData = true; break; } } } //Adjust the coverage ratio by a fudge factor to try to keep it from being too small, //tiles are either processed or not and the ratio is exact so will cover tiles partially //and potentially be too small double adjust = 4.0; coverageRatio = osg::clampBetween(coverageRatio * adjust, 0.0, 1.0); //OE_NOTICE << level << " CoverageRatio = " << coverageRatio << std::endl; if (hasData) { _total += (int)ceil(coverageRatio * (double)tilesAtLevel ); } } } } //Adjust the # of tiles again to be bigger than computed to avoid giving false hope _total *= 2; osg::Timer_t endTime = osg::Timer::instance()->tick(); //OE_NOTICE << "Counted tiles in " << osg::Timer::instance()->delta_s(startTime, endTime) << " s" << std::endl; OE_INFO << "Processing ~" << _total << " tiles" << std::endl; for (unsigned int i = 0; i < keys.size(); ++i) { processKey( mapf, keys[i] ); } _total = _completed; if ( _progress.valid()) _progress->reportProgress(_completed, _total, 0, 1, "Finished"); }
TileSource::Status CompositeTileSource::initialize(const osgDB::Options* dbOptions) { _dbOptions = Registry::instance()->cloneOrCreateOptions(dbOptions); osg::ref_ptr<const Profile> profile = getProfile(); for(CompositeTileSourceOptions::ComponentVector::iterator i = _options._components.begin(); i != _options._components.end(); ) { if ( i->_imageLayerOptions.isSet() ) { if ( !i->_tileSourceInstance.valid() ) { i->_tileSourceInstance = TileSourceFactory::create( i->_imageLayerOptions->driver().value() ); if ( !i->_tileSourceInstance.valid() ) { OE_WARN << LC << "Could not find a TileSource for driver [" << i->_imageLayerOptions->driver()->getDriver() << "]" << std::endl; } } } if ( !i->_tileSourceInstance.valid() ) { OE_WARN << LC << "A component has no valid TileSource ... removing." << std::endl; i = _options._components.erase( i ); } else { TileSource* source = i->_tileSourceInstance.get(); if ( source ) { osg::ref_ptr<const Profile> localOverrideProfile = profile.get(); const TileSourceOptions& opt = source->getOptions(); if ( opt.profile().isSet() ) { localOverrideProfile = Profile::create( opt.profile().value() ); source->setProfile( localOverrideProfile.get() ); } // initialize the component tile source: TileSource::Status compStatus = source->startup( _dbOptions.get() ); if ( compStatus == TileSource::STATUS_OK ) { if ( !profile.valid() ) { // assume the profile of the first source to be the overall profile. profile = source->getProfile(); } else if ( !profile->isEquivalentTo( source->getProfile() ) ) { // if sub-sources have different profiles, print a warning because this is // not supported! OE_WARN << LC << "Components with differing profiles are not supported. " << "Visual anomalies may result." << std::endl; } _dynamic = _dynamic || source->isDynamic(); // gather extents const DataExtentList& extents = source->getDataExtents(); for( DataExtentList::const_iterator j = extents.begin(); j != extents.end(); ++j ) { getDataExtents().push_back( *j ); } } else { // if even one of the components fails to initialize, the entire // composite tile source is invalid. return Status::Error("At least one component is invalid"); } } } ++i; } // set the new profile that was derived from the components setProfile( profile.get() ); _initialized = true; return STATUS_OK; }
void CompositeTileSource::initialize(const osgDB::Options* dbOptions, const Profile* overrideProfile ) { _dbOptions = dbOptions; osg::ref_ptr<const Profile> profile = overrideProfile; for(CompositeTileSourceOptions::ComponentVector::iterator i = _options._components.begin(); i != _options._components.end(); ) { if ( i->_imageLayerOptions.isSet() ) { if ( !i->_tileSourceInstance.valid() ) { i->_tileSourceInstance = TileSourceFactory::create( i->_imageLayerOptions->driver().value() ); if ( !i->_tileSourceInstance.valid() ) { OE_WARN << LC << "Could not find a TileSource for driver [" << i->_imageLayerOptions->driver()->getDriver() << "]" << std::endl; } } } if ( !i->_tileSourceInstance.valid() ) { OE_WARN << LC << "A component has no valid TileSource ... removing." << std::endl; i = _options._components.erase( i ); } else { TileSource* source = i->_tileSourceInstance.get(); if ( source ) { osg::ref_ptr<const Profile> localOverrideProfile = overrideProfile; const TileSourceOptions& opt = source->getOptions(); if ( opt.profile().isSet() ) localOverrideProfile = Profile::create( opt.profile().value() ); source->initialize( dbOptions, localOverrideProfile.get() ); if ( !profile.valid() ) { // assume the profile of the first source to be the overall profile. profile = source->getProfile(); } else if ( !profile->isEquivalentTo( source->getProfile() ) ) { // if sub-sources have different profiles, print a warning because this is // not supported! OE_WARN << LC << "Components with differing profiles are not supported. " << "Visual anomalies may result." << std::endl; } _dynamic = _dynamic || source->isDynamic(); // gather extents const DataExtentList& extents = source->getDataExtents(); for( DataExtentList::const_iterator j = extents.begin(); j != extents.end(); ++j ) { getDataExtents().push_back( *j ); } } } ++i; } setProfile( profile.get() ); _initialized = true; }