int seed( osg::ArgumentParser& args ) { osgDB::Registry::instance()->getReaderWriterForExtension("png"); osgDB::Registry::instance()->getReaderWriterForExtension("jpg"); osgDB::Registry::instance()->getReaderWriterForExtension("tiff"); //Read the min level int minLevel = -1; while (args.read("--min-level", minLevel)); //Read the max level int maxLevel = -1; while (args.read("--max-level", maxLevel)); bool estimate = args.read("--estimate"); std::vector< Bounds > bounds; // restrict packaging to user-specified bounds. double xmin=DBL_MAX, ymin=DBL_MAX, xmax=DBL_MIN, ymax=DBL_MIN; while (args.read("--bounds", xmin, ymin, xmax, ymax )) { Bounds b; b.xMin() = xmin, b.yMin() = ymin, b.xMax() = xmax, b.yMax() = ymax; bounds.push_back( b ); } std::string tileList; while (args.read( "--tiles", tileList ) ); bool verbose = args.read("--verbose"); unsigned int batchSize = 0; args.read("--batchsize", batchSize); // Read the concurrency level unsigned int concurrency = 0; args.read("-c", concurrency); args.read("--concurrency", concurrency); int imageLayerIndex = -1; args.read("--image", imageLayerIndex); int elevationLayerIndex = -1; args.read("--elevation", elevationLayerIndex); //Read in the earth file. osg::ref_ptr<osg::Node> node = osgDB::readNodeFiles( args ); if ( !node.valid() ) return usage( "Failed to read .earth file." ); MapNode* mapNode = MapNode::findMapNode( node.get() ); if ( !mapNode ) return usage( "Input file was not a .earth file" ); // Read in an index shapefile std::string index; while (args.read("--index", index)) { //Open the feature source OGRFeatureOptions featureOpt; featureOpt.url() = index; osg::ref_ptr< FeatureSource > features = FeatureSourceFactory::create( featureOpt ); features->initialize(); features->getFeatureProfile(); osg::ref_ptr< FeatureCursor > cursor = features->createFeatureCursor(); while (cursor.valid() && cursor->hasMore()) { osg::ref_ptr< Feature > feature = cursor->nextFeature(); osgEarth::Bounds featureBounds = feature->getGeometry()->getBounds(); GeoExtent ext( feature->getSRS(), featureBounds ); ext = ext.transform( mapNode->getMapSRS() ); bounds.push_back( ext.bounds() ); } } // If they requested to do an estimate then don't do the the seed, just print out the estimated values. if (estimate) { CacheEstimator est; if ( minLevel >= 0 ) est.setMinLevel( minLevel ); if ( maxLevel >= 0 ) est.setMaxLevel( maxLevel ); est.setProfile( mapNode->getMap()->getProfile() ); for (unsigned int i = 0; i < bounds.size(); i++) { GeoExtent extent(mapNode->getMapSRS(), bounds[i]); OE_DEBUG << "Adding extent " << extent.toString() << std::endl; est.addExtent( extent ); } unsigned int numTiles = est.getNumTiles(); double size = est.getSizeInMB(); double time = est.getTotalTimeInSeconds(); std::cout << "Cache Estimation " << std::endl << "---------------- " << std::endl << "Total number of tiles: " << numTiles << std::endl << "Size on disk: " << osgEarth::prettyPrintSize( size ) << std::endl << "Total time: " << osgEarth::prettyPrintTime( time ) << std::endl; return 0; } osg::ref_ptr< TileVisitor > visitor; // If we are given a task file, load it up and create a new TileKeyListVisitor if (!tileList.empty()) { TaskList tasks( mapNode->getMap()->getProfile() ); tasks.load( tileList ); TileKeyListVisitor* v = new TileKeyListVisitor(); v->setKeys( tasks.getKeys() ); visitor = v; OE_DEBUG << "Read task list with " << tasks.getKeys().size() << " tasks" << std::endl; } // If we dont' have a visitor create one. if (!visitor.valid()) { if (args.read("--mt")) { // Create a multithreaded visitor MultithreadedTileVisitor* v = new MultithreadedTileVisitor(); if (concurrency > 0) { v->setNumThreads(concurrency); } visitor = v; } else if (args.read("--mp")) { // Create a multiprocess visitor MultiprocessTileVisitor* v = new MultiprocessTileVisitor(); if (concurrency > 0) { v->setNumProcesses(concurrency); } if (batchSize > 0) { v->setBatchSize(batchSize); } // Try to find the earth file std::string earthFile; for(int pos=1;pos<args.argc();++pos) { if (!args.isOption(pos)) { earthFile = args[ pos ]; break; } } v->setEarthFile( earthFile ); visitor = v; } else { // Create a single thread visitor visitor = new TileVisitor(); } } osg::ref_ptr< ProgressCallback > progress = new ConsoleProgressCallback(); if (verbose) { visitor->setProgressCallback( progress ); } if ( minLevel >= 0 ) visitor->setMinLevel( minLevel ); if ( maxLevel >= 0 ) visitor->setMaxLevel( maxLevel ); for (unsigned int i = 0; i < bounds.size(); i++) { GeoExtent extent(mapNode->getMapSRS(), bounds[i]); OE_DEBUG << "Adding extent " << extent.toString() << std::endl; visitor->addExtent( extent ); } // Initialize the seeder CacheSeed seeder; seeder.setVisitor(visitor.get()); osgEarth::Map* map = mapNode->getMap(); // They want to seed an image layer if (imageLayerIndex >= 0) { osg::ref_ptr< ImageLayer > layer = map->getImageLayerAt( imageLayerIndex ); if (layer) { OE_NOTICE << "Seeding single layer " << layer->getName() << std::endl; osg::Timer_t start = osg::Timer::instance()->tick(); seeder.run(layer, map); osg::Timer_t end = osg::Timer::instance()->tick(); if (verbose) { OE_NOTICE << "Completed seeding layer " << layer->getName() << " in " << prettyPrintTime( osg::Timer::instance()->delta_s( start, end ) ) << std::endl; } } else { std::cout << "Failed to find an image layer at index " << imageLayerIndex << std::endl; return 1; } } // They want to seed an elevation layer else if (elevationLayerIndex >= 0) { osg::ref_ptr< ElevationLayer > layer = map->getElevationLayerAt( elevationLayerIndex ); if (layer) { OE_NOTICE << "Seeding single layer " << layer->getName() << std::endl; osg::Timer_t start = osg::Timer::instance()->tick(); seeder.run(layer, map); osg::Timer_t end = osg::Timer::instance()->tick(); if (verbose) { OE_NOTICE << "Completed seeding layer " << layer->getName() << " in " << prettyPrintTime( osg::Timer::instance()->delta_s( start, end ) ) << std::endl; } } else { std::cout << "Failed to find an elevation layer at index " << elevationLayerIndex << std::endl; return 1; } } // They want to seed the entire map else { // Seed all the map layers for (unsigned int i = 0; i < map->getNumImageLayers(); ++i) { osg::ref_ptr< ImageLayer > layer = map->getImageLayerAt(i); OE_NOTICE << "Seeding layer" << layer->getName() << std::endl; osg::Timer_t start = osg::Timer::instance()->tick(); seeder.run(layer.get(), map); osg::Timer_t end = osg::Timer::instance()->tick(); if (verbose) { OE_NOTICE << "Completed seeding layer " << layer->getName() << " in " << prettyPrintTime( osg::Timer::instance()->delta_s( start, end ) ) << std::endl; } } for (unsigned int i = 0; i < map->getNumElevationLayers(); ++i) { osg::ref_ptr< ElevationLayer > layer = map->getElevationLayerAt(i); OE_NOTICE << "Seeding layer" << layer->getName() << std::endl; osg::Timer_t start = osg::Timer::instance()->tick(); seeder.run(layer.get(), map); osg::Timer_t end = osg::Timer::instance()->tick(); if (verbose) { OE_NOTICE << "Completed seeding layer " << layer->getName() << " in " << prettyPrintTime( osg::Timer::instance()->delta_s( start, end ) ) << std::endl; } } } return 0; }
void ExportDialog::updateEstimate() { CacheEstimator est; est.setProfile(_mapNode->getMap()->getProfile()); if (useBounds() && _bounds.width() > 0 && _bounds.height() > 0) { est.addExtent(GeoExtent(_mapNode->getMapSRS(), _bounds)); } int maxLevel = 10; if (maxLevelEnabled()) { maxLevel = getMaxLevel(); } else { // Determine the max level from the layers maxLevel = 0; for (unsigned int i = 0; i < _mapNode->getMap()->getNumImageLayers(); i++) { osgEarth::ImageLayer* layer = _mapNode->getMap()->getImageLayerAt(i); if (layer) { osgEarth::TileSource* ts = layer->getTileSource(); if (ts) { for (DataExtentList::iterator itr = ts->getDataExtents().begin(); itr != ts->getDataExtents().end(); itr++) { if (itr->maxLevel().isSet() && itr->maxLevel().value() > maxLevel) { maxLevel = itr->maxLevel().value(); } } } } } for (unsigned int i = 0; i < _mapNode->getMap()->getNumElevationLayers(); i++) { osgEarth::ElevationLayer* layer = _mapNode->getMap()->getElevationLayerAt(i); if (layer) { osgEarth::TileSource* ts = layer->getTileSource(); if (ts) { for (DataExtentList::iterator itr = ts->getDataExtents().begin(); itr != ts->getDataExtents().end(); itr++) { if (itr->maxLevel().isSet() && itr->maxLevel().value() > maxLevel) { maxLevel = itr->maxLevel().value(); } } } } } } est.setMaxLevel(maxLevel); std::stringstream buf; double totalSeconds = est.getTotalTimeInSeconds(); TMSExporter::ProcessingMode mode = getProcessingMode(); // If we are using multiple threads or processes assume it will scale linearly. if (mode == TMSExporter::MODE_MULTIPROCESS || mode == TMSExporter::MODE_MULTITHREADED) { totalSeconds /= (double)getConcurrency(); } // Adjust everything by the # of layers unsigned int numLayers = _mapNode->getMap()->getNumImageLayers() + _mapNode->getMap()->getNumElevationLayers(); totalSeconds *= (double)numLayers; unsigned int numTiles = est.getNumTiles() * numLayers; double sizeMB = est.getSizeInMB() * (double)numLayers; std::string timeString = prettyPrintTime(totalSeconds); buf << "Estimate: Max level=" << maxLevel << " " << numTiles << " tiles. " << sizeMB << " MB. " << timeString; _ui.estimateLabel->setText(QString::fromStdString(buf.str())); }