首页 > 编程语言 >C++ GDAL用CreateCopy()新建栅格并修改波段的个数

C++ GDAL用CreateCopy()新建栅格并修改波段的个数

时间:2024-02-26 10:35:38浏览次数:29  
标签:vrt CreateCopy C++ 格式文件 栅格 图像文件 tif

  本文介绍基于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()函数创建新的栅格图像且为新的栅格图像增添波段数量的需求。

标签:vrt,CreateCopy,C++,格式文件,栅格,图像文件,tif
From: https://www.cnblogs.com/fkxxgis/p/18033767

相关文章

  • C++ auto与循环
    C++auto与循环C++auto的介绍typeid(p).name();可以输出auto的类型auto是C++11引入的一个关键字,用于自动类型推导。编译器会根据初始化表达式的类型来自动推导auto变量的类型。使用auto可以简化代码,减少重复书写类型名称的繁琐,并且当类型非常复杂或者难以书写时,auto......
  • C++U6-05 - 动态规划算法入门
    目标:动态规划     兔子数列的每一项都是前两项之和,公式为f[n]=f[n−1]+f[n−2]。#include<bits/stdc++.h>usingnamespacestd;intmain(){intf[105],n;f[1]=1;f[2]=1;cin>>n;for(inti=3;i<=n;i++){......
  • C++U5-第05课-广度优先搜索2
    学习目标 广度优先搜索的思路复习 [【广度优先搜索(二)】图像渲染]  【题意分析】从需要上色的点开始,将所有与他相连接的点全部涂上相同的颜色【思路分析】我们从给定的起点开始,进行广度优先搜索。每次搜索到一个方格时,如果其与初始位置的方格颜色相同,就将该......
  • C++文件读取末尾空行问题
    起因是做gitlet读取文件内容时遇到的内容不匹配错误,后来发现是自己读取文件内容时均使用getline函数,写回时读入的每个字符串都加上换行符,导致文件末尾可能多出换行符。于是改成了vector<string>Blob::readContentsForBlob(conststring&file){vector<string>content;......
  • 3. 无重复字符的最长子串C++
    思路就是从头开始找,然后每次在从重复节点的后一个找。classSolution{public:intlengthOfLongestSubstring(strings){inti=0,j=0,nowmax=1;intmax=1;if(s.size()==0||s.size()==1)returns.size();map<char,int>m;......
  • C++ STL学习
    C++STL学习目录C++STL学习容器库概览对可以保存在容器中的元素的限制容器支持的操作所有容器都支持的操作或容器成员迭代器迭代器的公共操作迭代器的类型迭代器的const属性迭代器的操作类型迭代器范围使用左闭合区间的编程假定顺序容器顺序容器概述顺序容器的类型和特点确定使......
  • C++ 拷贝构造函数简单测试
    浅拷贝静态数组的空间体现深拷贝的效果#include<iostream>#include<string>usingnamespacestd;#defineSEX_SIZE10classStudent{public:Student(stringname){Age=10;Name=newstring(name);strcpy(Sex,"男");......
  • 【C++】【OpenCV】Visual Studio 2022 配置OpenCV
    记录一下VisualStudio配置OpenCV过程以及出现的问题本机环境:1、Windows102、VisualStudio2022 配置步骤:1、下载OpenCV(Releases·opencv/opencv·GitHub)在GitHub上下载最新的版本 2、双击打开,然后选择路径后,点击Extract 3、等待提取完成后在VisualStudio中新......
  • C++ 令人无语/好用的语法合集
    此贴用来总结一些傻逼C++语法,或者坑了我很久的写法。1、(坑)重载>,<,==时,千万不要使用pair为基的typedef!!!!!!pii的max不受你的重载影响,它自己有自己的max,然后typedef和define是相同的,基本可以看做直接替换,不会对作用域/命名做区分。2、(坑)lower_bound(..,..,{x......
  • 如何学习PYTHON(python和c++哪个难学)
    1.如何学习PYTHONPython是一门简单易学的编程语言,但想要真正掌握它需要花费不少时间和精力。我的建议是先从Python基础开始学习,掌握基本语法和常见数据结构,再逐步深入学习高级特性和应用场景。 在学习Python的过程中,https://www.fuligou8.com/noking/4006.html我们可以通过阅......