RFC 51:RasterIO()改进:重新采样和进度回调
作者:连鲁奥
联系人:spatialys.com上的偶数点rouault
状态:采用,在GDAL 2.0中实现
总结
此RFC旨在扩展RasterIO()API,以便在执行涉及子采样或过采样的请求时指定重新采样算法。进程回调也可以指定为通知进程并允许用户中断操作。
核心变化
添加GdalStartioExtraarg结构
将添加新结构GDALRasterIOExtraArg以包含新选项。
/** Structure to pass extra arguments to RasterIO() method
* @since GDAL 2.0
*/
typedef struct
{
/*! Version of structure (to allow future extensions of the structure) */
int nVersion;
/*! Resampling algorithm */
GDALRIOResampleAlg eResampleAlg;
/*! Progress callback */
GDALProgressFunc pfnProgress;
/*! Progress callback user data */
void *pProgressData;
/*! Indicate if dfXOff, dfYOff, dfXSize and dfYSize are set.
Mostly reserved from the VRT driver to communicate a more precise
source window. Must be such that dfXOff - nXOff < 1.0 and
dfYOff - nYOff < 1.0 and nXSize - dfXSize < 1.0 and nYSize - dfYSize < 1.0 */
int bFloatingPointWindowValidity;
/*! Pixel offset to the top left corner. Only valid if bFloatingPointWindowValidity = TRUE */
double dfXOff;
/*! Line offset to the top left corner. Only valid if bFloatingPointWindowValidity = TRUE */
double dfYOff;
/*! Width in pixels of the area of interest. Only valid if bFloatingPointWindowValidity = TRUE */
double dfXSize;
/*! Height in pixels of the area of interest. Only valid if bFloatingPointWindowValidity = TRUE */
double dfYSize;
} GDALRasterIOExtraArg;
#define RASTERIO_EXTRA_ARG_CURRENT_VERSION 1
/** Macro to initialize an instance of GDALRasterIOExtraArg structure.
* @since GDAL 2.0
*/
#define INIT_RASTERIO_EXTRA_ARG(s) \
do { (s).nVersion = RASTERIO_EXTRA_ARG_CURRENT_VERSION; \
(s).eResampleAlg = GRIORA_NearestNeighbour; \
(s).pfnProgress = NULL; \
(s).pProgressData = NULL; \
(s).bFloatingPointWindowValidity = FALSE; } while(0)
与RasterIO()方法相比,更喜欢结构而不是新参数有几个原因:
代码可读性(GDALDataset::IRasterIO()已经有14个参数…)
允许将来扩展而不更改所有驱动程序中的原型
在较小程度上,效率:在泛型/特定和/或数据集/栅格带实现之间链接RasterIO()调用是很常见的。只传递指针更有效。
结构已版本化。将来如果添加更多选项,新成员将添加到结构的末尾,版本号将递增。GDAL内核中的代码&驱动程序可以检查版本号以确定哪些选项可用。
添加GDALRIOResampleAlg结构
以下重采样算法可用:
/** RasterIO() resampling method.
* @since GDAL 2.0
*/
typedef enum
{
/*! Nearest neighbour */ GRIORA_NearestNeighbour = 0,
/*! Bilinear (2x2 kernel) */ GRIORA_Bilinear = 1,
/*! Cubic Convolution Approximation (4x4 kernel) */ GRIORA_Cubic = 2,
/*! Cubic B-Spline Approximation (4x4 kernel) */ GRIORA_CubicSpline = 3,
/*! Lanczos windowed sinc interpolation (6x6 kernel) */ GRIORA_Lanczos = 4,
/*! Average */ GRIORA_Average = 5,
/*! Mode (selects the value which appears most often of all the sampled points) */
GRIORA_Mode = 6,
/*! Gauss blurring */ GRIORA_Gauss = 7
} GDALRIOResampleAlg;
当缓冲区的大小(nBufXSize x nBufYSize)与感兴趣区域的大小(nXSize x nYSize)不同时,GDALRasterBand::IRasterIO()默认实现可以使用这些新的重采样方法。代码在很大程度上依赖于用于概览计算的算法,通过调整也能够处理过采样。双线性、CubicSpline和Lanczos现在也可用于概述计算,并且依赖于最近引入的卷积计算的通用基础设施来改进立方概述。有些算法在带有调色板的栅格标注栏上不可用。如果尝试这样做,将发出警告,最近的邻居将用作回退。
GDAL_RASTERIO_RESAMPLING配置选项可以设置为指定重采样算法的另一种方式。主要用于对尚未使用新API的应用程序进行测试。
目前,新的重采样方法仅适用于GF_读取操作。GF_写操作的用例并不明显,但如果需要的话,可以在不更改API的情况下添加。
C++的变化
GDALDataset和GDALRasterBand(非虚拟)RasterIO()和(虚拟)IRasterIO()方法有一个新的最终参数psExtraArg,类型为GDALRasterIOExtraArg*。对于使用GDAL的代码,此额外参数默认为空,但对于所有树内代码都是必需的,这样可以避免树内代码忘记转发psExtraArg,因为它可能是从调用方返回的。
GDALDataset::RasterIO()和gdalrasteriband::RasterIO()可以接受该参数的空指针,在这种情况下,它们将实例化要传递给IRasterIO()的默认GDALRasterIOExtraArg结构。任何其他直接调用IRasterIO()的代码(一些IReadBlock()实现)都应该确保这样做,以便IRasterIO()可以假定其psExtraArg不是NULL。
为了能够处理缓冲区大于千兆字节的非常大的请求,nPixelSpace、nLineSpace和nBandSpace参数已从int数据类型提升到新的GSpacing数据类型,后者是有符号64位整数的别名。
GDALRasterBand::IRasterIO()和GDALDataset::BlockBasedRasterIO()现在在可用时使用进度回调。
C API更改
仅添加:
CPLErr CPL_DLL CPL_STDCALL GDALDatasetRasterIOEx(
GDALDatasetH hDS, GDALRWFlag eRWFlag,
int nDSXOff, int nDSYOff, int nDSXSize, int nDSYSize,
void * pBuffer, int nBXSize, int nBYSize, GDALDataType eBDataType,
int nBandCount, int *panBandCount,
GSpacing nPixelSpace, GSpacing nLineSpace, GSpacing nBandSpace,
GDALRasterIOExtraArg* psExtraArg);
CPLErr CPL_DLL CPL_STDCALL
GDALRasterIOEx( GDALRasterBandH hRBand, GDALRWFlag eRWFlag,
int nDSXOff, int nDSYOff, int nDSXSize, int nDSYSize,
void * pBuffer, int nBXSize, int nBYSize,GDALDataType eBDataType,
GSpacing nPixelSpace, GSpacing nLineSpace,
GDALRasterIOExtraArg* psExtraArg );
这些函数与具有最终GDALRasterIOExtraArg的现有函数相同 * psExtraArg参数,间距参数提升为GSpacing。
驱动因素的变化
所有实现或使用RasterIO的树内驱动程序都已编辑为接受GDALRasterIOExtraArg * psExtraArg参数,需要时转发。那些拥有自定义RasterIO()实现的用户现在可以在可用时使用进度回调。
VRT:and元素可以接受“重采样”属性。VRT驱动程序还将设置GDALRasterIOExtraArg的dfXOff、dfYOff、dfXSize和dfYSize字段 * 要获得源亚像素精度,以便在感兴趣的小区域或整个栅格上操作时,GDALRasterBand::IRasterIO()会导致一致的结果。如果不这样做,在gdaldatasetcopywholerater()或其他算法中完成的分块可能会由于整数舍入问题而导致重复行。
公用设施的变化
gdal_translate:接受a-r参数以指定重采样算法。默认为“近”。可以设置为双线性、立方、立方线、lanczos、平均或模式。(在引擎盖下,这将在VRT源级别设置新的重采样属性。)
gdaladdo:-r参数现在接受双线性、cubicspline和lanczos作为现有算法的附加算法。
SWIG绑定的更改
对于Python和Perl绑定:Band.ReadRaster(),Dataset.ReadRaster()现在接受可选的重采样、回调和回调数据参数。(Perl未经测试,但现有测试通过)
对于Python绑定,Band.ReadAsArray()和Dataset.ReadAsArray()现在接受可选的重采样、回调和回调数据参数。
兼容性
保存API/ABI。
C++的GalrasBiels::RaStIORE()和GDAdDATAET::RestIORE()API不需要改变它们的代码,因为新的GDRArStIORIONTURG * psExtraArg参数对于树外代码是可选的。
实现IRasterIO()的树外驱动程序必须更改为接受新的gdalStartioExtraarg * psExtraArg参数。注意:如果编译失败,将不会在编译时发现(由于C++虚拟方法重载工作)。
这两个问题都将在迁移中提到_指南.TXT
文档
所有新方法都记录在案。
测试
在Python绑定中测试了此RFC的各个方面:
使用Band.ReadRaster()、Dataset.ReadRaster()、Band.ReadAsArray()和Dataset.ReadAsArray()的新选项。
子采样和过采样RasterIO()请求中的重采样算法。
gdalúu translate的“-r”选项
实施
实施将由甚至鲁奥完成 (Spatialys _),并由 R3 GIS .
建议的实现位于 https://github.com/rouault/gdal2/tree/rasterio 储存库。
投票历史
+1名来自法兰克、朱卡尔、霍华德、丹尼尔姆、塔马斯和埃文