zoukankan      html  css  js  c++  java
  • GDAL中MEM格式的简单使用示例

    GDAL库中提供了一种内存文件格式——MEM。如何使用MEM文件格式,主要有两种,一种是通过别的文件使用CreateCopy方法来创建一个MEM;另外一种是图像数据都已经存储在内存中了,然后使用内存数据块来构造一个MEM。第一种方式比较简单,这里主要说明下第二种方式。
    首先看看MEM的说明文档,地址为:www.gdal.org/frmt_mem.html。从里面我们可以看到MEM文件支持几乎所有的空间数据信息,包括投影,坐标,GCP,元数据等信息。下面就主要看看怎么从一个内存数据块来构造一个MEM文件。MEM文件的数据名称如下:
    MEM:::option=value[,option=value...]
    例如:
    MEM:::DATAPOINTER=342343408,PIXELS=100,LINES=100,BANDS=3,DATATYPE=Byte,PIXELOFFSET=3,LINEOFFSET=300,BANDOFFSET=1
    可以看到MEM文件名开头有MEM后接三个英文冒号(:::),解析来由一系列的选项=值的方式来组成,具体选项和说明如下:
    • DATAPOINTER:内存数据块的指针地址,指针地址使用长整形来进行表示。注意:指针地址与32位或者64位系统有关系,要注意对应关系。必填项
    • PIXELS:图像宽度。必填项
    • LINES:图像高度,行数。必填项
    • BANDS:波段数,默认为1。选填项
    • DATATYPE:数据类型的名称(如Byte,Int16等),可以通过函数GDALGetDataTypeName()来获取,默认为Byte。选填项
    • PIXELOFFSET:像素偏移量,以Byte为单位。选填项
    • LINEOFFSET:行偏移量,以Byte为单位。选填项
    • BANDOFFSET:波段偏移量,以Byte为单位。选填项
    其中前三项为必填项,必须指定,其余五项为选填项,最后三项和RasterIO函数的最后三个参数的意思相同。
    下面是一个简单的示例代码,主要作用就是从一个大图像中读取512*512的大小的图像,然后将读取出来的图像构造一个MEM文件,并将该文件存储为一个PNG图像出来。

    void GDAL_MEM_Test()
    {
    	GDALAllRegister();
    	
    	// 打开原始图像
    	GDALDataset *pSrcDS = (GDALDataset*) GDALOpen("D:\Data\landsat\p139r26_5t19900902_nn2.tif", GA_ReadOnly);
    	GDALRasterBand *pBand = pSrcDS->GetRasterBand(1);
    
    
    	// 申请512*512大小的内存,用于存放像素值
    	unsigned char *pData = new unsigned char[512*512];
    	memset(pData, 0, 512*512);
    
    
    	// 从2500,2500开始宽高均读取256个像素
    	pBand->RasterIO(GF_Read, 2500, 2500, 512, 512, pData, 512, 512, GDT_Byte, 0, 0);
    
    
    	//使用读取出来的pData构造一个MEM数据集
    	//"MEM:::DATAPOINTER=342343408,PIXELS=100,LINES=100,BANDS=3,DATATYPE=Byte,PIXELOFFSET=3,LINEOFFSET=300,BANDOFFSET=1"
    	char aMemString[256] ={0};
    	//构造MEM的文件名
    	sprintf_s(aMemString, 256, "MEM:::DATAPOINTER=%d,PIXELS=%d,LINES=%d", pData, 512, 512);
    
    
    	//打开MEM文件
    	GDALDataset *pMemDS = (GDALDataset*) GDALOpen(aMemString, GA_ReadOnly);
    	
    	GDALDriver *pDriver = GetGDALDriverManager()->GetDriverByName("PNG");
    	GDALDataset *pOutDS = pDriver->CreateCopy("D:\Data\landsat\p139r26_5t19900902_nn2_sub.png", pMemDS, FALSE, NULL, NULL, NULL);
    
    
    	GDALClose((GDALDatasetH) pSrcDS);
    	GDALClose((GDALDatasetH) pMemDS);
    	GDALClose((GDALDatasetH) pOutDS);
    
    	delete []pData;
    }
    裁切的原始图像如下图所示,图中的红色区域大致为代码中读取出来的区域,右下角为鹰眼图。
     

    下图是构造的MEM并输出的结果,可以看出图像的区域与上图中的红色区域中的一样。对于需要从图像中裁切一块数据除了使用RasterIO和Cereate方式之外,还可以使用MEM,比较方便,不需要复杂的代码即可完成工作;同时对于某些算法需要将数据做成一个临时文件放到磁盘上,然后再处理的情况,可以考虑使用这种方式,即不将数据写入磁盘,所有的数据都在内存中进行处理,可以很大程度上提高算法的效率。


    需要注意的是,MEM文件大小是和你的系统内存大小有关系。如果使用32位程序的话,处理的数据保守估计不会超过2GB,如果是64位程序的话,只和你机器的内存大小有关系了。
  • 相关阅读:
    《Docker Deep Dive》Note
    使用 Angular RouteReuseStrategy 缓存(路由)组件
    我的 VSCode 配置
    TCP/IP协议
    Fiddler代理手机抓包
    基于 Docker 和 GitLab 的前端自动化部署实践笔记
    Vue.js 2.x render 渲染函数 & JSX
    服务器免密登陆脚本
    gitlab+jenkins+pm2+rsync实现node的自动化部署
    nginx常用
  • 原文地址:https://www.cnblogs.com/xiaowangba/p/6313926.html
Copyright © 2011-2022 走看看