目标:(五十五)中的问题132
如果从dem/img等文件中提取出指定范围的高程网格,需要用到gdal库进行读取。遥感影像一般包含至少一个波段,波段对应波长,比如红、绿、蓝等,也包含透明度。
osgEarthDrivers/gdal/ReaderWriterGDAL.cpp
osg::HeightField* createHeightField( const TileKey& key,
ProgressCallback* progress)
{
if (key.getLevelOfDetail() > _maxDataLevel)
{
//OE_NOTICE << "Reached maximum data resolution key=" << key.getLevelOfDetail() << " max=" << _maxDataLevel << std::endl;
return NULL;
}
GDAL_SCOPED_LOCK;
int tileSize = getPixelsPerTile();
//Allocate the heightfield
osg::ref_ptr<osg::HeightField> hf = new osg::HeightField;
hf->allocate(tileSize, tileSize);
if (intersects(key))
{
//Get the meter extents of the tile
double xmin, ymin, xmax, ymax;
key.getExtent().getBounds(xmin, ymin, xmax, ymax);
// Try to find a FLOAT band
GDALRasterBand* band = findBandByDataType(_warpedDS, GDT_Float32);
if (band == NULL)
{
// Just get first band
band = _warpedDS->GetRasterBand(1);
}
if (_options.interpolation() == INTERP_NEAREST)
{
double colMin, colMax;
double rowMin, rowMax;
geoToPixel( xmin, ymin, colMin, rowMax );
geoToPixel( xmax, ymax, colMax, rowMin );
std::vector<float> buffer(tileSize * tileSize, NO_DATA_VALUE);
int iColMin = floor(colMin);
int iColMax = ceil(colMax);
int iRowMin = floor(rowMin);
int iRowMax = ceil(rowMax);
int iNumCols = iColMax - iColMin + 1;
int iNumRows = iRowMax - iRowMin + 1;
int iWinColMin = max(0, iColMin);
int iWinColMax = min(_warpedDS->GetRasterXSize()-1, iColMax);
int iWinRowMin = max(0, iRowMin);
int iWinRowMax = min(_warpedDS->GetRasterYSize()-1, iRowMax);
int iNumWinCols = iWinColMax - iWinColMin + 1;
int iNumWinRows = iWinRowMax - iWinRowMin + 1;
int iBufColMin = osg::round((iWinColMin - iColMin) / double(iNumCols - 1) * (tileSize - 1));
int iBufColMax = osg::round((iWinColMax - iColMin) / double(iNumCols - 1) * (tileSize - 1));
int iBufRowMin = osg::round((iWinRowMin - iRowMin) / double(iNumRows - 1) * (tileSize - 1));
int iBufRowMax = osg::round((iWinRowMax - iRowMin) / double(iNumRows - 1) * (tileSize - 1));
int iNumBufCols = iBufColMax - iBufColMin + 1;
int iNumBufRows = iBufRowMax - iBufRowMin + 1;
int startOffset = iBufRowMin * tileSize + iBufColMin;
int lineSpace = tileSize * sizeof(float);
band->RasterIO(GF_Read, iWinColMin, iWinRowMin, iNumWinCols, iNumWinRows, &buffer[startOffset], iNumBufCols, iNumBufRows, GDT_Float32, 0, lineSpace);
for (int r = 0, ir = tileSize - 1; r < tileSize; ++r, --ir)
{
for (int c = 0; c < tileSize; ++c)
{
hf->setHeight(c, ir, buffer[r * tileSize + c]);
}
}
}
else
{
double dx = (xmax