GDALDataset::RasterIO()
参数
函数原型:
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
)
-
eRWFlag - 枚举,
GF_Read
代表将数据读取到缓存中,GF_Write
代表将数据从缓存写入栅格。 -
nXOff - 栅格像素在x轴上的偏移起始位置
-
nYOff - 栅格像素在y轴上的偏移起始位置
-
nXSize - 需要读/写的栅格宽度
-
nYSize - 需要读/写的栅格高度
如:在一个4x4像素的栅格中,通过以上四个参数指定出红色的4个像素。
示例.png -
pData - 缓冲区,eRWFlag为
GF_Read
时,栅格数据被读取进该缓冲区;当eRWFlag为GF_Write
时,此缓冲区的数据写入栅格。 -
nBufXSize - 缓冲区的宽度
-
nBufYSize - 缓冲区的高度
-
eBufType - 像素的数据类型,此类型会决定了pData的真实类型。
-
nBandCount - 波段数量,指定要读/写的波段数
-
panBandMap - 波段数组,指定要读/写的具体波段
-
nPixelSpace - 指定在
pData
中存放源栅格一个像素开始到下一个像素的字节偏移量,默认(0)则是eBufType的大小。 -
nLineSpace - 指定
pData
中存放原栅格一行到下一行的字节偏移量,默认(0)则是eBufType * nBufXSize的大小。 -
nBandSpace - 指定一个波段到下一个波段的字节偏移量,默认(0)则是eBufType * nBufXSize * nBufYSize。
通过参数指定波段
源码分析:
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,
- 情形一,nPixelSpace=1byte, nLineSpace=3byte,nBandSpace=9byte。
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,
分析:
- 情形二,nPixelSpace=2byte, nLineSpace=6byte,nBandSpace=1byte。
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
- 情形三,nPixelSpace=3byte, nLineSpace=3byte,nBandSpace=1byte。
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.