RFC 24:GDAL渐进式数据支持
作者:诺曼·巴克,弗兰克·温特丹
联系方式:nbarker@ittvis.com,wartemdam@pobox.com
状态:通过
总结
在GDAL中提供异步/流数据访问接口。最初的实现是针对JPIP的,但是应该是通用的,足以应用于其他流/渐进式方法。JPIP(Kakadu)实现的背景可以在 [wiki:rfc24_jpipkak] .
界面
GDALAsyncReader
这个新类旨在表示一个活动的异步栅格图像请求。请求包括数据集上源窗口的信息、目标缓冲区大小(表示抽取或复制级别)、缓冲区类型、缓冲区交错、数据缓冲区和所请求的频带。基本上与GDALDataset中传递的信息相同::!RasterIO()请求。
GetNextUpdatedRegion()方法可用于等待图像缓冲区的更新,并找出更新的区域。LockBuffer()和UnlockBuffer()方法可用于在应用程序代码访问缓冲区时临时禁用对缓冲区的更新。
虽然简单访问器的实现是作为类的一部分提供的,但是类的子类是作为特定驱动程序实现的一部分提供的,并且提供了GetNextUpdatedRegion()、LockBuffer()和UnlockBuffer()的自定义实现。
{{{ class CPL_DLL GDALAsyncReader { protected: GDALDataset* poDS; int nXOff; int nYOff; int nXSize; int nYSize; void * pBuf; int nBufXSize; int nBufYSize; GDALDataType eBufType; int nBandCount; int* panBandMap; int nPixelSpace; int nLineSpace; int nBandSpace; long nDataRead;
公共:GDALAsyncReader(GDALDataset * poDS=NULL);虚拟~gdalasyncreder();
GDALDataset* GetGDALDataset() {return poDS;}
int GetXOffset() {return nXOff;}
int GetYOffset() {return nYOff;}
int GetXSize() {return nXSize;}
int GetYSize() {return nYSize;}
void * GetBuffer() {return pBuf;}
int GetBufferXSize() {return nBufXSize;}
int GetBufferYSize() {return nBufYSize;}
GDALDataType GetBufferType() {return eBufType;}
int GetBandCount() {return nBandCount;}
int* GetBandMap() {return panBandMap;}
int GetPixelSpace() {return nPixelSpace;}
int GetLineSpace() {return nLineSpace;}
int GetBandSpace() {return nBandSpace;}
virtual GDALAsyncStatusType GetNextUpdatedRegion(double dfTimeout,
int* pnBufXOff,
int* pnBufYOff,
int* pnBufXSize,
int* pnBufXSize) = 0;
virtual int LockBuffer( double dfTimeout );
virtual void UnlockBuffer();
friend class GDALDataset;
}; }}}
GetNextUpdatedRegion()
GDALAsyncStatusType
GDALAsyncRasterio::GetNextUpdatedRegion(int dfTimeout,
int* pnBufXOff, int* pnBufYOff,
int* pnBufXSize, int* pnBufXSize);
int dfTimeout;
The amount of time to wait for results measured in seconds. If this is
zero available work may be processed but no waiting for the arrival of more
imagery should be done. A value of -1.0 means wait an infinite amount of
time for new data. Processing available imagery may still take an
arbitrary amount of time.
int *pnBufXOff, *pnBufYOff, *pnBufXSize, *pnBufYSize;
The window of data updated within the async io imagery buffer is returned in
these variables. This information can be used to limit screen redraws or other
processing to the portion of the imagery that may have changed.
异步返回状态列表如下,将在gdal.h中声明。
typedef enum
{
GARIO_PENDING = 0,
GARIO_UPDATE = 1,
GARIO_ERROR = 2,
GARIO_COMPLETE = 3,
GARIO_TypeCount = 4
} GDALAsyncStatusType;
返回值的含义是:
GARIO_PENDING:缓冲区中没有图像更改,但仍有活动挂起,应用程序应在时间允许的情况下继续调用GetNextUpdatedRegion()。
加里奥更新:一些图像已经更新,但仍有活动悬而未决。
加里奥:出了点问题。异步请求应该结束。
GARIO_COMPLETE:已发生更新,此请求没有其他挂起的工作。请求应该结束并使用缓冲区。
GDALDataset
GDALDataset类通过创建异步读取器和清理异步读取器的方法进行扩展。这些方法将由实现异步数据访问的驱动程序子类化。
virtual GDALAsyncReader*
BeginAsyncReader(int nXOff, int nYOff, int nXSize, int nYSize,
void *pBuf, int nBufXSize, int nBufYSize,
GDALDataType eBufType,
int nBandCount, int* panBandMap,
int nPixelSpace, int nLineSpace, int nBandSpace,
char **papszOptions);
virtual void EndAsyncReader(GDALAsyncReader *);
作为gdal/gcore的一部分,应该是默认值!将提供仅使用GDALDataset::的GDALAsyncReader实现!RasterIO()将请求作为单个阻塞请求执行。但是,此默认实现将确保应用程序可以使用异步接口,而不必担心特定格式是否实际异步操作。
GDALDriver
为了向应用程序提示特定格式是否支持异步IO,我们将在实现格式的GDALDriver上添加一个新的元数据项。元数据项将是“DCAP_ASYNCIO”(宏GDAL_DCAP_ASYNCIO),如果异步IO可用,则其值为“YES”。
实现驱动程序将在其驱动程序设置代码中执行以下操作:
poDriver->SetMetadataItem( GDAL_DCAP_ASYNCIO, "YES" );
GDALRasterBand
异步栅格IO的GdalStartBand接口没有更改。异步IO请求只能在数据集级别发出,而不能在带区发出。
计算机辅助编程接口
下面将添加C++类和方法的C API包装器。请注意,此时不打算为所有GDALAsyncReader访问器提供C包装器,因为从启动异步io的调用中提供的信息已经在应用程序中可用。
typedef void *GDALAsyncReaderH;
GDALAsyncStatusType CPL_DLL CPL_STDCALL
GDALGetNextUpdatedRegion(GDALAsyncReaderH hARIO, double dfTimeout,
int* pnXBufOff, int* pnYBufOff,
int* pnXBufSize, int* pnYBufSize );
int CPL_DLL CPL_STDCALL GDALLockBuffer(GDALAsyncReaderH hARIO,double dfTimeout);
void CPL_DLL CPL_STDCALL GDALUnlockBuffer(GDALAsyncReaderH hARIO);
GDALAsyncReaderH CPL_DLL CPL_STDCALL
GDALBeginAsyncReader(GDALDatasetH hDS, int nXOff, int nYOff,
int nXSize, int nYSize,
void *pBuf, int nBufXSize, int nBufYSize,
GDALDataType eBufType,
int nBandCount, int* panBandMap,
int nPixelSpace, int nLineSpace, int nBandSpace,
char **papszOptions);
void CPL_DLL CPL_STDCALL
GDALEndAsyncReader(GDALDatasetH hDS, GDALAsyncReaderH hAsynchRasterIOH);
SWIG
C API中的上述所有函数都将包装成SWIG。
驱动程序实现
异步API的完整实现将作为JPIPKAK驱动程序提供,这是一个使用Kakadu库的JPIP协议实现。
目前,还没有其他的实现计划。
测试
将在测试套件中添加一些针对普通驱动程序的异步api测试,以及使用异步和传统数据访问方法测试JPIPKAK驱动程序。
此外,还实现了一个新的命令行程序gdalasyncread,它提供了一种从命令行测试异步API的机制。它接受gdal_translate命令行选项的子集。
Usage: gdalasyncread [--help-general]
[-ot {Byte/Int16/UInt16/UInt32/Int32/Float32/Float64/
CInt16/CInt32/CFloat32/CFloat64}]
[-of format] [-b band]
[-outsize xsize[%] ysize[%]]
[-srcwin xoff yoff xsize ysize]
[-co "NAME=VALUE"]* [-ao "NAME=VALUE"]
src_dataset dst_dataset