OSG中讀取shp數據

OSG(OpenSceneGraph)主要被用來展示三維,但目前需要在Qt5.0中顯示二三維地圖並進行開發,所以就想到了OSG。上網查了一下OSG支持的數據格式:大量常用的2D 圖形文件格式,包括.bmp,.dds,.gif,.jpeg,.pic,.png,.rgb,.tga 和.tiff。OSG  支持的3D模型文件格式包括3D Studio Max(.3ds),AliasWavefront(.obj),Carbon Graphics’ Geo(.geo),Collada(.dae),ESRI Shapefile(.shp),OpenFlight(.flt),Quake(.md2)和Terrex TerraPage(.txp)等常見格式。編譯什麼的可以參考我之前的博客:https://blog.csdn.net/qq_38378235/article/details/80082141。今天主要來分享一下如何在OSG中加載shp數據,及一些簡單的操作。

1、gis常用shp數據的加載

其實這部分操作也不難,是之前自己想複雜了,話不多說,用代碼來說明:

//創建Viewer對象,場景瀏覽器
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
//創建場景組節點
osg::ref_ptr<osg::Group> root = new osg::Group();
//創建節點,讀取SHP文件
osg::ref_ptr<osg::Node> node1 = osgDB::readNodeFile("region.shp");
osg::ref_ptr<osg::Node> node2 = osgDB::readNodeFile("line.shp");
osg::ref_ptr<osg::Node> node3 = osgDB::readNodeFile("point.shp");
//添加到場景
root->addChild(node1.get());
root->addChild(node2.get());
root->addChild(node3.get());
//優化場景數據
osgUtil::Optimizer optimizer ;
optimizer.optimize(root.get()) ;
//設置場景數據
viewer->setSceneData(root.get());
//初始化並創建窗口
viewer->realize();
//開始渲染
viewer->run();

這樣gis中的點、線、面數據就能用OSG進行展示了,是不是覺得很簡單和加載其他模型沒有什麼區別,當然這只是目前嘗試的加載方法,能夠顯示並滿足展示要求。

2、因爲加載進去的點、線、面都是一樣的顏色,因此只能看到最大層次的面數據,線和點層數據被覆蓋了,因此通過修改不同node的顏色來區別以便顯示查看,修改模型顏色主要參考網上的博客:https://blog.csdn.net/woaicd/article/details/77163012,代碼如下:

#include <QCoreApplication>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Texture2D>
#include <osg/TexEnv>
#include <osg/TexGen>
osg::Image* createImage( int width, int height,osg::Vec3 color )
{
    osg::ref_ptr<osg::Image> image = new osg::Image;
    image->allocateImage( width, height, 1, GL_RGB, GL_UNSIGNED_BYTE );
    unsigned char* data = image->data();
    for ( int y=0; y<height; ++y )
    {
        for ( int x=0; x<width; ++x )
        {
            *(data++) = color.x();
            *(data++) = color.y();
            *(data++) = color.z();
        }
    }
    return image.release();
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    osgViewer::Viewer viewer;
    osg::ref_ptr<osg::Node> model = osgDB::readNodeFile("cow.osg");
    if(model.valid())
    {
        osg::ref_ptr<osg::Image> image= createImage(256,256,osg::Vec3(255.0,1.0,0.0));
        if (image.get())
        {
            osg::ref_ptr<osg::Texture2D> texture=new osg::Texture2D();
            texture->setImage(image.get());
            //設置自動生成紋理座標
            osg::ref_ptr<osg::TexGen> texgen=new osg::TexGen();
            texgen->setMode(osg::TexGen::NORMAL_MAP);
            //設置紋理環境,模式爲BLEND
            osg::ref_ptr<osg::TexEnv> texenv=new osg::TexEnv;
            texenv->setMode(osg::TexEnv::Mode::ADD);
            texenv->setColor(osg::Vec4(0.6,0.6,0.6,0.0));
            //啓動單元一自動生成紋理座標,並使用紋理
            osg::ref_ptr<osg::StateSet> state=new osg::StateSet;
            state->setTextureAttributeAndModes(1,texture.get(),osg::StateAttribute::ON);
            state->setTextureAttributeAndModes(1,texgen.get(),osg::StateAttribute::ON);
           // state->setTextureAttribute(1,texenv.get());
            model->setStateSet(state.get());
        }
        viewer.setSceneData(model.get());
    }
    viewer.run();
    return a.exec();
}

3、改變節點姿態

OSG中通過旋轉模型來改變節點的姿態,使用的類叫 MatrixTransform

//創建旋轉矩陣 
osg::MatrixTransform* rotateMT=new osg::MatrixTransform;
rotateMT->setMatrix(osg::Matrix::rotate(osg::inDegrees(-90.f),-1.0f,-1.0f,0.0f));
rotateMT->addChild(root);

osg::MatrixTransform* mt=new osg::MatrixTransform;
mt->addChild(node4);
root->addChild(mt);
//設置場景數據
viewer->setSceneData(rotateMT);

說明:(1)在setMatrix的時候,使用osg::Matrix::rotate(osg::inDegrees(-90.0f), 0.0f, 0.0f, 1.0f) 構造了一個變換矩陣。

osg::Matrix::rotate這是Matrix類的靜態函數,返回一個矩陣。一共有4個參數,第一個參數是角度,後面三個參數是旋轉的向量座標值。

(2)OSG中的旋轉,通常是指繞着某個軸旋轉一定角度。實參中的後三個參數(0.0f, 0.0f, 1.0f)實際指的是z軸的正半軸。

可以把座標原點(0, 0, 0)看成向量起點,向量指向點(0.0f, 0.0f, 1.0f),這個點位於z軸座標軸上,因爲這個點的x=0, y=0, z=1。

4、改變背景顏色

 

osg默認的背景是藍色的,畫線是黑色,直觀上有時候看着不好,想換成常用的白色,當然也可以換成其他圖片做背景。

這裏只說換顏色(以換成白色爲例),代碼就一句話:

//更變背景顏色
viewer->getCamera()->setClearColor(osg::Vec4f(1.0f,1.0f,1.0f,1.0f));  //white

參數RGB和透明度,可以隨意改,直到修改到自己滿意爲止,現在的這個設置是底面爲白色。

5、縮放改變節點大小

這個也是比較常用的功能,在視圖模式下,通過縮放鼠標來改變節點的大小,一句代碼就好,要提前#include <osgViewer/ViewerEventHandlers>

viewer->addEventHandler(new osgViewer::WindowSizeHandler);

好了,現在已經差不多了,源代碼見:https://pan.baidu.com/s/1yD7pxzLz9_J99OlGdfaFSw

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章