查看: 6111|回复: 3

【原创】浅谈用GDAL的RasterIO( )做大影像分块

[复制链接]

该用户从未签到

发表于 2008-3-3 12:42:05 | 显示全部楼层 |阅读模式
GDAL的GDALDataset和GDALRasterBand类为我们提供了功能强大的RasterIO(…)函数,它可以把图像上 指定大小的矩形象素块 以缩放的形式 按指定的数据类型 输出或输入到 用户指定大小的缓冲区中。
原型:
CPLErr GDALDataset::RasterIO(
GDALRWFlag eRWFlag, //读写标记
int nXOff, int nYOff,//相对于图像左上角顶点(从零开始)的行列偏移量
int nXSize, int nYSize,//要读写的块在x方向的象素个数和y方向的象素列数
void * pData,//指向目标缓冲区的指针,由用户分配
int nBufXSize, int  nBufYSize,//目标块在x方向上和y方向上的大小
GDALDataType eBufType, //目标缓冲区的数据类型,原类型会自动转换为目标类型
int nBandCount, //要处理的波段数
int * panBandMap,//记录要操作的波段的索引(波段索引从1开始)的数组,若为空,//则数组中存放的是前nBandCount个波段的索引
int nPixelSpace,//x方向上两个相邻象素之间的字节偏移,默认为0,则列间的实际//字节偏移由目标数据类型eBufType确定
int nLineSpace, //y方向上相邻两行之间的字节偏移, 默认为0,则行间的实际字节//偏移为eBufType * nBufXSize
int nBandSpace  //相邻两波段之间的字节偏移,默认为0,则意味着波段是顺序结构//的,其间字节偏移为nLineSpace * nBufYSize
);

CPLErr GDALRasterBand::RasterIO(//各参数意义同上
GDALRWFlag eRWFlag,
int nXOff, int nYOff,
int nXSize, int nYSize,
void * pData,//
int nBufXSize, int  nBufYSize,
GDALDataType eBufType,
int nBandCount,
int nPixelSpace,
int nLineSpace,
);
上述函数的区别在于前者是对同一数据集的多个波段操作,而后者是对单个波段的操作。

基于以上的GDALRasterBand::RasterIO()函数构建影像分块的类clsDOM,并在类中做了函数SmartRead()进行缩放读取dom,处理过程为:
//打开文件获得指向该文件的GDALDataset指针
clsDOM::OpenFile();
//指定分块的大小
clsDOM::SetBlockSize();
//循环处理每一块
{
//SmartRead()内部调用RasterIO(),此时动态分配当前块的内存
clsDOM::SmartRead();
//每一块处理完之后立即释放当前块
}
//所有块处理完后,释放GDALDataset指针
clsDOM::CloseFile();
跟踪以上过程发现读取各块时内存逐次增长,虽然每次循环都释放了当前块,但是仍无法回落到处理这一块之前的值,直到最终释放GDALDataset指针内存才会回落至打开文件前的值。内存的不断增长显然对处理大文件会产生致命问题!究其原因,每执行一次RasterIO内存都会(不太慢的)增长,以致于每一块处理完后内存不彻底回落。尝试每次处理完后删除当前的RasterBand指针也无法回落。最终解决办法是处理每一块时都执行一次打开文件和关闭文件释放GDALDataset指针的操作:
//指定分块的大小
clsDOM::SetBlockSize();
//循环处理每一块
{
//处理每一块之前打开文件获得指向该文件的GDALDataset指针
clsDOM::OpenFile();
//SmartRead()内部调用RasterIO(),此时动态分配当前块的内存
SmartRead();
//每一块处理完之后立即释放当前块
//…
//当前块处理完后,释放GDALDataset指针
CloseFile();
}
这样做内存的开销极小,但频繁的打开关闭文件总是不太好。
另外,如果是数据库连接,像下面这样反复连接更是不可取的:
        GDALOpenInfo  OpenInfo(szdbConnect , GA_ReadOnly);
        GDALDataset   poDataset=SDEDataset::Open(&OpenInfo);
关注此页的朋友,如有更好的解决办法,请联系我xuex_chen@126.com 或加入我的群46328427讨论。

该用户从未签到

发表于 2008-3-3 13:21:05 | 显示全部楼层


不错,呵呵~~~~~~~~~~~~~ :) :)
  • TA的每日心情
    开心
    2019-11-11 10:36
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2008-3-3 15:08:28 | 显示全部楼层
    把姓名或是ID留下,我给你转到前面去,,


    附:能不能写个小程序出来,我们割个试试,,,,现在工具割多一些,如果代码好使,稳定的话,那方便了,整个过程向机械化又迈了一步
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    OSG中国官方论坛-有您OSG在中国才更好

    网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

    联系我们

    • 工作时间:09:00--18:00
    • 反馈邮箱:1315785073@qq.com
    快速回复 返回顶部 返回列表