osgEarth 2.1.1
|
00001 /* -*-c++-*- */ 00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph 00003 * Copyright 2008-2010 Pelican Mapping 00004 * http://osgearth.org 00005 * 00006 * osgEarth is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU Lesser General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> 00018 */ 00019 00020 #include <osgEarth/CacheSeed> 00021 #include <osgEarth/Caching> 00022 #include <OpenThreads/ScopedLock> 00023 #include <limits.h> 00024 00025 using namespace osgEarth; 00026 using namespace OpenThreads; 00027 00028 void CacheSeed::seed( Map* map ) 00029 { 00030 //Threading::ScopedReadLock lock( map->getMapDataMutex() ); 00031 00032 if ( !map->getMapOptions().cache().isSet() ) 00033 //if (!map->getCache()) 00034 { 00035 OE_WARN << "Warning: Map does not have a cache defined, please define a cache." << std::endl; 00036 return; 00037 } 00038 00039 // osg::ref_ptr<MapEngine> engine = new MapEngine(); //map->createMapEngine(); 00040 00041 std::vector<TileKey> keys; 00042 map->getProfile()->getRootKeys(keys); 00043 00044 //Set the default bounds to the entire profile if the user didn't override the bounds 00045 if (_bounds.xMin() == 0 && _bounds.yMin() == 0 && 00046 _bounds.xMax() == 0 && _bounds.yMax() == 0) 00047 { 00048 const GeoExtent& mapEx = map->getProfile()->getExtent(); 00049 _bounds = Bounds( mapEx.xMin(), mapEx.yMin(), mapEx.xMax(), mapEx.yMax() ); 00050 } 00051 00052 00053 bool hasCaches = false; 00054 int src_min_level = INT_MAX; 00055 unsigned int src_max_level = 0; 00056 00057 MapFrame mapf( map, Map::TERRAIN_LAYERS, "CacheSeed::seed" ); 00058 00059 //Assumes the the TileSource will perform the caching for us when we call createImage 00060 for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); i++ ) 00061 { 00062 ImageLayer* layer = i->get(); 00063 TileSource* src = i->get()->getTileSource(); 00064 const ImageLayerOptions& opt = layer->getImageLayerOptions(); 00065 00066 if ( opt.cacheOnly() == true ) 00067 { 00068 OE_WARN << "Warning: Cannot seed b/c Layer \"" << layer->getName() << "\" is cache only." << std::endl; 00069 return; 00070 } 00071 else if (!src) 00072 { 00073 OE_WARN << "Warning: Layer \"" << layer->getName() << "\" could not create TileSource." << std::endl; 00074 } 00075 else if ( !src->supportsPersistentCaching() ) 00076 { 00077 OE_WARN << "Warning: Layer \"" << layer->getName() << "\" does not support seeding." << std::endl; 00078 } 00079 else if ( !layer->getCache() ) 00080 { 00081 OE_NOTICE << "Notice: Layer \"" << layer->getName() << "\" has no persistent cache defined; skipping." << std::endl; 00082 } 00083 else 00084 { 00085 hasCaches = true; 00086 00087 if (opt.minLevel().isSet() && opt.minLevel().get() < src_min_level) 00088 src_min_level = opt.minLevel().get(); 00089 if (opt.maxLevel().isSet() && opt.maxLevel().get() > src_max_level) 00090 src_max_level = opt.maxLevel().get(); 00091 } 00092 } 00093 00094 for( ElevationLayerVector::const_iterator i = mapf.elevationLayers().begin(); i != mapf.elevationLayers().end(); i++ ) 00095 { 00096 ElevationLayer* layer = i->get(); 00097 TileSource* src = i->get()->getTileSource(); 00098 const ElevationLayerOptions& opt = layer->getElevationLayerOptions(); 00099 00100 if ( opt.cacheOnly().get()) 00101 { 00102 OE_WARN << "Warning: Cannot seed b/c Layer \"" << layer->getName() << "\" is cache only." << std::endl; 00103 return; 00104 } 00105 else if (!src) 00106 { 00107 OE_WARN << "Warning: Layer \"" << layer->getName() << "\" could not create TileSource." << std::endl; 00108 } 00109 else if ( !src->supportsPersistentCaching() ) 00110 { 00111 OE_WARN << "Warning: Layer \"" << layer->getName() << "\" does not support seeding." << std::endl; 00112 } 00113 else if ( !layer->getCache() ) 00114 { 00115 OE_NOTICE << "Notice: Layer \"" << src->getName() << "\" has no persistent cache defined; skipping." << std::endl; 00116 } 00117 else 00118 { 00119 hasCaches = true; 00120 00121 if (opt.minLevel().isSet() && opt.minLevel().get() < src_min_level) 00122 src_min_level = opt.minLevel().get(); 00123 if (opt.maxLevel().isSet() && opt.maxLevel().get() > src_max_level) 00124 src_max_level = opt.maxLevel().get(); 00125 } 00126 } 00127 00128 if (!hasCaches) 00129 { 00130 OE_NOTICE << "There are either no caches defined in the map, or no sources to cache. Exiting." << std::endl; 00131 return; 00132 } 00133 00134 if ( src_max_level > 0 && src_max_level < _maxLevel ) 00135 { 00136 _maxLevel = src_max_level; 00137 } 00138 00139 OE_NOTICE << "Maximum cache level will be " << _maxLevel << std::endl; 00140 00141 for (unsigned int i = 0; i < keys.size(); ++i) 00142 { 00143 processKey( mapf, keys[i] ); 00144 } 00145 } 00146 00147 00148 void 00149 CacheSeed::processKey(const MapFrame& mapf, const TileKey& key ) const 00150 { 00151 unsigned int x, y, lod; 00152 key.getTileXY(x, y); 00153 lod = key.getLevelOfDetail(); 00154 00155 // osg::ref_ptr<osgEarth::VersionedTerrain> terrain = new osgEarth::VersionedTerrain( map, engine ); 00156 00157 if ( _minLevel <= lod && _maxLevel >= lod ) 00158 { 00159 // OE_NOTICE << "Caching tile = " << key.str() << std::endl; //<< lod << " (" << x << ", " << y << ") " << std::endl; 00160 if ( _progress.valid() && _progress->reportProgress(0, 0, "Caching tile: " + key.str()) ) 00161 return; // Task has been cancelled by user 00162 00163 cacheTile( mapf, key ); 00164 // bool validData; 00165 //osg::ref_ptr<osg::Node> node = engine->createTile( map, terrain.get(), key, true, false, false, validData ); 00166 } 00167 00168 if (lod <= _maxLevel) 00169 { 00170 TileKey k0 = key.createChildKey(0); 00171 TileKey k1 = key.createChildKey(1); 00172 TileKey k2 = key.createChildKey(2); 00173 TileKey k3 = key.createChildKey(3); 00174 00175 //Check to see if the bounds intersects ANY of the tile's children. If it does, then process all of the children 00176 //for this level 00177 if (_bounds.intersects( k0.getExtent().bounds() ) || _bounds.intersects(k1.getExtent().bounds()) || 00178 _bounds.intersects( k2.getExtent().bounds() ) || _bounds.intersects(k3.getExtent().bounds()) ) 00179 { 00180 processKey(mapf, k0); 00181 processKey(mapf, k1); 00182 processKey(mapf, k2); 00183 processKey(mapf, k3); 00184 } 00185 } 00186 } 00187 00188 void 00189 CacheSeed::cacheTile(const MapFrame& mapf, const TileKey& key ) const 00190 { 00191 for( ImageLayerVector::const_iterator i = mapf.imageLayers().begin(); i != mapf.imageLayers().end(); i++ ) 00192 { 00193 ImageLayer* layer = i->get(); 00194 if ( layer->isKeyValid( key ) ) 00195 { 00196 GeoImage image = layer->createImage( key ); 00197 } 00198 } 00199 00200 if ( mapf.elevationLayers().size() > 0 ) 00201 { 00202 osg::ref_ptr<osg::HeightField> hf; 00203 mapf.getHeightField( key, false, hf ); 00204 } 00205 }