使用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; }