参考:http://blog.csdn.net/cccstudyer/article/details/17691893

通过\src\osgEarthDrivers\earth\ReaderWriterOsgEarth.cpp文件

ReaderWriterEarth类,用来解析“earth”文件

在文件225行的readNode函数

   virtual ReadResult readNode(std::istream& in, const osgDB::Options* readOptions) const
{
// pull the URI context from the options structure (since we're reading
// from an "anonymous" stream here)
URIContext uriContext( readOptions ); osg::ref_ptr<XmlDocument> doc = XmlDocument::load( in, uriContext );
if ( !doc.valid() )
return ReadResult::ERROR_IN_READING_FILE; Config docConf = doc->getConfig(); // support both "map" and "earth" tag names at the top level
Config conf;
if ( docConf.hasChild( "map" ) )
conf = docConf.child( "map" );
else if ( docConf.hasChild( "earth" ) )
conf = docConf.child( "earth" ); osg::ref_ptr<osg::Node> node; if ( !conf.empty() )
{
// see if we were given a reference URI to use:
std::string refURI = uriContext.referrer(); if ( conf.value("version") == "" )
{
OE_INFO << LC << "Detected a version 1.x earth file" << std::endl;
EarthFileSerializer1 ser;
node = ser.deserialize( conf, refURI );
} else
{
if ( conf.value("version") != "" )
OE_DEBUG << LC << "No valid earth file version; assuming version='2'" << std::endl; // attempt to parse a "default options" JSON string:
std::string defaultConfStr;
if ( readOptions )
{
defaultConfStr = readOptions->getPluginStringData("osgEarth.defaultOptions");
if ( !defaultConfStr.empty() )
{
Config optionsConf("options");
if (optionsConf.fromJSON(defaultConfStr))
{
//OE_NOTICE << "\n\nOriginal = \n" << conf.toJSON(true) << "\n";
Config* original = conf.mutable_child("options");
if ( original )
{
recursiveUniqueKeyMerge(optionsConf, *original);
}
if ( !optionsConf.empty() )
{
conf.set("options", optionsConf);
}
//OE_NOTICE << "\n\nMerged = \n" << conf.toJSON(true) << "\n";
}
}
} EarthFileSerializer2 ser;
node = ser.deserialize( conf, refURI );
}
} MapNode* mapNode = MapNode::get(node.get());
if (mapNode)
{
// If the user passed in a cache object, apply it to the map now
CacheSettings* cacheSettings = CacheSettings::get(readOptions);
if (cacheSettings && cacheSettings->getCache())
{
mapNode->getMap()->setCache( cacheSettings->getCache() );
OE_INFO << LC << "Applied user-supplied cache to the Map\n";
}
} return ReadResult(node.get());
}
};

看到65行的读取调用

进入\src\osgEarthDrivers\earth\EarthFileSerializer2.cpp文件

EarthFileSerializer2类的deserialize函数

  void addImageLayer(const Config& conf, Map* map)
{
ImageLayerOptions options( conf );
options.name() = conf.value("name");
ImageLayer* layer = new ImageLayer(options);
map->addLayer(layer);
if (layer->getStatus().isError())
OE_WARN << LC << "Layer \"" << layer->getName() << "\" : " << layer->getStatus().toString() << std::endl;
} void addElevationLayer(const Config& conf, Map* map)
{
ElevationLayerOptions options( conf );
options.name() = conf.value( "name" );
ElevationLayer* layer = new ElevationLayer(options);
map->addLayer(layer);
if (layer->getStatus().isError())
OE_WARN << LC << "Layer \"" << layer->getName() << "\" : " << layer->getStatus().toString() << std::endl;
} void addModelLayer(const Config& conf, Map* map)
{
ModelLayerOptions options( conf );
options.name() = conf.value( "name" );
options.driver() = ModelSourceOptions( conf );
ModelLayer* layer = new ModelLayer(options);
map->addLayer(layer);
if (layer->getStatus().isError())
OE_WARN << LC << "Layer \"" << layer->getName() << "\" : " << layer->getStatus().toString() << std::endl;
} void addMaskLayer(const Config& conf, Map* map)
{
MaskLayerOptions options(conf);
options.name() = conf.value( "name" );
options.driver() = MaskSourceOptions(options);
MaskLayer* layer = new MaskLayer(options);
map->addLayer(layer);
if (layer->getStatus().isError())
OE_WARN << LC << "Layer \"" << layer->getName() << "\" : " << layer->getStatus().toString() << std::endl;
} // support for "special" extension names (convenience and backwards compat)
Extension* createSpecialExtension(const Config& conf)
{
// special support for the default sky extension:
if (conf.key() == "sky" && !conf.hasValue("driver"))
return Extension::create("sky_simple", conf); if (conf.key() == "ocean" && !conf.hasValue("driver"))
return Extension::create("ocean_simple", conf); return 0L;
} bool addLayer(const Config& conf, Map* map)
{
std::string name = conf.key();
Layer* layer = Layer::create(name, conf);
if (layer)
{
map->addLayer(layer);
if (layer->getStatus().isError())
OE_WARN << LC << "Layer \"" << layer->getName() << "\" : " << layer->getStatus().toString() << std::endl;
}
return layer != 0L;
} osg::Node*
EarthFileSerializer2::deserialize( const Config& conf, const std::string& referrer ) const
{
// First, pre-load any extension DLLs.
preloadExtensionLibs(conf);
preloadExtensionLibs(conf.child("extensions"));
preloadExtensionLibs(conf.child("external")); MapOptions mapOptions( conf.child( "options" ) ); // legacy: check for name/type in top-level attrs:
if ( conf.hasValue( "name" ) || conf.hasValue( "type" ) )
{
Config legacy;
if ( conf.hasValue("name") ) legacy.add( "name", conf.value("name") );
if ( conf.hasValue("type") ) legacy.add( "type", conf.value("type") );
mapOptions.mergeConfig( legacy );
} Map* map = new Map( mapOptions ); // Start a batch update of the map:
map->beginUpdate(); // Read all the elevation layers in FIRST so other layers can access them for things like clamping.
for(ConfigSet::const_iterator i = conf.children().begin(); i != conf.children().end(); ++i)
{
if ( i->key() == "elevation" || i->key() == "heightfield" )
{
addElevationLayer( *i, map );
}
} Config externalConfig;
std::vector<osg::ref_ptr<Extension> > extensions; // Read the layers in LAST (otherwise they will not benefit from the cache/profile configuration)
for(ConfigSet::const_iterator i = conf.children().begin(); i != conf.children().end(); ++i)
{
if (i->key() == "options" || i->key() == "name" || i->key() == "type" || i->key() == "version")
{
// nop - handled earlier
} else if ( i->key() == "image" )
{
addImageLayer( *i, map );
} else if ( i->key() == "model" )
{
addModelLayer( *i, map );
} else if ( i->key() == "mask" )
{
addMaskLayer( *i, map );
} else if ( i->key() == "external" || i->key() == "extensions" )
{
externalConfig = *i; for(ConfigSet::const_iterator e = i->children().begin(); e != i->children().end(); ++e)
{
Extension* extension = loadExtension(*e);
if (extension)
extensions.push_back(extension);
//addExtension( *e, mapNode.get() );
}
} else if ( !isReservedWord(i->key()) ) // plugins/extensions.
{
bool addedLayer = addLayer(*i, map); //mapNode.get()); if ( !addedLayer )
{
Extension* extension = loadExtension(*i);
if (extension)
extensions.push_back(extension);
//OE_INFO << LC << "Tried to load \"" << i->key() << "\" as a layer; now trying extension\n";
//addExtension( *i, mapNode.get() );
}
}
} // Complete the batch update of the map
map->endUpdate(); // Yes, MapOptions and MapNodeOptions share the same Config node. Weird but true.
MapNodeOptions mapNodeOptions( conf.child("options") ); // Create a map node.
osg::ref_ptr<MapNode> mapNode = new MapNode( map, mapNodeOptions ); // Apply the external conf if there is one.
if (!externalConfig.empty())
{
mapNode->externalConfig() = externalConfig;
} // Install the extensions
for (unsigned i = ; i < extensions.size(); ++i)
{
mapNode->addExtension(extensions.at(i).get());
} // return the topmost parent of the mapnode. It's possible that
// an extension added parents!
osg::Node* top = mapNode.release(); while( top->getNumParents() > )
top = top->getParent(); return top;
}

从上面可以看到

1 earth插件 map 统筹OE中所有"层"的概念,支持多层影像,高程,模型,镂空层(mask)等

2各个层相应配置的属性由指定的Option类从Config中获取,如果对应Config中有Option类指定元素相应值的配置Option将其写入

为了统筹OE各个层的属性配置,OE提供了ConfigOptions类,ConfigOptions类就是对某个Config类的封装,提供了到Config层次上的调用,例如Config赋值,拼接等

为不同层的属性配置提供了存储载体,结合上文map包含的图层有以下关系

通过这些类,可以很方便的将特定的XML节点下属性配置生成Config归类到某一个图层中,以下列出部分图层的属性(仅供参考)

MapOptions:XML<<options>>节点下配置的信息,主要是配置地形渲染时的属性;包括如下

  1. <elevation_interploation> 插值,nearset 最近点插值  average 最近点平均值 bilinear 线性插值,  triangulate 三角面片插值
  2. <elevation_tile_size> 瓦片大小
  3. <elevation_texture_size> 纹理大小
  4. <overlay_wapring> 纹理装载
  5. <overlay_blending>混合
  6. <overlay_minmapping>  纹理映射
  7. <overlay_texture_size>
  8. <overlay_attach_stencil>模板

ImageLayerOptions: XML<<image>>节点下配置的信息,很明显,影像属性配置,部分属性值

  1. <nodata_image> 无数据显示的url
  2. <opacity>    透明度
  3. <min_range> 最小可视范围
  4. <max_range> 最大可视范围
  5. <min_level>  最小显示细节层级
  6. <max_level>  最大显示细节层级
  7. <min_resolution> 数据的最小分辨率,单位的像素
  8. <max_resolution>数据的最大分辨率,单位的像素
  9. <enable> 是否包含进map层
  10. <visible> 可视

ElevationLayerOptions: XML<<elevation>>or<<heightfield>>节点下配置的信息,高程层

  1. <min_level>  最小显示细节层级
  2. <max_level>  最大显示细节层级
  3. <min_resolution> 数据的最小分辨率,单位的像素
  4. <max_resolution>数据的最大分辨率,单位的像素
  5. <enable> 是否包含进map层

ModelLayerOptions: XML<<Model>>节点下配置的信息 模型层装载 矢量数据,模型,几何体等

  1. <name>
  2. <driver>
  3. <enable><span style="font-family:Arial, Helvetica, sans-serif;">是否包含进map层</span>
  4. <visible>是否可见
  5. <overLay>

MaskLayerOptions: XML<<mask>>节点配置下的信息,镂空层

一个比较特殊的节点 ext(Config); 暂且叫他功能层,XML <<external>>,它由mapNode直接读取配置信息,实现一些经常用到的功能点,例如 视点定位 <<<viewpoint>> 星空时刻设置<<sky>>等

[原][osgearth]API加载earth文件的解析的更多相关文章

  1. [原][译][osgearth]API加载地球(OE官方文档翻译)

    原文参考:http://docs.osgearth.org/en/latest/developer/maps.html#programmatic-map-creation 本人翻译水平有限... 加载 ...

  2. 代码收藏系列--php--加载sql文件并解析成数组

    php加载sql文件,解析成以分号分割的数组.(支持存储过程和函数提取,自动过滤注释) /** * 加载sql文件为分号分割的数组 * <br />支持存储过程和函数提取,自动过滤注释 * ...

  3. c#两种方式调用google地球,调用COM API以及调用GEPLUGIN 与js交互,加载kml文件,dae文件。将二维高德地图覆盖到到三维谷歌地球表面。

    网络上资源很多不全面,自己在开发的时候走了不少弯路,在这里整理了最全面的google全套开发,COM交互,web端交互.封装好了各种模块功能. 直接就可以调用. 第一种方式:调用COMAPI实现调用g ...

  4. SharpDX之Direct2D教程II——加载位图文件和保存位图文件

    本系列文章目录: SharpDX之Direct2D教程I——简单示例和Color(颜色) 绘制位图是绘制操作的不可缺少的一部分.在Direct2D中绘制位图,必须先利用WIC组件将位图加载到内存中,再 ...

  5. 如何在SCENEKIT使用SWIFT RUNTIME动态加载COLLADA文件

    问题:今天接到一个项目,负责弄需求的美眉跟我讲能不能做一个原型能够加载Collada文件,流程如下: 用户用app下载Collada 压缩包(如内购项目) 压缩包解压 展示Collada文件里的内容 ...

  6. 两种动态加载JavaScript文件的方法

    两种动态加载JavaScript文件的方法 第一种便是利用ajax方式,第二种是,动静创建一个script标签,配置其src属性,经过把script标签拔出到页面head来加载js,感乐趣的网友可以看 ...

  7. JVM加载class文件的原理

    当Java编译器编译好.class文件之后,我们需要使用JVM来运行这个class文件.那么最开始的工作就是要把字节码从磁盘输入到内存中,这个过程我们叫做[加载 ].加载完成之后,我们就可以进行一系列 ...

  8. Android动态加载so文件

    在Android中调用动态库文件(*.so)都是通过jni的方式,而且往往在apk或jar包中调用so文件时,都要将对应so文件打包进apk或jar包,工程目录下图: 以上方式的存在的问题: 1.缺少 ...

  9. Spire.XLS,生成Excel文件、加载Excel文件

    一.组件介绍 Spire.XLS是E-iceblue开发的一套基于企业级的专业Office文档处理的组件之一,全称Spire.Office for .NET.旗下有Spire.Doc,Spire XL ...

随机推荐

  1. windows MySQL5.7.9免安装版配置方法

    1. 解压MySQL压缩包    将下载的MySQL压缩包解压到自定义目录下,我的解压目录是:    "D:\Program Files\mysql-5.7.9-win32"    ...

  2. jquery点击事件失效原因和解决办法

    在使用jQuery绑定点击事件的时候,有时候会遇到点击无效,这种情况大多出现在动态添加元素的时候 例如:给demo里添加li元素给li绑定点击事件 $("#demo").appen ...

  3. Groovy中的面向对象

    Groovy中的面向对象 前面说到groovy支持脚本和类,前面一节已将简单说了脚本和类之间的关系,这一节主要介绍一下groovy中类的相关知识,即面向对象相关知识. 1.类型 1.1 原始类型 gr ...

  4. spring的AOP个人理解和使用

    1什么是AOP:AOP是面向切面编程,也就是说面向某个功能模块编程,典型的应用就是Spring的声明式事务, Spring的AOP事务解析: 在以前的事务管理是要融合在逻辑代码中的,在逻辑代码中决定事 ...

  5. python threading.thread

    Thread 是threading模块中最重要的类之一,可以使用它来创建线程.有两种方式来创建线程:一种是通过继承Thread类,重写它的run方法:另一种是创建一个threading.Thread对 ...

  6. apidemos编译出错

    编译api 19的(4.4.2)apidemos一直报xml相关资源出错. 把build-toos 22删除,替换成19版本的,就ok了. 真是坑啊. 学习新东西难免遇到坑.

  7. XPipe 解决什么问题

    x-pipe/README.md at master · ctripcorp/x-pipe https://github.com/ctripcorp/x-pipe/blob/master/README ...

  8. 《玩转Spring》第二章 BeanPostProcessor扩展

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/shan9liang/article/details/34421141 上一章.介绍了怎样扩展spri ...

  9. 9.python的列表

    list2 = [1, 2, 3, 4, 5, 6, 7 ]; print ("list2[1:5]: ", list2[1:5]) 得到 list2[1:5]:  [2, 3, ...

  10. Spark调优秘诀

    1.诊断内存的消耗 在Spark应用程序中,内存都消耗在哪了? 1.每个Java对象都有一个包含该对象元数据的对象头,其大小是16个Byte.由于在写代码时候,可能会出现这种情况:对象头比对象本身占有 ...