如何做网站优化,wordpress 百度云图安装,猪八戒网可以做网站吗,邓州企业网站本文介绍基于C语言GDAL库#xff0c;批量读取大量栅格遥感影像文件#xff0c;并生成各像元数值的时间序列数组的方法。 首先#xff0c;我们来明确一下本文所需实现的需求。现在有一个文件夹#xff0c;其中包含了很多不同格式的文件#xff0c;如下图所示。 其中#x…本文介绍基于C语言GDAL库批量读取大量栅格遥感影像文件并生成各像元数值的时间序列数组的方法。 首先我们来明确一下本文所需实现的需求。现在有一个文件夹其中包含了很多不同格式的文件如下图所示。 其中我们首先需要遍历这一文件夹遴选出其中所有类型为.bmp格式的栅格遥感影像文件一共有6个并分别读取文件已知这些遥感影像的行数、列数都是一致的随后将不同遥感影像的同一个位置的像素的数值进行分别读取并存储在一个数组中。例如最终我们生成的第一个数组其中共有6个元素分别就是上图所示文件夹中6景遥感影像各自(0,0)位置的像元数值生成的第二个数组其中也是6个元素分别就是6景遥感影像各自(1,0)位置的像元数值以此类推。其中显然我们得到的数组个数就是遥感影像像元的个数。此外这里6景遥感影像的排序是按照文件名称的升序来进行的。 明确了具体需求接下来就可以开始代码的实践。其中本文分为两部分第一部分为代码的分段讲解第二部分为完整代码。 此外本文是基于GDAL库来实现栅格数据读取的具体GDAL库的配置方法大家可以参考文章在Visual Studio中部署GDAL库的C版本包括SQLite、PROJ等依赖。
1 代码分段介绍
1.1 代码准备
这一部分主要是代码的头文件、命名空间与我们自行撰写的自定义函数get_need_file()的声明具体代码如下所示。
#include iostream
#include vector
#include io.h
#include gdal_priv.husing namespace std;void get_need_file(string path, vectorstring file, string ext);其中由于我们在接下来的代码中需要用到容器vector这一数据类型因此首先需要添加#include vector同时我们在接下来的代码中需要用到头文件io.h中的部分函数主要都是一些与计算机系统、文件管理相关的函数因此需要添加#include io.h此外我们是基于GDAL库来实现栅格数据读取的因此需要添加#include gdal_priv.h。 接下来这里声明了一个自定义函数get_need_file()具体我们在本文1.2部分介绍。
1.2 栅格文件筛选 由于我这里几乎将全部的代码都放在了主函数中因此这一部分就先介绍代码main()函数的第一部分亦即栅格文件的遴选部分具体代码如下所示。
int main() {string file_path R(E:\02_Project\02_ChlorophyllProduce\01_Data\00_Test);vectorstring my_file;string need_extension .bmp;get_need_file(file_path, my_file, need_extension);int file_size my_file.size();if (file_size 0){cout No file can be found! endl;}else{cout Find file_size file(s).\n endl;}这一部分主要就是做好调用自定义函数get_need_file()的变量准备并调用get_need_file()函数得到指定文件夹下的栅格文件随后将栅格文件的筛选结果进行输出。这一部分的具体代码介绍大家查看文章C遴选出特定类型的文件或文件名符合要求的文件即可这里就不再赘述。
1.3 栅格文件读取 这一部分主要是基于GDAL库循环读取前述文件夹中的每一个栅格遥感影像文件。 int nXSize, nYSize;float** pafScanline new float* [file_size];int pic_index 1;for (auto x : my_file){GDALDataset* poDataset;GDALAllRegister();CPLSetConfigOption(GDAL_FILENAME_IS_UTF8, NO);poDataset (GDALDataset*)GDALOpen(x.c_str(), GA_ReadOnly);if (poDataset NULL){cout Open File x Error! endl;}else{cout Open File x Success! endl;}GDALRasterBand* poBand;poBand poDataset-GetRasterBand(1);nXSize poBand-GetXSize();nYSize poBand-GetYSize();cout nXSize , nYSize \n endl;pafScanline[pic_index - 1] new float[nXSize * nYSize];poBand-RasterIO(GF_Read, 0, 0, nXSize, nYSize, pafScanline[pic_index - 1], nXSize, nYSize, GDT_Float32, 0, 0);pic_index ;}其中nXSize与nYSize分别表示栅格遥感影像的列数与行数pafScanline是我们读取栅格遥感影像文件所需的变量之后读取好的遥感影像数据就会存放在这里由于我们有多个栅格文件需要读取因此通过for循环来实现批量读取的操作并通过pic_index这个变量作为每一次读取文件的计数。 在这里float** pafScanline new float* [file_size];这句代码表示我们将pafScanline作为一个指向指针的指针的数组在后期读取遥感影像数据后pafScanline[0]、pafScanline[1]一直到pafScanline[5]这6个数值同样分别是指针分别指向存储6景遥感影像数据的地址。这里我们通过new实现对pafScanline内存的动态分配因为我们在获取栅格遥感影像的景数也就是文件夹中栅格遥感影像文件的个数之前也不知道具体需要给pafScanline这一变量分配多少的内存。此外在for循环中我们还对pafScanline[0]、pafScanline[1]一直到pafScanline[5]同样进行了动态内存分配因为我们在获取每一景栅格遥感影像的行数与列数之前同样是不知道需要给pafScanline[x]这6个数组变量分配多少内存的。 随后for循环中的其他部分就是GDAL库读取遥感影像的基本代码。读取第一景遥感影像数据后我们将数据保存至pafScanline[0]并随后进行第二次循环读取第二景遥感影像数据并将其数据保存至pafScanline[1]中随后再次循环以此类推直至读取6景遥感影像完毕。 如果大家只是需要实现C批量读取栅格遥感影像数据那么以上操作就已经实现了大家的需求。其中显然pafScanline[0]就是第一景遥感影像数据pafScanline[1]就是第二景遥感影像数据pafScanline[2]就是第三景遥感影像数据以此类推。
1.4 像元时间序列数组生成
这一部分则是基于以上获取的各景遥感影像数据读取结果进行每一个像元数值的时间序列数组生成。 float** pixel_paf new float* [nXSize * nYSize];for (int pixel_num 0; pixel_num nXSize * nYSize; pixel_num){pixel_paf[pixel_num] new float[file_size];for (int time_num 0; time_num file_size; time_num){pixel_paf[pixel_num][time_num] pafScanline[time_num][pixel_num];}}这一部分的代码思路其实也非常简单就是通过两个for循环将原本一共6个的、每一个表示每一景遥感影像中全部数据的数组转变为一共X个的X表示每一景遥感影像的像元总个数、每一个表示每一个位置的像元在6景遥感影像中的各自数值的数组。 在这里由于同样的原因我们对pixel_paf亦进行了内存的动态分配。
1.5 输出测试与代码收尾 这一部分主要是输出一个我们刚刚配置好的像元数值时间序列数组从而检查代码运行结果是否符合我们的要求此外由于前面我们对很多变量进行了动态内存分配因此需要将其delete掉同时这里还可以对前面我们定义的指向指针的指针赋值为NULL这样子其就不能再指向任何地址了即彻底将其废除。 for (int i 0; i file_size; i){cout pixel_paf[0][i] , endl;}delete[] pafScanline;delete[] pixel_paf;pafScanline NULL;pixel_paf NULL;return 0;
}至此代码的主函数部分结束。
1.6 自定义函数
这一部分是我们的自定义函数get_need_file()。
void get_need_file(string path, vectorstring file, string ext)
{intptr_t file_handle 0;struct _finddata_t file_info;string temp;if ((file_handle _findfirst(temp.assign(path).append(/* ext).c_str(), file_info)) ! -1){do{file.push_back(temp.assign(path).append(/).append(file_info.name));} while (_findnext(file_handle, file_info) 0);_findclose(file_handle);}
}如前所述这一部分的具体代码介绍大家查看文章C遴选出特定类型的文件或文件名符合要求的文件即可这里就不再赘述。
2 完整代码
本文所需用到的完整代码如下所示。
#include iostream
#include vector
#include io.h
#include gdal_priv.husing namespace std;void get_need_file(string path, vectorstring file, string ext);int main() {string file_path R(E:\02_Project\02_ChlorophyllProduce\01_Data\00_Test);vectorstring my_file;string need_extension .bmp;get_need_file(file_path, my_file, need_extension);int file_size my_file.size();if (file_size 0){cout No file can be found! endl;}else{cout Find file_size file(s).\n endl;}int nXSize, nYSize;float** pafScanline new float* [file_size];int pic_index 1;for (auto x : my_file){GDALDataset* poDataset;GDALAllRegister();CPLSetConfigOption(GDAL_FILENAME_IS_UTF8, NO);poDataset (GDALDataset*)GDALOpen(x.c_str(), GA_ReadOnly);if (poDataset NULL){cout Open File x Error! endl;}else{cout Open File x Success! endl;}GDALRasterBand* poBand;poBand poDataset-GetRasterBand(1);nXSize poBand-GetXSize();nYSize poBand-GetYSize();cout nXSize , nYSize \n endl;pafScanline[pic_index - 1] new float[nXSize * nYSize];poBand-RasterIO(GF_Read, 0, 0, nXSize, nYSize, pafScanline[pic_index - 1], nXSize, nYSize, GDT_Float32, 0, 0);pic_index ;}float** pixel_paf new float* [nXSize * nYSize];for (int pixel_num 0; pixel_num nXSize * nYSize; pixel_num){pixel_paf[pixel_num] new float[file_size];for (int time_num 0; time_num file_size; time_num){pixel_paf[pixel_num][time_num] pafScanline[time_num][pixel_num];}}for (int i 0; i file_size; i){cout pixel_paf[0][i] , endl;}delete[] pafScanline;delete[] pixel_paf;pafScanline NULL;pixel_paf NULL;return 0;
}void get_need_file(string path, vectorstring file, string ext)
{intptr_t file_handle 0;struct _finddata_t file_info;string temp;if ((file_handle _findfirst(temp.assign(path).append(/* ext).c_str(), file_info)) ! -1){do{file.push_back(temp.assign(path).append(/).append(file_info.name));} while (_findnext(file_handle, file_info) 0);_findclose(file_handle);}
}当我们运行上述代码后将会出现如下所示的界面。 其中会显示栅格遥感影像文件的筛选情况、具体文件名称及其各自的行号与列号同时最后一部分则是本文1.5部分提及的测试输出结果其表示本文所用的6景遥感影像各自(0,0)位置处的像元数值。 至此大功告成。
参考链接 https://www.cnblogs.com/fkxxgis/p/18004549