0

创建大量栅格文件并分别写入像元数据:C++ GDAL代码实现 - 疯狂学习GIS

 7 months ago
source link: https://www.cnblogs.com/fkxxgis/p/18006054
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

创建大量栅格文件并分别写入像元数据: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++遴选出特定类型的文件或文件名符合要求的文件

  接下来,就是基于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等语句释放内存、取消指针。

  此时,即可在目标文件夹中看到我们批量生成的栅格文件。

3080295-20240204134541785-147814230.png

  基于此,即可完成批量创建、写入栅格数据的操作。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK