對於網絡數據源,調度中可以把數據寫入本地,然后讀取本地數據格式進行影像的解析(地形有時候也用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
