注册 登录
  • 注册时,本站名称为:RGB空格3S博客,注意中间的空格。
  • 2018.10.14本人利用业余时间接遥感数据处理与编程小活,欢迎骚扰,QQ:853060844
  • 2018.8.14本站全面接入google广告
  • 本人闲暇时间(周末及其他闲暇时间)接遥感图像处理与IDL编程小活,欢迎骚扰,qq:853060844
  • 2017.2.14今天收到45条恶意评论(全是外文),故评论时请填写必要信息,匿名评论全部拉黑,迫不得已而为之
  • 2017.1.27,2017年春节及至,我谨代表本人祝大家新春快乐,本人年终总结文章请访问:2016年终总结
  • 为防止恶意转载,本站全面禁止复制,并添加图片水印:RGB 3S博客www.ixxin.cn。
  • 本站正式更名为RGB 3S博客,本站将撤消所有非3S内容,其将转移到新博客江湖时代

C++ NetCDF接口读取H8数据

C/C++ admin 802次浏览 已收录 0个评论

NetCDF(NC)格式是气象领域比较常见的科学数据格式,该格式的部分数据可以直接使用HDF5库读取,前几天发现NC库的C++接口,用起来很简便,就写了一个读取Himawari-8 NC格式数据的示例,话不多数,直接放代码了:

//作者:宿鑫
//网址:www.ixxin.cn
//时间:2019.4
#include <iostream>
#include "ReadData.h"
using namespace std;
using namespace netCDF;
using namespace netCDF::exceptions;
bool inDsNames(string sInDsName, string inDs[], int nDsName);
int Readh8<a href="https://www.ixxin.cn/tag/nc/" title="查看更多关于NC的文章" target="_blank">NC</a>(const char* pSrcFile,const char* pDstFile)
{
	try
	{
		cout << "Start" << endl;
		NcFile dataFile(pSrcFile, NcFile::read);
		string inDsNm[20] = {"SAA","SAZ","SOA","SOZ", //4
			"albedo_01","albedo_02","albedo_03","albedo_04","albedo_05","albedo_06", //6
			"tbb_07","tbb_08","tbb_09","tbb_10","tbb_11","tbb_12","tbb_13","tbb_14","tbb_15","tbb_16"}; //10
		//获取行列号
		NcVar Varf = dataFile.getVar("SAA");
		NcDim Dimf = Varf.getDim(1);
		int XSizef = Dimf.getSize();
		Dimf = Varf.getDim(0);
		int YSizef = Dimf.getSize();
		int nBand = 20;
		short * pSrcData = new short[XSizef*YSizef]();
		float * pDstData = new float[XSizef*YSizef]();
		GDALAllRegister();
		CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
		GDALDriver* pDstDrive = (GDALDriver*)GDALGetDriverByName("GTiff");
		char** papszOptions = nullptr;
		//papszOptions = CSLSetNameValue(papszOptions, "COMPRESS", "LZW");
		//papszOptions = CSLSetNameValue(papszOptions, "TILED", "YES");
		GDALDataset* pDstDs = pDstDrive->Create(pDstFile, XSizef, YSizef, nBand, GDT_Int16, papszOptions);
		multimap<std::string, NcVar> TestD; 
		TestD = dataFile.getVars();
		int VarSize = TestD.size();
		multimap<string, NcVar>::iterator i, iend; //迭代器
		iend = TestD.end();
		int b = 1;
		for (i = TestD.begin(); i != iend; i++)
		{
			cout << (*i).first << endl;
			if (inDsNames((*i).first, inDsNm, nBand))
			//if ((*i).first == "SAA")
			{
				cout << "Processing:'" << (*i).first << endl;
				NcVar VarT = (*i).second;
				NcVarAtt AttT = VarT.getAtt("scale_factor");
				NcType TypeT =  AttT.getType();
				int TypeId = TypeT.getId();  //float,长度是1
				float fScale = 0.0f;
				AttT.getValues(&fScale);
				AttT = VarT.getAtt("add_offset");
				float fOffset = 0.0f;
				AttT.getValues(&fOffset);
				NcDim DimT = VarT.getDim(1);
				int XSize = DimT.getSize();
				DimT = VarT.getDim(0);
				int YSize = DimT.getSize();
				//cout << 1 << endl;
				//cout << fScale << endl;
				if (XSize == XSizef && YSize == YSizef)
				{
					VarT.getVar(pSrcData);
					GDALRasterBand* pBand = pDstDs->GetRasterBand(b);
					b++;
					for (int t = 0; t < XSize*YSize; t++)
					{
						pDstData[t] = pSrcData[t] * fScale + fOffset;
					}
					CPLErr Err = pBand->RasterIO(GF_Write, 0, 0, XSizef, YSizef, pSrcData, XSizef, YSizef, GDT_Int16, 0, 0, 0);
					if(Err != 0)
					{
						cout << "写入错误" << (*i).first << endl;
						return Err_W;
					}
					cout << "Process End" << endl;
				}
			}
		}
		//构建投影
		OGRSpatialReference oSRS;
		char *pszSRS_WKT = NULL;
		oSRS.SetWellKnownGeogCS("WGS84");
		oSRS.exportToWkt(&pszSRS_WKT);
		pDstDs->SetProjection(pszSRS_WKT);
		CPLFree(pszSRS_WKT);
		double dDsGeoTran[6] = {80,0.02,0,60,0,-0.02};
		pDstDs->SetGeoTransform(dDsGeoTran);
		delete[] pSrcData;
		delete[] pDstData;
		dataFile.close();
		GDALClose(GDALDatasetH(pDstDs));
		cout << "End" << endl;
		return 0;
	}
	catch (NcException& e)
	{
		e.what();
		return e.errorCode();
	}
	return Err_OK;
}

bool inDsNames(string sInDsName,string inDs[],int nDsName)
{
	bool in = FALSE;
	for (int i = 0; i < nDsName; i++)
	{
		if (sInDsName == inDs[i])
		{
			in = TRUE;
			break;
		}
	}
	return in;
}

令我比较困惑的是,https://www.unidata.ucar.edu/software/netcdf/netcdf-4/newdocs/netcdf-cxx.html 这里给出的API中,在实际使用中竟然没有,所以这应该是网上比较全的一个NetCDF C++接口的读取数据的例子。
另外,配置NetCDF C++库,可以参考以下博客:
https://blog.csdn.net/chenhemin604/article/details/25197693
https://www.cnblogs.com/wang985850293/p/6576533.html
https://blog.csdn.net/toby54king/article/details/78711563


xxin blog , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C++ NetCDF接口读取H8数据
喜欢 (0)
支付宝[853060844@qq.com]
分享 (0)
admin
关于作者:
坐标山科大遥感系小鲜肉一枚。
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址