本文介紹基於C++語言GDAL庫,為CreateCopy()函數創建的柵格圖像添加更多波段的方法。 在C++語言的GDAL庫中,我們可以基於CreateCopy()函數與Create()函數創建新的柵格圖像文件。其中,CreateCopy()函數需要基於一個已有的柵格圖像文件作為模板,將模板文件的各 ...
本文介紹基於C++語言GDAL
庫,為CreateCopy()
函數創建的柵格圖像添加更多波段的方法。
在C++語言的GDAL
庫中,我們可以基於CreateCopy()
函數與Create()
函數創建新的柵格圖像文件。其中,CreateCopy()
函數需要基於一個已有的柵格圖像文件作為模板,將模板文件的各項屬性信息(例如空間參考信息、像元個數、像元大小、波段數量等),自動作為新創建的柵格圖像文件的屬性信息;而Create()
函數則是僅僅新建立一個柵格圖像,需要我們自行定義新柵格圖像的各類屬性信息。
因此,一般我們選擇CreateCopy()
函數來創建柵格圖像文件較為方便,因為其不需要我們手動為所創建的柵格圖像配置各種屬性信息;但是有時我們希望所創建的新的柵格圖像,其與作為模板的圖像之間的屬性有一定差異。例如,我們現在依據一個具有1
個波段的.tif
格式的模板圖像,創建一個新的.tif
格式的圖像;而我們需要使得新的圖像具有3
個波段,除此之外其他屬性信息與模板圖像一致。這就需要我們在調用CreateCopy()
函數之後,進行一些額外的操作。
首先,GDAL
庫提供了AddBand()
函數,可以為GDALDataset*
類型的數據添加波段;但是,AddBand()
函數對於大部分格式的柵格圖像而言都不起作用——例如,最常見的.tif
格式的柵格圖像文件,其就不支持利用AddBand()
函數增添自身的波段數量。大家在實踐過程中,如果用的是其他格式的柵格圖像文件,可以先直接用AddBand()
函數嘗試一下,看看其對於自己當前格式的數據是否有效;如果沒有效果的話,就需要用接下來的方法來實現需求了。
整體思路其實也很簡單——我們在依據.tif
格式的模板柵格圖像文件創建新的.tif
格式的柵格圖像文件前,先建立一個.vrt
格式的文件。.vrt
格式文件是GDAL
庫中提供的一種虛擬數據格式,這一數據格式的詳細介紹大家可以參考GDAL
庫的幫助文檔,這裡我們就不再詳細說明瞭;目前只需要知道,.vrt
格式文件是支持利用AddBand()
函數增添自身的波段數量的。隨後,我們為.vrt
格式文件增添波段,再用CreateCopy()
函數基於這一.vrt
格式文件創建新的.tif
格式的柵格圖像文件,從而實現我們的需求。
const char* pszFormat = "GTiff";
GDALDriver* poDriver, * poDriver_VRT;
poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
poDriver_VRT = GetGDALDriverManager()->GetDriverByName("VRT");
GDALDataset* poSrcDS = (GDALDataset*)GDALOpenShared(mod_file.c_str(), GA_ReadOnly);
GDALDataset* poVRTDS = poDriver_VRT->CreateCopy(mod_file.replace(mod_file.find(".tif"), 4, ".vrt").c_str(), poSrcDS, FALSE, NULL, NULL, NULL);
poVRTDS->AddBand(GDT_Float64, NULL);
poVRTDS->AddBand(GDT_Float64, NULL);
char** papszOptions = NULL;
papszOptions = CSLSetNameValue(papszOptions, "TILED", "YES");
papszOptions = CSLSetNameValue(papszOptions, "COMPRESS", "LZW");
上述代碼也很好理解。首先,我們創建兩個GDALDataset*
變數,分別指向.tif
格式的模板柵格圖像文件與我們將要創立的.vrt
格式文件;隨後,先用一次CreateCopy()
函數,將模板文件的全部屬性信息複製到.vrt
格式文件中。接下來,就利用AddBand()
函數,為.vrt
格式文件增添兩個波段。此時,加上原有的1
個波段,.vrt
格式文件就已經擁有了3
個波段;而除此之外,.vrt
格式文件的所有屬性信息都是與.tif
格式的模板柵格圖像文件一致的。
接下來,就可以開始配置我們所需要創立的新的.tif
格式柵格圖像文件。其中,再用一次CreateCopy()
函數,將.vrt
格式文件的全部屬性信息複製到新的.tif
格式的柵格圖像文件中。這樣,我們新的.tif
格式的柵格圖像文件也就具有3
個波段了。
GDALDataset* poDstDS;
poDstDS = poDriver->CreateCopy(out_file.c_str(), poVRTDS, FALSE, papszOptions, GDALTermProgress, NULL);
GDALRasterBand* poOutBand;
poOutBand = poDstDS->GetRasterBand(1);
poOutBand->RasterIO(GF_Write, 0, 0, nXSize, nYSize, combination_out_pafScanline[pic_index_2 - 1], nXSize, nYSize, GDT_Float64, 0, 0);
GDALRasterBand* poOutBand_2;
poOutBand_2 = poDstDS->GetRasterBand(2);
poOutBand_2->RasterIO(GF_Write, 0, 0, nXSize, nYSize, out_pafScanline[pic_index_2 - 1], nXSize, nYSize, GDT_Float64, 0, 0);
GDALRasterBand* poOutBand_3;
poOutBand_3 = poDstDS->GetRasterBand(3);
poOutBand_3->RasterIO(GF_Write, 0, 0, nXSize, nYSize, qa_pixel_paf[pic_index_2 - 1], nXSize, nYSize, GDT_Float64, 0, 0);
上述代碼就是基於.vrt
格式文件,創建新的.tif
格式的柵格圖像文件,並對新的圖像文件的3
個波段依次賦值的全部過程。
通過上述方式,我們就實現了CreateCopy()
函數創建新的柵格圖像且為新的柵格圖像增添波段數量的需求。