今天开始仔细研究osgearth,osgearth是一个开源的地理信息库,里面有很方便的插件可以使用。但是osgearth的资料少之又少,所以我们从osgearth的例程开始研究。
我们从第一个osgearth_city开始。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace osgEarth;
using namespace osgEarth::Drivers;
using namespace osgEarth::Features;
using namespace osgEarth::Symbology;
using namespace osgEarth::Util;
int
main(int argc, char** argv)
{
osg::ArgumentParser arguments(&argc,argv);
// 创建一个新的地图
Map* map = new Map();
// 添加一个TMS高程的数据层
TMSOptions imagery;
imagery.url() = "http://readymap.org/readymap/tiles/1.0.0/22/"; //这个是TMS数据库网址
map->addImageLayer( new ImageLayer("ReadyMap imagery", imagery) );
// 创建一个osgearth里面提供的波士顿城市的建筑位置文件。
OGRFeatureOptions feature_opt;
feature_opt.name() = "buildings";
feature_opt.url() = "../data/boston_buildings_utm19.shp";//波士顿城市的位置文件
feature_opt.buildSpatialIndex() = true;
//创建一个建筑物风格
Style buildingStyle;
buildingStyle.setName( "default" );
//ExtrusionSymbol提供了一个将二维图形挤出为三维的一个类继承于osgEarth::Symbology::Symbol
ExtrusionSymbol* extrusion = buildingStyle.getOrCreate
extrusion->heightExpression() = NumericExpression( "3.5 * max( [story_ht_], 1 )" ); //挤出建筑物的高度
extrusion->flatten() = true;
extrusion->wallStyleName() = "building-wall";//设置挤出墙的名字
extrusion->roofStyleName() = "building-roof";
// 为墙的纹理创建风格
Style wallStyle;
wallStyle.setName( "building-wall" );
SkinSymbol* wallSkin = wallStyle.getOrCreate
wallSkin->libraryName() = "us_resources";
wallSkin->addTag( "building" );
wallSkin->randomSeed() = 1;
// 为挤出的屋顶设置纹理风格
Style roofStyle;
roofStyle.setName( "building-roof" );
SkinSymbol* roofSkin = roofStyle.getOrCreate
roofSkin->libraryName() = "us_resources";
roofSkin->addTag( "rooftop" );
roofSkin->randomSeed() = 1;
roofSkin->isTiled() = true;
//将所有的墙体风格集合到一个建筑物上面,形成虚构的建筑物
StyleSheet* styleSheet = new StyleSheet();
styleSheet->addStyle( buildingStyle );//建筑物风格
styleSheet->addStyle( wallStyle );//墙体纹理的风格
styleSheet->addStyle( roofStyle );//屋顶纹理的风格
// 获取纹理图片所在文件夹的索引文件
ResourceLibrary* reslib = new ResourceLibrary( "us_resources", "../data/resources/textures_us/catalog.xml" );
styleSheet->addResourceLibrary( reslib );
// 建立一个混合多层显示布局,这个较为重要,下面再细讲
FeatureDisplayLayout layout;
layout.tileSizeFactor() = 45.0;
layout.addLevel( FeatureLevel(0.0f, 20000.0f) );
// 根据我们前面设置的样式表建立一个建筑物
FeatureGeomModelOptions fgm_opt;
fgm_opt.featureOptions() = feature_opt;
fgm_opt.styles() = styleSheet;
fgm_opt.layout() = layout;
map->addModelLayer( new ModelLayer( "buildings", fgm_opt ) );//添加建筑物到地图中去
// 建立一个osg视景浏览器
osgViewer::Viewer viewer(arguments);
EarthManipulator* manip = new EarthManipulator();
viewer.setCameraManipulator( manip );
osg::Group* root = new osg::Group();
viewer.setSceneData( root );
MapNode* mapNode = new MapNode( map );
root->addChild( mapNode );
MapNodeHelper helper;
helper.configureView( &viewer );
helper.parse(mapNode, arguments, &viewer, root, new LabelControl("City Demo"));
// 设置照相机视角
manip->setViewpoint( Viewpoint(-71.0763, 42.34425, 0, 24.261, -21.6, 3450.0), 5.0 );
viewer.getCamera()->addCullCallback( new AutoClipPlaneCullCallback(mapNode) );
return viewer.run();
}
重点分析FeatureDisplayLayout 这个类,这个类设置了一个混合的LOD显示层,能够实现建筑物的分层显示。我们看一下这个类的主要成员:
optional< float > & | tileSizeFactor () |
const optional< float > & | tileSizeFactor () const |
optional< float > & | maxRange () |
const optional< float > & | maxRange () const |
optional< float > & | minRange () |
const optional< float > & | minRange () const |
optional< bool > & | cropFeatures () |
const optional< bool > & | cropFeatures () const |
optional< float > & | priorityOffset () |
const optional< float > & | priorityOffset () const |
optional< float > & | priorityScale () |
const optional< float > & | priorityScale () const |
void | addLevel (const FeatureLevel &level) |
unsigned | getNumLevels () const |
const FeatureLevel * | getLevel (unsigned i) const |
unsigned | chooseLOD (const FeatureLevel &level, double fullExtentRadius) const |
Config | getConfig () const |
maxRange ()成员函数则是设置最先看到的第一层纹理时候的距离。
minRange ()设置能够看到所有建筑的最小距离。
cropFeatures () 这个函数默认是false的,也就是说只是在纹理的中心在视野中的时候才开始显示纹理贴图,而当你设置为true时候则待显示的纹理只要一部分在视野中的时候就开始显示纹理贴图。
priorityOffset () 这个函数是设置读取下一页数据的偏移,通过设置便宜能够影响下一页数据的优先程度。
priorityScale () 设置显示分页数据的规模。
addLevel 添加分层数据到建筑中
chooseLOD () 获得最优的分层四叉树。
先分析到这里,如果有什么错误请给与指导,谢谢。