利用GDAL从内存中直接解析图像数据

对于网络数据源,调度中可以把数据写入本地,然后读取本地数据格式进行影像的解析(地形有时候也用tif等格式)。

此种方式会每次调度进行不必要的IO开销和时间花费。

 

GDAL提供了相应的接口,直接从内存中解析数据,避免了磁盘写入和读取操作。具体步骤是:

(1)利用内存中的二进制数据流创建对应的内存文件  即 从 Buffer 创建  memory "file",这里的内存文件路径是位于GDAL自定义的虚拟文件目录 /vsimem/下。

(2)和解析本地文件一样,利用GDALOpen 读取内存文件。

//通过读取本地文件,产生二进制数据流 buffer、size
	FILE* pFile = fopen("D:\\data\\1.tif","rb");
	fseek(pFile,0,SEEK_END);
	int size = ftell(pFile);
	rewind(pFile);

	GByte * buffer  = new GByte [size];
	fread(buffer,1,size,pFile);
	fclose(pFile);

	//利用二进制流创建内存文件
	VSIFCloseL(VSIFileFromMemBuffer("/vsimem/work",buffer,size,FALSE));

	//像打开本地文件一样,利用GDALopen 打开内存文件
	GDALAllRegister();
	GDALDataset* readDS = (GDALDataset*)GDALOpen("/vsimem/work",GA_ReadOnly);
	//释放 内存文件
	VSIUnlink("/vsimem/work");
	
	int width = readDS->GetRasterXSize();
	int height = readDS->GetRasterYSize();
	int bandCount = readDS->GetRasterCount();
	float* data = new float[width*height*bandCount];
	if (readDS->RasterIO(GDALRWFlag::GF_Read,0,0,width,height,data,width,height,GDT_Float32,bandCount,NULL,0,0,0)==CE_Failure)
	{
		GDALClose(readDS);
		//释放二进制数据流
		delete[] buffer;
		buffer = NULL;

		delete[] data;
		data = NULL;
	}

	GDALClose(readDS);
	delete[] buffer;
	buffer = NULL;
	//现在只需操纵data就好,用完释放
	delete[] data;
	data = NULL;
这里需注意,内存中二进制数据流 buffer 的释放是 在数据读取结束才能做,否则会出现RasterIO 失败。

这也正好说明,创建的内存文件 "/vsimem/work" 没有重新分配内存保存图像数据块,而是指向二进制数据流 buffer。

 

参考:

http://cryolite.iteye.com/blog/358929

http://blog.csdn.net/liminlu0314/article/details/40209357

http://www.gdal.org/cpl__vsi_8h.html#af9c1b931449d423e7a80bacb75ff0717

posted @ 2015-08-23 23:30  Geospatial  阅读(3308)  评论(0编辑  收藏  举报