參考:http://blog.csdn.net/cccstudyer/article/details/17691893
通過\src\osgEarthDrivers\earth\ReaderWriterOsgEarth.cpp文件
ReaderWriterEarth類,用來解析“earth”文件
在文件225行的readNode函數
1 virtual ReadResult readNode(std::istream& in, const osgDB::Options* readOptions) const 2 { 3 // pull the URI context from the options structure (since we're reading 4 // from an "anonymous" stream here) 5 URIContext uriContext( readOptions ); 6 7 osg::ref_ptr<XmlDocument> doc = XmlDocument::load( in, uriContext ); 8 if ( !doc.valid() ) 9 return ReadResult::ERROR_IN_READING_FILE; 10 11 Config docConf = doc->getConfig(); 12 13 // support both "map" and "earth" tag names at the top level 14 Config conf; 15 if ( docConf.hasChild( "map" ) ) 16 conf = docConf.child( "map" ); 17 else if ( docConf.hasChild( "earth" ) ) 18 conf = docConf.child( "earth" ); 19 20 osg::ref_ptr<osg::Node> node; 21 22 if ( !conf.empty() ) 23 { 24 // see if we were given a reference URI to use: 25 std::string refURI = uriContext.referrer(); 26 27 if ( conf.value("version") == "1" ) 28 { 29 OE_INFO << LC << "Detected a version 1.x earth file" << std::endl; 30 EarthFileSerializer1 ser; 31 node = ser.deserialize( conf, refURI ); 32 } 33 34 else 35 { 36 if ( conf.value("version") != "2" ) 37 OE_DEBUG << LC << "No valid earth file version; assuming version='2'" << std::endl; 38 39 // attempt to parse a "default options" JSON string: 40 std::string defaultConfStr; 41 if ( readOptions ) 42 { 43 defaultConfStr = readOptions->getPluginStringData("osgEarth.defaultOptions"); 44 if ( !defaultConfStr.empty() ) 45 { 46 Config optionsConf("options"); 47 if (optionsConf.fromJSON(defaultConfStr)) 48 { 49 //OE_NOTICE << "\n\nOriginal = \n" << conf.toJSON(true) << "\n"; 50 Config* original = conf.mutable_child("options"); 51 if ( original ) 52 { 53 recursiveUniqueKeyMerge(optionsConf, *original); 54 } 55 if ( !optionsConf.empty() ) 56 { 57 conf.set("options", optionsConf); 58 } 59 //OE_NOTICE << "\n\nMerged = \n" << conf.toJSON(true) << "\n"; 60 } 61 } 62 } 63 64 EarthFileSerializer2 ser; 65 node = ser.deserialize( conf, refURI ); 66 } 67 } 68 69 MapNode* mapNode = MapNode::get(node.get()); 70 if (mapNode) 71 { 72 // If the user passed in a cache object, apply it to the map now 73 CacheSettings* cacheSettings = CacheSettings::get(readOptions); 74 if (cacheSettings && cacheSettings->getCache()) 75 { 76 mapNode->getMap()->setCache( cacheSettings->getCache() ); 77 OE_INFO << LC << "Applied user-supplied cache to the Map\n"; 78 } 79 } 80 81 return ReadResult(node.get()); 82 } 83 };
看到65行的讀取調用
進入\src\osgEarthDrivers\earth\EarthFileSerializer2.cpp文件
EarthFileSerializer2類的deserialize函數
1 void addImageLayer(const Config& conf, Map* map) 2 { 3 ImageLayerOptions options( conf ); 4 options.name() = conf.value("name"); 5 ImageLayer* layer = new ImageLayer(options); 6 map->addLayer(layer); 7 if (layer->getStatus().isError()) 8 OE_WARN << LC << "Layer \"" << layer->getName() << "\" : " << layer->getStatus().toString() << std::endl; 9 } 10 11 void addElevationLayer(const Config& conf, Map* map) 12 { 13 ElevationLayerOptions options( conf ); 14 options.name() = conf.value( "name" ); 15 ElevationLayer* layer = new ElevationLayer(options); 16 map->addLayer(layer); 17 if (layer->getStatus().isError()) 18 OE_WARN << LC << "Layer \"" << layer->getName() << "\" : " << layer->getStatus().toString() << std::endl; 19 } 20 21 void addModelLayer(const Config& conf, Map* map) 22 { 23 ModelLayerOptions options( conf ); 24 options.name() = conf.value( "name" ); 25 options.driver() = ModelSourceOptions( conf ); 26 ModelLayer* layer = new ModelLayer(options); 27 map->addLayer(layer); 28 if (layer->getStatus().isError()) 29 OE_WARN << LC << "Layer \"" << layer->getName() << "\" : " << layer->getStatus().toString() << std::endl; 30 } 31 32 void addMaskLayer(const Config& conf, Map* map) 33 { 34 MaskLayerOptions options(conf); 35 options.name() = conf.value( "name" ); 36 options.driver() = MaskSourceOptions(options); 37 MaskLayer* layer = new MaskLayer(options); 38 map->addLayer(layer); 39 if (layer->getStatus().isError()) 40 OE_WARN << LC << "Layer \"" << layer->getName() << "\" : " << layer->getStatus().toString() << std::endl; 41 } 42 43 // support for "special" extension names (convenience and backwards compat) 44 Extension* createSpecialExtension(const Config& conf) 45 { 46 // special support for the default sky extension: 47 if (conf.key() == "sky" && !conf.hasValue("driver")) 48 return Extension::create("sky_simple", conf); 49 50 if (conf.key() == "ocean" && !conf.hasValue("driver")) 51 return Extension::create("ocean_simple", conf); 52 53 return 0L; 54 } 55 56 bool addLayer(const Config& conf, Map* map) 57 { 58 std::string name = conf.key(); 59 Layer* layer = Layer::create(name, conf); 60 if (layer) 61 { 62 map->addLayer(layer); 63 if (layer->getStatus().isError()) 64 OE_WARN << LC << "Layer \"" << layer->getName() << "\" : " << layer->getStatus().toString() << std::endl; 65 } 66 return layer != 0L; 67 } 68 69 osg::Node* 70 EarthFileSerializer2::deserialize( const Config& conf, const std::string& referrer ) const 71 { 72 // First, pre-load any extension DLLs. 73 preloadExtensionLibs(conf); 74 preloadExtensionLibs(conf.child("extensions")); 75 preloadExtensionLibs(conf.child("external")); 76 77 MapOptions mapOptions( conf.child( "options" ) ); 78 79 // legacy: check for name/type in top-level attrs: 80 if ( conf.hasValue( "name" ) || conf.hasValue( "type" ) ) 81 { 82 Config legacy; 83 if ( conf.hasValue("name") ) legacy.add( "name", conf.value("name") ); 84 if ( conf.hasValue("type") ) legacy.add( "type", conf.value("type") ); 85 mapOptions.mergeConfig( legacy ); 86 } 87 88 Map* map = new Map( mapOptions ); 89 90 // Start a batch update of the map: 91 map->beginUpdate(); 92 93 // Read all the elevation layers in FIRST so other layers can access them for things like clamping. 94 for(ConfigSet::const_iterator i = conf.children().begin(); i != conf.children().end(); ++i) 95 { 96 if ( i->key() == "elevation" || i->key() == "heightfield" ) 97 { 98 addElevationLayer( *i, map ); 99 } 100 } 101 102 Config externalConfig; 103 std::vector<osg::ref_ptr<Extension> > extensions; 104 105 // Read the layers in LAST (otherwise they will not benefit from the cache/profile configuration) 106 for(ConfigSet::const_iterator i = conf.children().begin(); i != conf.children().end(); ++i) 107 { 108 if (i->key() == "options" || i->key() == "name" || i->key() == "type" || i->key() == "version") 109 { 110 // nop - handled earlier 111 } 112 113 else if ( i->key() == "image" ) 114 { 115 addImageLayer( *i, map ); 116 } 117 118 else if ( i->key() == "model" ) 119 { 120 addModelLayer( *i, map ); 121 } 122 123 else if ( i->key() == "mask" ) 124 { 125 addMaskLayer( *i, map ); 126 } 127 128 else if ( i->key() == "external" || i->key() == "extensions" ) 129 { 130 externalConfig = *i; 131 132 for(ConfigSet::const_iterator e = i->children().begin(); e != i->children().end(); ++e) 133 { 134 Extension* extension = loadExtension(*e); 135 if (extension) 136 extensions.push_back(extension); 137 //addExtension( *e, mapNode.get() ); 138 } 139 } 140 141 else if ( !isReservedWord(i->key()) ) // plugins/extensions. 142 { 143 bool addedLayer = addLayer(*i, map); //mapNode.get()); 144 145 if ( !addedLayer ) 146 { 147 Extension* extension = loadExtension(*i); 148 if (extension) 149 extensions.push_back(extension); 150 //OE_INFO << LC << "Tried to load \"" << i->key() << "\" as a layer; now trying extension\n"; 151 //addExtension( *i, mapNode.get() ); 152 } 153 } 154 } 155 156 // Complete the batch update of the map 157 map->endUpdate(); 158 159 // Yes, MapOptions and MapNodeOptions share the same Config node. Weird but true. 160 MapNodeOptions mapNodeOptions( conf.child("options") ); 161 162 // Create a map node. 163 osg::ref_ptr<MapNode> mapNode = new MapNode( map, mapNodeOptions ); 164 165 // Apply the external conf if there is one. 166 if (!externalConfig.empty()) 167 { 168 mapNode->externalConfig() = externalConfig; 169 } 170 171 // Install the extensions 172 for (unsigned i = 0; i < extensions.size(); ++i) 173 { 174 mapNode->addExtension(extensions.at(i).get()); 175 } 176 177 // return the topmost parent of the mapnode. It's possible that 178 // an extension added parents! 179 osg::Node* top = mapNode.release(); 180 181 while( top->getNumParents() > 0 ) 182 top = top->getParent(0); 183 184 return top; 185 }
從上面可以看到
1 earth插件 map 統籌OE中所有"層"的概念,支持多層影像,高程,模型,鏤空層(mask)等
2各個層相應配置的屬性由指定的Option類從Config中獲取,如果對應Config中有Option類指定元素相應值的配置Option將其寫入
為了統籌OE各個層的屬性配置,OE提供了ConfigOptions類,ConfigOptions類就是對某個Config類的封裝,提供了到Config層次上的調用,例如Config賦值,拼接等
為不同層的屬性配置提供了存儲載體,結合上文map包含的圖層有以下關系
通過這些類,可以很方便的將特定的XML節點下屬性配置生成Config歸類到某一個圖層中,以下列出部分圖層的屬性(僅供參考)
MapOptions:XML<<options>>節點下配置的信息,主要是配置地形渲染時的屬性;包括如下
- <elevation_interploation> 插值,nearset 最近點插值 average 最近點平均值 bilinear 線性插值, triangulate 三角面片插值
- <elevation_tile_size> 瓦片大小
- <elevation_texture_size> 紋理大小
- <overlay_wapring> 紋理裝載
- <overlay_blending>混合
- <overlay_minmapping> 紋理映射
- <overlay_texture_size>
- <overlay_attach_stencil>模板
ImageLayerOptions: XML<<image>>節點下配置的信息,很明顯,影像屬性配置,部分屬性值
- <nodata_image> 無數據顯示的url
- <opacity> 透明度
- <min_range> 最小可視范圍
- <max_range> 最大可視范圍
- <min_level> 最小顯示細節層級
- <max_level> 最大顯示細節層級
- <min_resolution> 數據的最小分辨率,單位的像素
- <max_resolution>數據的最大分辨率,單位的像素
- <enable> 是否包含進map層
- <visible> 可視
ElevationLayerOptions: XML<<elevation>>or<<heightfield>>節點下配置的信息,高程層
- <min_level> 最小顯示細節層級
- <max_level> 最大顯示細節層級
- <min_resolution> 數據的最小分辨率,單位的像素
- <max_resolution>數據的最大分辨率,單位的像素
- <enable> 是否包含進map層
ModelLayerOptions: XML<<Model>>節點下配置的信息 模型層裝載 矢量數據,模型,幾何體等
- <name>
- <driver>
- <enable><span style="font-family:Arial, Helvetica, sans-serif;">是否包含進map層</span>
- <visible>是否可見
- <overLay>
MaskLayerOptions: XML<<mask>>節點配置下的信息,鏤空層
一個比較特殊的節點 ext(Config); 暫且叫他功能層,XML <<external>>,它由mapNode直接讀取配置信息,實現一些經常用到的功能點,例如 視點定位 <<<viewpoint>> 星空時刻設置<<sky>>等