前言
网上关于GDAL等高线生成的示例全是GDALContourGenerate
函数相关的,为加快等高线生成速度,某项目需要对内存数据进行等高线生成,恰好GDAL提供了相应的算法。
要想调用GDAL的算法进行等高线生成,需包含头文件:
#include <gdal_alg.h>
该头文件包含了GDAL的算法接口,等高线生成的函数接口也在其中。
1. 如何使用?
以下将从GDAL的函数原型、参数解释、示例代码等方面对GDAL等高线算法进行介绍。
注意:以下内容是对内存数据(数组)进行操作!!!
1.1 GDAL函数原型
从GDAL源码中(gdal_alg.h
)可以看到,创建等高线生成器的函数原型如下:
GDALContourGeneratorH CPL_DLL
GDAL_CG_Create( int nWidth, int nHeight,
int bNoDataSet, double dfNoDataValue,
double dfContourInterval, double dfContourBase,
GDALContourWriter pfnWriter, void *pCBData );
该函数返回一个等高线生成器—GDALContourGeneratorH
,其参数解释如下:
int nWidth
:数据块的宽度
int nHeight
:数据块的高度
int bNoDataSet
:数据块中是否存在无数据值
double dfNoDataValue
:如果数据块中存在无数据值,该无数据值是多少
double dfContourInterval
:等高线间隔
double dfContourBase
:等高线起始值
GDALContourWriter pfnWriter
:等高线写操作器
void *pCBData
:传给等高线写操作器的数据
上述等高线写操作器
是什么东西??
这是GDAL的gdal_alg.h
头文件中定义的一个回调函数,该函数原型如下:
typedef CPLErr (*GDALContourWriter)( double dfLevel, int nPoints,
double *padfX, double *padfY, void * );
该函数的参数解释如下:
double dfLevel
:等高线的层级
int nPoints
:当前行数据里等高线的点数
double *padfX
:当前行数据里等高线点的X坐标数组
double *padfY
:当前行数据里等高线点的Y坐标数组
void *
:传给等高线写操作器的数据
上述GDAL接口只是创建了等高线生成器,那么内存数据块是如何传给等高线生成器进行等高线的生成呢?
从GDAL的源码中,紧跟在GDAL_CG_Create
函数后的是GDAL_CG_FeedLine
函数,该函数就是将内存数据块传递给GDAL的等高线生成器的重要函数。
下面的代码是GDAL_CG_FeedLine
函数的一般用法:
for (int i = 0; i < m_pInput->height(); ++i)
{
GDAL_CG_FeedLine(cg, pScanLine);
pScanLine += m_pInput->width();
}
上述代码中,m_pInput
就是输入的内存数据块,是一个width * height
大小的数组,通过遍历数组的每一行,将行数据传递给等高线生成器,再在上文提到的等高线写操作器
里将等高线数据进行处理(导出或者绘制)。
1.2 等高线生成器的示例代码
- 创建等高线生成器
GDALContourGeneratorH cg = GDAL_CG_Create(m_pInput->width(), m_pInput->height(),
m_pInput->hasNoDataValue(), m_pInput->noDataValue(),
m_dContourInterval, m_dContourBase,
rasterContourWriter, static_cast<void*>(&cwd));
double *pScanLine = (double*)(m_pInput->data());
for (int i = 0; i < m_pInput->height(); ++i)
{
GDAL_CG_FeedLine(cg, pScanLine);
pScanLine += m_pInput->width();
}
- 自定义
等高线写操作器
及其需要的数据
CPLErr rasterContourWriter(double dfLevel, int nPoints, double *padfX, double *padfY, void *ptr)
{
ContourWriterData *data = static_cast<ContourWriterData *>(ptr);
QPolygonF polygon(nPoints);
QPointF *d = polygon.data();
for (int i = 0; i < nPoints; i++)
{
d[i] = QPointF(padfX[i], padfY[i]);
}
data->painter->drawPolyline(polygon);
return CE_None;
}
该函数即是GDAL的等等高线写操作器
。
- 等高线写操作器的数据
struct ContourWriterData
{
QPainter* painter;
};
上述示例代码中,等高线写操作器
仅仅只是将生成的等高线数据绘制到QImage
上,并未进行等高线数据导出。