osg渲染数据高程文件

 

使用gdal解析DEM文件,将高程数据转换为HeightField对象,然后在osg渲染。

1 源代码

#include <gdal_priv.h>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osg/Shape>
#include <osgTerrain/TerrainTile>
#include <osgTerrain/GeometryTechnique>
#include <osgTerrain/Layer>


int main(int argc, char* argv[])
{
        if(argc<1)
                return -1;
        GDALAllRegister();
        GDALDataset* poDataset=(GDALDataset*)GDALOpen(argv[1],GA_ReadOnly);
        if(poDataset){
                double gdalGeoTransform[6];
                poDataset->GetGeoTransform(gdalGeoTransform);
                osg::HeightField* hf=new osg::HeightField();
                hf->allocate(poDataset->GetRasterXSize(),poDataset->GetRasterYSize());
                hf->setOrigin(osg::Vec3(gdalGeoTransform[0],gdalGeoTransform[3],0));
                hf->setXInterval(gdalGeoTransform[2]);
                hf->setYInterval(gdalGeoTransform[5]);
                float * heightData=new float[poDataset->GetRasterXSize()*poDataset->GetRasterYSize()];
                poDataset->GetRasterBand(1)->RasterIO(GF_Read,0,0,poDataset->GetRasterXSize(),poDataset->GetRasterYSize(),heightData,poDataset->GetRasterXSize(),poDataset->GetRasterYSize(),GDT_Float32,0,0);
                float* heightPtr=heightData;
                float noDataValueFill=0.0f;
                float noDataValue=poDataset->GetRasterBand(1)->GetNoDataValue();
                for(int r=poDataset->GetRasterYSize()-1;r>=0;--r){
                        for(int c=0;c<poDataset->GetRasterXSize();++c){
                                float h=*heightPtr++;
                                if(h!=noDataValue)
                                        hf->setHeight(c,r,h);
                                else
                                        hf->setHeight(c,r,noDataValueFill);
                        }
                }

                osg::ref_ptr<osgTerrain::TerrainTile> terrainTile=new osgTerrain::TerrainTile;
                osg::ref_ptr<osgTerrain::Locator> locator=new osgTerrain::Locator;
                double minX,minY,maxX,maxY;
                minX=std::min(gdalGeoTransform[0],gdalGeoTransform[0]+poDataset->GetRasterXSize()*gdalGeoTransform[1]);
                minY=std::min(gdalGeoTransform[3],gdalGeoTransform[3]+poDataset->GetRasterYSize()*gdalGeoTransform[5]);
                maxX=std::max(gdalGeoTransform[0],gdalGeoTransform[0]+poDataset->GetRasterXSize()*gdalGeoTransform[1]);
                maxY=std::max(gdalGeoTransform[3],gdalGeoTransform[3]+poDataset->GetRasterYSize()*gdalGeoTransform[5]);
                locator->setTransformAsExtents( minX,minY,maxX,maxY);

                osg::ref_ptr<osgTerrain::HeightFieldLayer> hfl=new osgTerrain::HeightFieldLayer;
                hfl->setHeightField(hf);
                hfl->setLocator(locator.get());
                terrainTile->setElevationLayer(hfl);
                osg::Group* scene=new osg::Group;
                scene->addChild(terrainTile.get());
                osgViewer::Viewer viewer;
                viewer.setSceneData(scene);
                viewer.addEventHandler(new osgViewer::WindowSizeHandler());
                viewer.run();
        }
        return 0;
}
原文地址:https://www.cnblogs.com/tuncaysanli/p/3591704.html