天天看點

C++中GDAL批量建立栅格圖像檔案并批量寫入資料

作者:瘋狂學習GIS

  本文介紹基于C++ 語言GDAL庫,批量建立大量栅格遙感影像檔案,并将資料批量寫入其中的方法。

C++中GDAL批量建立栅格圖像檔案并批量寫入資料

  首先,我們來明确一下本文所需實作的需求。已知我們對大量遙感影像進行了批量讀取與資料處理操作——具體過程可以參考文章C++借助GDAL批量讀取栅格影像并生成像元數值的時間序列;而随後,就需要對我們處理後的栅格資料再進行輸出,即建立新的大量的栅格遙感影像,并将我們處理後的像中繼資料依次輸入進去。

  明确了具體需求,接下來就可以開始代碼的實踐;本文所用到的具體代碼如下。這裡需要注意,在這裡就僅将與本文需求有關的代碼放了上來,其他無關的代碼就省略了(是以以下代碼隻是程式主函數中的一部分);大家在實踐過程中,依據自己的需求,将自己代碼與本文的代碼相結合就可以。

#include <iostream>
#include "gdal_priv.h"

//以下隻列出栅格資料批量建立、寫入與導出的代碼,其他無關的代碼就省略了~

    int pic_index_2 = 1;
    for (auto x : my_file)
    {
        const char* pszFormat = "GTiff";
        GDALDriver* poDriver;
        GDALAllRegister();
        poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
        if (poDriver == NULL)
            cout << "There is an error with poDriver!" << endl;
        GDALDataset* poSrcDS = (GDALDataset*)GDALOpen(mod_file.c_str(), GA_ReadOnly);
        GDALDataset* poDstDS;
        char** papszOptions = NULL;
        papszOptions = CSLSetNameValue(papszOptions, "TILED", "YES"); //建立金字塔
        papszOptions = CSLSetNameValue(papszOptions, "COMPRESS", "LZW");

        int pos_need = x.rfind("CSI");
        string file_name = x.substr(pos_need);
        string out_file = out_path + "//R_" + file_name;
        poDstDS = poDriver->CreateCopy(out_file.c_str(), poSrcDS, FALSE, papszOptions, GDALTermProgress, NULL);

        GDALRasterBand* poOutBand;
        poOutBand = poDstDS->GetRasterBand(1);
        poOutBand->RasterIO(GF_Write, 0, 0, nXSize, nYSize, out_pafScanline[pic_index_2 - 1], nXSize, nYSize, GDT_Float64, 0, 0);

        pic_index_2++;

        GDALClose((GDALDatasetH)poDstDS);
        GDALClose((GDALDatasetH)poSrcDS);
    }

    delete[] pafScanline;
    delete[] out_pafScanline;
    delete[] pixel_paf;
    delete[] pixel_paf_result;
    pafScanline = NULL;
    out_pafScanline = NULL;
    pixel_paf = NULL;
    pixel_paf_result = NULL;           

  以上代碼的思路其實也非常簡單。首先,因為是需要對大量的栅格進行批量操作,是以代碼整體是在for循環中進行的,每一個循環都是對一個獨立的栅格檔案的建立、資料寫入與檔案儲存操作;其中,"GTiff"表示我們将要生成的栅格檔案是.tif格式的,如果大家需要生成别的格式的話可以修改這裡;auto x : my_file表示從我們前期已經擷取到的需要處理的栅格檔案清單中周遊(雖然我們這裡是需要建立新的栅格檔案,但由于我這裡新的栅格檔案的命名規則是與原有的栅格檔案一緻的,是以就還是從原有的檔案清單中周遊),my_file就是前期已經擷取到的需要處理的栅格檔案清單,具體擷取方法可以參考文章C++周遊檔案夾篩選出指定格式的檔案或具有特定名稱的檔案。

C++中GDAL批量建立栅格圖像檔案并批量寫入資料

  接下來,就是基于GDAL庫來實作栅格資料的建立于寫入。在GDAL庫中,如果我們想用自己的資料生成栅格檔案,首先需要基于CreateCopy()函數建立一個栅格檔案,随後通過RasterIO()函數寫入資料。其中,poSrcDS是一個指向模闆栅格檔案的指針;在我們用CreateCopy()函數建立栅格檔案時,新的栅格檔案的各項屬性,比如行數、列數、像元大小、坐标資訊等,都直接與這個模闆栅格檔案保持一緻。随後,poDstDS則是指向我們此時将要建立的栅格檔案的指針。

  接下來,我們通過CSLSetNameValue()函數,配置一下将要生成的新的栅格檔案的屬性,比如"TILED", "YES"表示栅格檔案同時生成金字塔,"COMPRESS", "LZW"表示栅格檔案通過LZW算法進行壓縮等。

  再接下來,是配置我們新的栅格檔案的檔案名的代碼部分。因為我們是需要批量生成大量的栅格檔案的,是以其檔案名肯定不能手動逐一修改;我這裡就是直接在已有檔案的檔案名基礎上,增添了一個字母,作為新栅格檔案的檔案名;這裡就是通過字元串的截取等操作來實作新的檔案名的生成。其中,out_path是我們已經定義過的變量,表示結果儲存路徑。

  完成以上全部配置後,即可依據CreateCopy()函數進行新的栅格檔案的建立。

  至此,我們僅僅是完成了GDAL庫中栅格檔案的建立,但此時還沒有将資料導入進去,是以在資料總管中也是看不到具體的新的栅格檔案的。随後,我們基于RasterIO()函數,将資料寫入栅格檔案即可;其中,out_pafScanline[pic_index_2 - 1]就是需要寫入到每一景遙感影像中的資料。

  完成以上工作後,我們就完成了對其中一景遙感影像的建立、寫入,此時資料總管中就會看到這一景圖像的檔案已經存在。随後,通過GDALClose()函數将剛剛指向的栅格遙感檔案關閉,并進行下一次循環。對全部需要生成的栅格遙感影像檔案都完成周遊後,則通過delete[]、 = NULL等語句釋放記憶體、取消指針。

  此時,即可在目标檔案夾中看到我們批量生成的栅格檔案。

C++中GDAL批量建立栅格圖像檔案并批量寫入資料

  基于此,即可完成批量建立、寫入栅格資料的操作。

C++中GDAL批量建立栅格圖像檔案并批量寫入資料

繼續閱讀