GDALDataset::RasterIO()

2023-03-21  本文已影响0人  NullUser

参数

函数原型:

CPLErr RasterIO
(
GDALRWFlag eRWFlag, 
int nXOff, 
int nYOff,
int nXSize, 
int nYSize, 
void* pData, 
int nBufXSize, 
int nBufYSize, 
GDALDataType eBufType,
int nBandCount ,
int *panBandMap ,
GSpacing nPixelSpace,
GSpacing nLineSpace,
GSpacing nBandSpace,
GDALRasterIOExtraArg *psExtraArg
)

通过参数指定波段

源码分析:

    int anBandMap[] = { 1, 2, 3, 4 };
    if( panBandMap == nullptr )
    {
        if( nBandCount > 4 )
        {
            panBandMap =
                static_cast<int *>(VSIMalloc2(sizeof(int), nBandCount));
            if (panBandMap == nullptr)
            {
                ReportError(CE_Failure, CPLE_OutOfMemory,
                            "Out of memory while allocating band map array");
                return CE_Failure;
            }

            for( int i = 0; i < nBandCount; ++i )
                panBandMap[i] = i + 1;

            bNeedToFreeBandMap = true;
        }
        else
        {
            panBandMap = anBandMap;
        }
    }

从GDALDataset::RasterIO()源码中可以看出,其默认了有四个波段,当未指定具体波段时(即传入panBandMap为空指针),会根据传入的波段数使用默认的波段数组。

指定IO规则

通过指定nPixelSpace、nLineSpace、nBandSpace,可以以不同的规则进行IO。

关于nPixelSpace、nBandSpace、nLineSpace参数和pData内存的关系可见下图:
nPixelSpace指定栅格像素在pData中所占的空间,即指定行列号所对应的像素占用的空间。
nBandSpace指定栅格一个波段到下一个波段的偏移大小。
如图中所示,假设nPixelSpace为3,nBandSpace为1,即一个行列号所对应像素的空间为3,一个波段空间为1,那么可以在pData连续内存内储存一个像素的3个波段数据(3 / 1 = 3),如果栅格有5个波段,那么第4、5个波段的数据将无法储存。
nLineSpace指定栅格中的一行在pData中的空间,假设pLineSpace为10,那么可以在pData连续内存内储存一行中的三个像素(10 / 3 = 3),如果一行有4个像素,那么第四个像素的值将不会被放入pData.


pData.png

IO示例:

以读取为例,假定样例栅格为:
3x3,2个波段。
假设1波段数据为:

11,12,13,
14,15,16,
17,18,19,

2波段数据为:

21,22,23,
24,25,26,
27,28,29,
    int nPixelSpace = sizeof(GByte);
    int nLineSpace = sizeof(GByte) * nXSize;
    int nBandSpace = sizeof(GByte) * nXSize * nYSize;
    //int nBandSpace = sizeof(GByte);
    GByte* pData= (GByte*)VSI_MALLOC2_VERBOSE(sizeof(GByte), nXSize * nYSize * 2);
    poDs->RasterIO(GF_Read,
        0, 0, nXSize, nYSize,
        pData, nXSize, nYSize, GDT_Byte,
        2, nullptr,
        nPixelSpace, nLineSpace, nBandSpace, nullptr);
    int index = 0;
    for (; index < nXSize * nYSize * 2; index++)
    {
        printf("%d,", pData[index]);
    }
    printf("\n");

输出:

11,12,13,14,15,16,17,18,19,21,22,23,24,25,26,27,28,29,

分析:

    int nPixelSpace = sizeof(GByte) * 2 ;   //2
    int nLineSpace = sizeof(GByte) * 2 * nXSize; //6
    int nBandSpace = sizeof(GByte);   //1

输出:

11,21,12,22,13,23,14,24,15,25,16,26,17,27,18,28,19,29
    int nPixelSpace = sizeof(GByte) * 3;        //3
    int nLineSpace = sizeof(GByte)  * nXSize;   //3
    int nBandSpace = sizeof(GByte);             //1

输出:

11,21,0,14,24,0,17,27,0,18,28,0,19,29,0,0,0,0

分析:像素占用空间为3字节,栅格一行占用空间3字节,此时栅格中的一行数据只允许储存一个像素(3 / 3 =1),也就是说栅格每行的第2,3个像素将被舍弃,不会放入pData。而band的偏移为1字节,所以一个像素可以放三个波段的数据(3 / 3=1),而源栅格只有两个波段,所有每个像素对应的三个字节中,第三个字节输出为0.

上一篇下一篇

猜你喜欢

热点阅读