GDAL中的进度条
目录
GDAL中调用进度条函数都是以回调函数指针形式调用的,这里先介绍下回调函数。
函数指针
函数指针指向的是函数而非对象。
声明一个指向函数的函数指针,只需要用指针替换函数名即可:
void (*pfn) (string s1);
注:pfn两边的括号不能去掉。
使用函数指针
当我们把函数名作为值使用时,会自动转换为指针。
现在有个函数声明为为:void strCompare(string s1);
pfn = strCompare;//函数名strCompare作为值使用,则自动转换为指针,赋值给pfn.
pfn = &strCompare;//也可以对函数取地址。
以下三个语句是等价调用:
1) pfn(“meng”);
2)(*pfn)(“meng”);
3) strCompare(“meng”);
回调函数
这里说明一下,当用数组或者函数作为形参时,实际上是当做指针使用,如果传递数组时,实际上传递的是指向数组首元素的指针,如果传递函数时,实际上是作为函数指针使用。
例如:
void caller(string s, void fn(string str));//第二个形参会自动的转换为指向函数的指针。
void caller(string s, void (*fn)(string str));//显示的定义函数指针,两句代码等价。
下面的pfn表明是函数指针:
typedef void(*pfn)(const char* str);
下面就用GDAL中的进度条来说明回调函数的使用方法。
GDAL中的进度条
gdal中的进度条函数声明原型:
int CPL_STDCALL GDALTermProgress( CPL_UNUSED double dfComplete,
CPL_UNUSED const char *pszMessage,
void * /* pProgressArg */ )
GDALTermProgress函数的源代码(在源代码的\gdal-2.1.2\port\cpl_progress.cpp):
int CPL_STDCALL GDALTermProgress( CPL_UNUSED double dfComplete,
CPL_UNUSED const char *pszMessage,
void * /* pProgressArg */ )
{
int nThisTick = std::min(40, std::max(0,
static_cast<int>(dfComplete * 40.0) ));
// Have we started a new progress run?
static int nLastTick = -1;
if( nThisTick < nLastTick && nLastTick >= 39 )
nLastTick = -1;
if( nThisTick <= nLastTick )
return TRUE;
while( nThisTick > nLastTick )
{
++nLastTick;
if( nLastTick % 4 == 0 )
fprintf( stdout, "%d", (nLastTick / 4) * 10 );
else
fprintf( stdout, "." );
}
if( nThisTick == 40 )
fprintf( stdout, " - done.\n" );
else
fflush( stdout );
return TRUE;
}
下面我就用一个简单的例子来使用该函数:
#include "stdafx.h"
#include <iostream>
#include <algorithm>
using namespace std;
typedef int(*MyProgress)(double dfComplete,const char *pszMessage, void * pProgressArg );//声明函数指针
int Progress(double dfComplete,const char *pszMessage,void * pProgressArg );//函数声明
void print(int Size, MyProgress callback, void * pProgressArg);//回调函数
MyProgress pfnProgress = Progress; //定义函数指针变量并初始化
int _tmain(int argc, _TCHAR* argv[])
{
void * pProgressArg = NULL;
int nYSize = 1000000;
print(nYSize, pfnProgress, pProgressArg);
getchar();
return 0;
}
/*
Size:一般表示实际的长度,大小,比如波段的高等。
callback:指向进度条函数
pProgressArg:要显示的信息。
*/
void print(int Size, MyProgress callback, void * pProgressArg)
{
for (int i = 0; i < Size; i++)
{
pfnProgress(0.10 + 0.9 * ((i + 1) / (double)Size),
"", pProgressArg);//
}
}
//该段代码就是上面GDALTermProgress函数的源代码。
int Progress(double dfComplete,
const char *pszMessage,
void * pProgressArg )
{
int nThisTick = std::min(40, std::max(0,
static_cast<int>(dfComplete * 40.0)));
// Have we started a new progress run?
static int nLastTick = -1;
if (nThisTick < nLastTick && nLastTick >= 39)
nLastTick = -1;
if (nThisTick <= nLastTick)
return true;
while (nThisTick > nLastTick)
{
++nLastTick;
if (nLastTick % 4 == 0)
fprintf(stdout, "%d", (nLastTick / 4) * 10);
else
fprintf(stdout, ".");
}
if (nThisTick == 40)
fprintf(stdout, " - done.\n");
else
fflush(stdout);
return true;
}
运行结果:
下面来看看GDAL中是怎么使用进度条的。
GDALPolygonizeT函数是栅格矢量化函数,可以在源代码的\gdal-2.1.2\alg\polygonize.cpp中查看源码,在437行左右。
template<class DataType, class EqualityTest>
static CPLErr
GDALPolygonizeT( GDALRasterBandH hSrcBand,
GDALRasterBandH hMaskBand,
OGRLayerH hOutLayer, int iPixValField,
char **papszOptions,
GDALProgressFunc pfnProgress,
void * pProgressArg,
GDALDataType eDT)
GDALProgressFunc就是一个指向进度条函数的函数指针。
下面是源码中的使用(在664行左右):
/* -------------------------------------------------------------------- */
/* Report progress, and support interrupts. */
/* -------------------------------------------------------------------- */
if( eErr == CE_None
&& !pfnProgress( 0.10 + 0.90 * ((iY+1) / (double) nYSize),
"", pProgressArg ) )
{
CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
eErr = CE_Failure;
}
转载自:https://blog.csdn.net/u010670734/article/details/53787446