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 #include <osgEarth/Registry> 00020 #include <osgEarth/Cube> 00021 #include <osgEarth/ShaderComposition> 00022 #include <osgEarth/Caching> 00023 #include <osg/Notify> 00024 #include <osg/Version> 00025 #include <gdal_priv.h> 00026 #include <ogr_api.h> 00027 #include <stdlib.h> 00028 00029 using namespace osgEarth; 00030 using namespace OpenThreads; 00031 00032 #define STR_GLOBAL_GEODETIC "global-geodetic" 00033 #define STR_GLOBAL_MERCATOR "global-mercator" 00034 #define STR_CUBE "cube" 00035 #define STR_LOCAL "local" 00036 00037 #define LC "[Registry] " 00038 00039 // from MimeTypes.cpp 00040 extern const char* builtinMimeTypeExtMappings[]; 00041 00042 Registry::Registry() : 00043 osg::Referenced(true), 00044 _gdal_registered( false ), 00045 _numGdalMutexGets( 0 ), 00046 _uidGen( 0 ), 00047 _caps( 0L ) 00048 { 00049 OGRRegisterAll(); 00050 GDALAllRegister(); 00051 00052 // add built-in mime-type extension mappings 00053 for( int i=0; ; i+=2 ) 00054 { 00055 std::string mimeType = builtinMimeTypeExtMappings[i]; 00056 if ( mimeType.length() == 0 ) 00057 break; 00058 addMimeTypeExtensionMapping( mimeType, builtinMimeTypeExtMappings[i+1] ); 00059 } 00060 00061 _shaderLib = new ShaderFactory(); 00062 _taskServiceManager = new TaskServiceManager(); 00063 00064 // activate KMZ support 00065 osgDB::Registry::instance()->addFileExtensionAlias( "kmz", "kml" ); 00066 osgDB::Registry::instance()->addArchiveExtension( "kmz" ); 00067 #if OSG_MIN_VERSION_REQUIRED(3,0,0) 00068 osgDB::Registry::instance()->addMimeTypeExtensionMapping( "application/vnd.google-earth.kml+xml", "kml" ); 00069 osgDB::Registry::instance()->addMimeTypeExtensionMapping( "application/vnd.google-earth.kmz", "kmz" ); 00070 #endif 00071 00072 // set up our default r/w options to NOT cache archives! 00073 _defaultOptions = new osgDB::Options(); 00074 _defaultOptions->setObjectCacheHint( (osgDB::Options::CacheHintOptions) 00075 ((int)_defaultOptions->getObjectCacheHint() & ~osgDB::Options::CACHE_ARCHIVES) ); 00076 00077 // see if there's a cache in the envvar 00078 const char* cachePath = ::getenv("OSGEARTH_CACHE_PATH"); 00079 if ( cachePath ) 00080 { 00081 TMSCacheOptions tmso; 00082 tmso.setPath( std::string(cachePath) ); 00083 setCacheOverride( new TMSCache(tmso) ); 00084 OE_INFO << LC << "Setting cache (from env.var.) to " << tmso.path() << std::endl; 00085 } 00086 } 00087 00088 Registry::~Registry() 00089 { 00090 } 00091 00092 Registry* Registry::instance(bool erase) 00093 { 00094 static osg::ref_ptr<Registry> s_registry = new Registry; 00095 00096 if (erase) 00097 { 00098 s_registry->destruct(); 00099 s_registry = 0; 00100 } 00101 00102 return s_registry.get(); // will return NULL on erase 00103 } 00104 00105 void Registry::destruct() 00106 { 00107 _cacheOverride = 0; 00108 } 00109 00110 00111 OpenThreads::ReentrantMutex& 00112 Registry::getGDALMutex() 00113 { 00114 //_numGdalMutexGets++; 00115 //OE_NOTICE << "GDAL = " << _numGdalMutexGets << std::endl; 00116 return _gdal_mutex; 00117 } 00118 00119 00120 const Profile* 00121 Registry::getGlobalGeodeticProfile() const 00122 { 00123 if ( !_global_geodetic_profile.valid() ) 00124 { 00125 GDAL_SCOPED_LOCK; 00126 00127 if ( !_global_geodetic_profile.valid() ) // double-check pattern 00128 { 00129 const_cast<Registry*>(this)->_global_geodetic_profile = Profile::create( 00130 "epsg:4326", 00131 -180.0, -90.0, 180.0, 90.0, 00132 "", 00133 2, 1 ); 00134 } 00135 } 00136 return _global_geodetic_profile.get(); 00137 } 00138 00139 00140 const Profile* 00141 Registry::getGlobalMercatorProfile() const 00142 { 00143 if ( !_global_mercator_profile.valid() ) 00144 { 00145 GDAL_SCOPED_LOCK; 00146 00147 if ( !_global_mercator_profile.valid() ) // double-check pattern 00148 { 00149 // automatically figure out proper mercator extents: 00150 const SpatialReference* srs = SpatialReference::create( "spherical-mercator" ); 00151 //double e, dummy; 00152 //srs->getGeographicSRS()->transform( 180.0, 0.0, srs, e, dummy ); 00153 /*const_cast<Registry*>(this)->_global_mercator_profile = Profile::create( 00154 srs, -e, -e, e, e, 0L, 1, 1 );*/ 00155 const_cast<Registry*>(this)->_global_mercator_profile = Profile::create( 00156 srs, MERC_MINX, MERC_MINY, MERC_MAXX, MERC_MAXY, 0L, 1, 1 ); 00157 } 00158 } 00159 return _global_mercator_profile.get(); 00160 } 00161 00162 const Profile* 00163 Registry::getCubeProfile() const 00164 { 00165 if ( !_cube_profile.valid() ) 00166 { 00167 GDAL_SCOPED_LOCK; 00168 00169 if ( !_cube_profile.valid() ) // double-check pattern 00170 { 00171 const_cast<Registry*>(this)->_cube_profile = new UnifiedCubeProfile(); 00172 } 00173 } 00174 return _cube_profile.get(); 00175 } 00176 00177 const Profile* 00178 Registry::getNamedProfile( const std::string& name ) const 00179 { 00180 if ( name == STR_GLOBAL_GEODETIC ) 00181 return getGlobalGeodeticProfile(); 00182 else if ( name == STR_GLOBAL_MERCATOR ) 00183 return getGlobalMercatorProfile(); 00184 else if ( name == STR_CUBE ) 00185 return getCubeProfile(); 00186 else 00187 return NULL; 00188 } 00189 00190 const VerticalSpatialReference* 00191 Registry::getDefaultVSRS() const 00192 { 00193 if ( !_defaultVSRS.valid() ) 00194 const_cast<Registry*>(this)->_defaultVSRS = new VerticalSpatialReference( Units::METERS ); 00195 return _defaultVSRS.get(); 00196 } 00197 00198 osgEarth::Cache* 00199 Registry::getCacheOverride() const 00200 { 00201 return _cacheOverride.get(); 00202 } 00203 00204 void 00205 Registry::setCacheOverride( osgEarth::Cache* cacheOverride ) 00206 { 00207 _cacheOverride = cacheOverride; 00208 } 00209 00210 void Registry::addMimeTypeExtensionMapping(const std::string fromMimeType, const std::string toExt) 00211 { 00212 _mimeTypeExtMap[fromMimeType] = toExt; 00213 } 00214 00215 osgDB::ReaderWriter* 00216 Registry::getReaderWriterForMimeType(const std::string& mimeType) 00217 { 00218 MimeTypeExtensionMap::const_iterator i = _mimeTypeExtMap.find( mimeType ); 00219 return i != _mimeTypeExtMap.end()? 00220 osgDB::Registry::instance()->getReaderWriterForExtension( i->second ) : 00221 NULL; 00222 } 00223 00224 bool 00225 Registry::isBlacklisted(const std::string &filename) 00226 { 00227 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_blacklistMutex); 00228 return (_blacklistedFilenames.count(filename)==1); 00229 } 00230 00231 void 00232 Registry::blacklist(const std::string& filename) 00233 { 00234 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_blacklistMutex); 00235 _blacklistedFilenames.insert( filename ); 00236 OE_DEBUG << "Blacklist size = " << _blacklistedFilenames.size() << std::endl; 00237 } 00238 00239 void 00240 Registry::clearBlacklist() 00241 { 00242 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_blacklistMutex); 00243 _blacklistedFilenames.clear(); 00244 OE_DEBUG << "Blacklist size = " << _blacklistedFilenames.size() << std::endl; 00245 } 00246 00247 unsigned int 00248 Registry::getNumBlacklistedFilenames() 00249 { 00250 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_blacklistMutex); 00251 return _blacklistedFilenames.size(); 00252 } 00253 00254 const Capabilities& 00255 Registry::getCapabilities() const 00256 { 00257 if ( !_caps.valid() ) 00258 const_cast<Registry*>(this)->initCapabilities(); 00259 00260 return *_caps; 00261 } 00262 00263 static OpenThreads::Mutex s_initCapsMutex; 00264 void 00265 Registry::initCapabilities() 00266 { 00267 ScopedLock<Mutex> lock( s_initCapsMutex ); // double-check pattern (see getCapabilities) 00268 if ( !_caps.valid() ) 00269 _caps = new Capabilities(); 00270 } 00271 00272 ShaderFactory* 00273 Registry::getShaderFactory() const 00274 { 00275 return _shaderLib.get(); 00276 } 00277 00278 void 00279 Registry::setShaderFactory( ShaderFactory* lib ) 00280 { 00281 if ( lib != 0L && lib != _shaderLib.get() ) 00282 _shaderLib = lib; 00283 } 00284 00285 UID 00286 Registry::createUID() 00287 { 00288 static Mutex s_uidGenMutex; 00289 ScopedLock<Mutex> lock( s_uidGenMutex ); 00290 return (UID)( _uidGen++ ); 00291 } 00292 00293 osgDB::Options* 00294 Registry::cloneOrCreateOptions( const osgDB::Options* input ) const 00295 { 00296 osgDB::Options* newOptions = input ? static_cast<osgDB::Options*>(input->clone(osg::CopyOp::SHALLOW_COPY)) : new osgDB::Options(); 00297 00298 // clear the CACHE_ARCHIVES flag because it is evil 00299 if ( ((int)newOptions->getObjectCacheHint() & osgDB::Options::CACHE_ARCHIVES) != 0 ) 00300 { 00301 newOptions->setObjectCacheHint( (osgDB::Options::CacheHintOptions) 00302 ((int)newOptions->getObjectCacheHint() & ~osgDB::Options::CACHE_ARCHIVES) ); 00303 } 00304 00305 return newOptions; 00306 } 00307 00308 //Simple class used to add a file extension alias for the earth_tile to the earth plugin 00309 class RegisterEarthTileExtension 00310 { 00311 public: 00312 RegisterEarthTileExtension() 00313 { 00314 osg::Referenced::setThreadSafeReferenceCounting( true ); 00315 osgDB::Registry::instance()->addFileExtensionAlias("earth_tile", "earth"); 00316 } 00317 }; 00318 static RegisterEarthTileExtension s_registerEarthTileExtension;