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 储存库。

更改列表: https://github.com/rouault/gdal2/compare/rasterio

投票历史

+1名来自法兰克、朱卡尔、霍华德、丹尼尔姆、塔马斯和埃文