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 <osgDB/ReaderWriter> 00020 #include <osgDB/FileNameUtils> 00021 #include <osgDB/FileCache> 00022 #include <osgDB/Registry> 00023 #include <osgDB/FileUtils> 00024 #include <osgDB/Archive> 00025 #include <osgEarth/Registry> 00026 #include <osgEarth/ThreadingUtils> 00027 00028 #include "KMLOptions" 00029 #include "KMLReader" 00030 #include "KMZArchive" 00031 00032 #define LC "[ReaderWriterKML] " 00033 00034 using namespace osgEarth; 00035 using namespace osgEarth::Drivers; 00036 00037 //--------------------------------------------------------------------------- 00038 00039 struct ReaderWriterKML : public osgDB::ReaderWriter 00040 { 00041 ReaderWriterKML() 00042 { 00043 supportsExtension( "kml", "KML" ); 00044 00045 #ifdef SUPPORT_KMZ 00046 supportsExtension( "kmz", "KMZ" ); 00047 #endif // SUPPORT_KMZ 00048 } 00049 00050 ReadResult readObject(const std::string& url, const Options* options) const 00051 { 00052 return readNode( url, options ); 00053 } 00054 00055 ReadResult readObject(std::istream& in, const Options* options ) const 00056 { 00057 return readNode(in, options); 00058 } 00059 00060 ReadResult readNode(const std::string& url, const Options* options) const 00061 { 00062 std::string ext = osgDB::getLowerCaseFileExtension(url); 00063 if ( !acceptsExtension(ext) ) 00064 return ReadResult::FILE_NOT_HANDLED; 00065 00066 if ( ext == "kmz" ) 00067 { 00068 return URI(url + "/.kml").readNode( options ); 00069 } 00070 else 00071 { 00072 // propagate the source URI along to the stream reader 00073 osg::ref_ptr<osgDB::Options> myOptions = Registry::instance()->cloneOrCreateOptions(options); 00074 URIContext(url).store( myOptions.get() ); 00075 return readNode( URIStream(url), myOptions.get() ); 00076 } 00077 } 00078 00079 ReadResult readNode(std::istream& in, const Options* options ) const 00080 { 00081 if ( !options ) 00082 return ReadResult("Missing required MapNode option"); 00083 00084 // this plugin requires that you pass in a MapNode* in options. 00085 MapNode* mapNode = const_cast<MapNode*>( 00086 static_cast<const MapNode*>( options->getPluginData("osgEarth::MapNode")) ); 00087 if ( !mapNode ) 00088 return ReadResult("Missing required MapNode option"); 00089 00090 // grab the KMLOptions if present 00091 const KMLOptions* kmlOptions = 00092 static_cast<const KMLOptions*>(options->getPluginData("osgEarth::KMLOptions") ); 00093 00094 // Grab the URIContext from the options (since we're reading from a stream) 00095 URIContext uriContext( options ); 00096 00097 // fire up a KML reader and parse the data. 00098 KMLReader reader( mapNode, kmlOptions ); 00099 osg::Node* node = reader.read( in, uriContext ); 00100 return ReadResult(node); 00101 } 00102 00103 #ifdef SUPPORT_KMZ 00104 00105 ReadResult openArchive( const std::string& url, ArchiveStatus status, unsigned int dummy, const osgDB::Options* options =0L ) const 00106 { 00107 // Find the archive for this thread. We store one KMZ archive instance per thread 00108 // so that the minizip library can work in parallel 00109 osg::ref_ptr<KMZArchive>& kmz = const_cast<ReaderWriterKML*>(this)->_archive.get(); 00110 if ( !kmz.valid() ) 00111 kmz = new KMZArchive( URI(url) ); 00112 00113 return ReadResult( kmz.release() ); 00114 } 00115 00116 private: 00117 00118 Threading::PerThread< osg::ref_ptr<KMZArchive> > _archive; 00119 00120 #endif // SUPPORT_KMZ 00121 }; 00122 00123 REGISTER_OSGPLUGIN( kml, ReaderWriterKML )