GDAL的RASTERIO功能
为了能快速的显示大影像,最近一直在学习GDAL,GDAL确实是一个功能强大的开源库,其核心部分数据集和波段,下面这个图很详细的描述了它们之间的关系,还有其中的细节:

GDAL的RASTERIO功能非常强大,简短的一句话就能实现图像的显示,但也是这个简单函数,把我折腾的半死。在学习使用GDAL的过程中,非常感谢李林大哥和貟建明大哥,他们不厌其烦地解答我的疑问,提示关键性要点,使我在解决问题的过程中事半功倍。
我现在要把最近学习过程中的心得写下来,留给自己以后看看,也希望可以给新手们一点帮助!
GDALAllRegister();
const char* str ;
m_pDataset = (GDALDataset*) GDALOpen( str, GA_ReadOnly );这一部分应该很好理解,首先打开一个影像,我们必须注册其驱动,因为每种不同的栅格数据都有不同的驱动,也就是driver。之后我们就可以用GDALOpen()函数来打开一个数据集dataset,如果打开的格式并不是GDAL支持的,我们就需要通过new GDALDriver()创建一个新的driver并设置,这样才能打开。如果GDALOpen()函数返回NULL,表示打开文件失败。
打开了一个dataset之后,我们就可以对dataset的内部信息进行操作,dtaset的详细信息以及内部的关系在上图表述的非常详细。
m_pDataset->GetGeoTransform( m_AdfGeoTransform );上面这行代码是用来获取仿射信息用的,m_AdfGeoTransform是一个含6个元素的数组,执行了这行代码后,我们就可以获取m_AdfGeoTransform数组的信息,m_AdfGeoTransform[0],m_AdfGeoTransform[3]是整个影像的坐下角坐标,m_AdfGeoTransform[1]是影像宽度上的分辨率,m_AdfGeoTransform[5]是影像高度上的分辨率,而对于m_AdfGeoTransform[2]和m_AdfGeoTransform[4]来说,如果影像是指北的,这两个参数的值为0。有了这几个参数,我们就能通过以下两行代码求出影像左下角和右上角的信息:
XMin = m_AdfGeoTransform[0];
YMin = m_AdfGeoTransform[3];
XMax = m_AdfGeoTransform[0] + nX * m_AdfGeoTransform[1] + m_AdfGeoTransform[2];
YMax = m_AdfGeoTransform[3] + m_AdfGeoTransform[4] + nY * m_AdfGeoTransform[5]; 有了影像的信息之后,我们要做的就是将影像显示出来,这里就有一个分辨率的问题,一个是图像分辨率,一个是显示分辨率。图像分辨率就是单位长度内的像素数,而显示分辨率就是把数字图像在输出设备(比如显示屏或打印机等)上能够显示的像素数目和所显示像素之间的点距。这两个分辨率在显示影像的时候非常有作用。弄清楚原理的东西确实是成功的基石!
然后就到了GDAL的核心部分了:
pBuffer = (BYTE*) CPLMalloc(sizeof(BYTE)*(xBuf)*(yBuf)*nBand);
m_pDataset->RasterIO( GF_Read, xSrc, ySrc, xWidth, yHight, pBuffer, xBuf, yBuf,GDT_Byte, nBand, NULL, nBand, 0, 1 ); 对于三个波段以上的影像,我们可以直接通过以上两行代码讲影像读入pBuffer这个内存,然后根据我们的需要,比如说OPENGL,我们就可以利用glDrawPixels( )这个函数直接显示出影像了。现在关键的地方就是RasterIO里面的几个参数了,对照GDAL官方的函数说明:
GDALDataset::RasterIO ( GDALRWFlag eRWFlag,
int nXOff,
int nYOff,
int nXSize,
int nYSize,
void * pData,
int nBufXSize,
int nBufYSize,
GDALDataType eBufType,
int nBandCount,
int * panBandMap,
int nPixelSpace,
int nLineSpace,
int nBandSpace
) 
如果为GF_Read,则是将影像内容写入内存,如果为GF_Write,则是将内存中内容写入文件。
nXOff,nYOff,nXSize,nYSize这四个参数是用于影像的,nXOff,nYOff就是说我们要从影像的这个像素坐标开始取数据,nXSize,nYSize就是从影像上取数据的宽度和高度,也就是说要从影像上取出来的数据范围是(nXOff,nYOff)到(nXOff+nXSize,nYOff+nYSize)。如果我们要显示这个取出来的范围,我们就要把这个数据域写入缓存pData中,nBufXSize,nBufYSize即是这个缓存区的大小范围。
RasterIO这个函数只有这些说明,那我们在应用的时候就需要根据我们的实际需要计算,如果有一幅100M的影像,你想快速显示,那么这六个参数的设置就是关键,不过有一个前提条件就是这个影像是金字塔影像,这样你设置好了buffer的size,那么GDAL就会根据GDAL内部函数的实现过程,自动帮你完成缩放操作(把nXSize,nYSizen的数据缩放到BufXSize,nBufYSize的buffer里显示),而并不需要你去控制获取哪个overview,由于开始我并没有理解透这个函数的真正含义,在大影像的显示上走了很多弯路,自己去判断要读金字塔的第几层,以至于自己都把自己快搞崩溃了,这里要非常感谢李林大哥,呵呵,每个细节都给我讲的很详细,并且对于一些抽象的东西他也耐心的给我举些例子,加上自己的时间,最后终于明白了这个函数的原理所在。呵呵,在这里要真挚的感谢李大哥。
nBufXSize,nBufYSize这个缓存区的大小范围,决定了我们要在多大的屏幕范围显示你想显示的图像内容,因此我们要根据屏幕范围和缩放比例来计算这个buffer的size。
nPixelSpace表示一个像素所占byte大小,假如是24位的,那么一个像素就占3个字节,那么nPixelSpace = 3。nLineSpace表示一行所占大小,如果设为0的话,就默认为nBufXSize*nBufYSize。
nBandSpace为一个波段数据所占大小,如果设为0的话,就是以RRRGGGBBB这种形式存储,如果设为1的话,就是以RGBRGBRGB这种形式存储。
不过这个函数还是要自己试了才知道真正的意义,呵呵,希望新手少走我的弯路!!以后还会陆续添加自己的学习心得的,^_^Fighting!!!o(∩_∩)o...
GDAL的RASTERIO功能的更多相关文章
- GDAL中RasterIO函数(把文件读取为一个一维数组)和ReadBlock函数(读取栅格数据块)
CPLErr GDALRasterBand::RasterIO ( GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize, ...
- gdal读写图像分块处理(精华版)
一.gdal进行数据操作在安装好gdal后,即可调用gdal库中的函数.(需要包含的头文件:gdal_priv.h)1.打开数据集使用gdal库进行数据(影像)操作的第一步就是打开一个数据集.对于“数 ...
- gdal读写图像分块处理
转自赵文原文 gdal读写图像分块处理(精华版) Review: 用gdal,感觉还不如直接用C++底层函数对遥感数据进行处理.因为gdal进行太多封装,如果你仅仅只是Geotif等格式进行处理,IO ...
- GDAL指定自定义的金字塔目录
缘起 对于一般的遥感影像文件,金字塔文件默认都是与影像文件放在同一个目录下,金字塔文件名一般与源影像文件名相同,但后缀名不同.或者金字塔内建于影像内部,但这不是这里所涉及的. 在使用ArcGIS桌面版 ...
- GDAL库简介以及在Windows下编译过程
GDAL(Geospatial Data Abstraction Library,地理空间数据抽象库)是一个在X/MIT许可协议下的开源栅格空间数据转换库.官网http://www.gdal.org/ ...
- (数据科学学习手札143)为geopandas添加gdb文件写出功能
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 大家好我是费老师,很多读者朋友跟随着我先前写作的 ...
- VS下的解决方案目录结构设置和管理
转载:http://blog.csdn.net/pl20140910/article/details/52074165 为了方便管理自己写的代码,也为了日后工作能方便的查找之前做过相同的代码,仿照某源 ...
- 栅格那点儿事(四E)
栅格金字塔 如果上面的部分都已经看过了,那么如何在ArcMap中更好的渲染一个栅格数据你已经知道了.可仅展示好一个栅格数据是不够的,我们还需要知道如何快速的展示一个栅格数据. 讲金字塔之前,先解释 ...
- 【C#】C#中使用GDAL3(一):Windows下超详细编译C#版GDAL3.3.0(VS2015+.NET 4+32位/64位)
转载请注明原文地址:https://www.cnblogs.com/litou/p/15004877.html 目录 一.介绍 二.编译准备 三.编译SQLite 四.编译LibTiff 五.编译PR ...
随机推荐
- 用lsb_release -a 查看linux版本
1.要通过yum 安装上这个命令的软件包 yum -y install redhat-lsb 2.lsb_release -a 查看linux版本信息
- FAT16文件系统简介
有必要说明一下,以下对FAT16系统的介绍,很多都是参考文献.由于FAT16系统一般在U盘.MMC卡.SD卡以及一些小型存储设备上使用比较多,以后把这些小型存储设备统称为存储卡,这里仅局限于对存储卡的 ...
- C# unsafe code
(*) unsafe 和 fixed unsafe { ]; ; i < array.Length; i++) { arra ...
- jquery中使用offset()获得的div的left=0,top=0
写东西的时候要获取div的left和top,但怎么也取不到值都为0,但在chrome的console下是可以取到值的, 瞬间就纳闷了,于是乎就在网上找各种方法,大家一般的问题可能都是要获取的div被隐 ...
- C++对象模型浅析
本文仅代表博主自己对C++内存对象模型的一点理解,如果文中有 理解偏差和不准确的地方,希望各位大大提出,我好及时改正. 本博文只对博主自己负责,不对任何人负责. 就如<深度探索C++对象模型&g ...
- 正则表达式小试牛刀--匹配我的csdn博文标题
正则表达式小试牛刀--匹配我的博文标题 作者:vpoet 邮箱:vpoet_sir@163.com 正则匹配,我以我的博客页面的博客标题为例:http://blog.csdn.net/u0130187 ...
- poj 2395 Out of Hay(最小生成树,水)
Description The cows have run <= N <= ,) farms (numbered ..N); Bessie starts at Farm . She'll ...
- 解决 VM虚拟机网卡无法拉起 的问题
复制虚拟机后,第二块网卡始终无法正常运作,表现为无法自动获得dhcp地址,且重启后与第一块网卡使用同样的地址,让人苦笑不得,反复重启了很多次都是这样,后面想到ifcfg-eth1的配置文件可能写得太简 ...
- IOS7 UITableView一行滑动删除后 被删除行的下一行的点击事件将被忽略解决办法
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSI ...
- ViewPager的Adapter中视图重用
ViewPager的PagerAdapter不像ListView/GridView的BaseAdapter,它是没有内部视图重用机制的,也就是说我先inflate出来一个,然后调用destroyIte ...