osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarth/Registry.cpp

Go to the documentation of this file.
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;
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines