用Qt+NetCDF 读取NC文件

用Qt+NetCDF 读取NC文件_ivqtnc-CSDN博客

基于NetCDF-CXX4 封装,对NC文件进行读取,读取内存放到vector中。

ncBase.h

#ifndef  __NC_BASE_H__
#define __NC_BASE_H__
 
#include <QVariant>
#include <vector>
#include <map>
using namespace std;
 
typedef std::vector<float> _dataVector_f;   //存放一维数据
typedef std::vector<double> _dataVector_d;   //存放一维数据
typedef std::vector<QString> _dataVector_s;   //存放一维数据
typedef std::vector<_dataVector_d> _3DDataVector_v;   //存放三维数据
typedef QPair<float, float> _Pos;
 
 
Q_DECLARE_METATYPE(_dataVector_d)
Q_DECLARE_METATYPE(_3DDataVector_v)
 
#endif

ncReader.h

#pragma once
#ifndef _NC_READER_H_
#define _NC_READER_H_
 
#include "qfileinfo.h"
#include "ncBase.h"
#include <QMap>
#include <QString>
#include <Qvector>
#include <QFileInfo>
#include <QDir>
#include <QTimer>
#include <netcdfcpp.h>
#include "../../Z_PlantInterface/plantinterface.h"
 
 
using namespace  std;
using  namespace netCDF;
 
class ncReader :QObject
{
	Q_OBJECT
private:
	QString curFilePath;
	CPlantInterface* m_pInterface;
	NcFile *m_pDataFile{};
public:
	ncReader(QString filePath);
	~ncReader();
 
	void SetPlantInterface(CPlantInterface* pInterface) { m_pInterface = pInterface; };
	bool ReadData_D(_dataVector_d& vet_data, QString strEle, long l0 = -1, long l1 = -1, long l2 = -1, long l3 = -1, long l4 = -1);
	bool ReadData_F(_dataVector_f& vet_data, QString strEle, long l0 = -1, long l1 = -1, long l2 = -1, long l3 = -1, long l4 = -1);
	long *GetEleEdge(QString strElement);
	NcVar* GetVar(QString strEle);
	QString getfilePath();
	int  GetVarNums();
	void GetVars(_dataVector_s &vet_Vars);
};
 
#endif

ncReader.cpp

#include"ncReader.h"
#include<qdebug.h>
#include <QPixmap>
#include <QFile>
#include <QDataStream>
#include <QApplication>
#include <QSettings>
#include <iostream>
#include <QDateTime>
#include <string.h>
 
 
ncReader::ncReader(QString filePath) :curFilePath(filePath)
{
	//中文字符串转换
	std::string pathstr = filePath.toLocal8Bit();
	const char* temp = pathstr.c_str();
	m_pDataFile = new NcFile(temp, NcFile::read);//只读文件中的数据
}
 
 
ncReader::~ncReader()
{
 
}
 
 
bool ncReader::ReadData_D(_dataVector_d& vet_data, QString strEle, long l0 /*=-1*/, long l1/*=-1*/, long l2/*=-1*/, long l3 /*= -1*/, long l4 /*= -1*/)
{
	if (m_pDataFile->isNull() || !m_pDataFile)
		return false;
	if (l0 < -1 || l1 < -1 || l2 < -1 || l3 < -1 || l4 < -1)
		return false;
 
	long lg0 = 1, lg1 = 1, lg2 = 1, lg3 = 1, lg4 = 1, lg5 = 1;
 
	long *p = GetEleEdge(strEle);
	
	NcVar pVar = m_pDataFile->getVar(strEle.toStdString().c_str());
	if (pVar.isNull())
		return false;
 
	int nDims = pVar.getDimCount();
 
	std::vector<size_t> vet_Inx;//存放每个维度上索引(开始位置)
	std::vector<size_t> vet_Count;//存放索引(数量) value >=1
	vet_Inx.clear();
	switch (nDims)
	{
	case 1://1维
	{
		float* data = new float[p[0]];
 
		pVar.getVar(data);
 
		_dataVector_d vet_tmp(data, data + p[0]);
		vet_data.swap(vet_tmp);
		delete[]data;
	}
	break;
	case 2://2维
	{
		long long nLen = 1;
 
		if (l0 == -1)
		{
			nLen *= p[0];
			lg0 = p[0];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg0);
		}
		else
		{
			vet_Inx.push_back(l0);
			vet_Count.push_back(1);
		}
		if (l1 == -1)
		{
			nLen *= p[1];
			lg1 = p[1];
			vet_Count.push_back(lg1);
			vet_Inx.push_back(0);
			vet_Count.push_back(lg1);
		}
		else
		{
			vet_Inx.push_back(l1);
			vet_Count.push_back(1);
		}
	
		float* data = new float[nLen];
		pVar.getVar(vet_Inx, vet_Count, data);
		_dataVector_d vet_tmp(data, data + nLen);//转存,效率提升170倍
		vet_data.swap(vet_tmp);
		delete[]data;
		
	}
	break;
	case 3://3维
	{
		long nLen = 1;
		if (l0 == -1)
		{
			nLen *= p[0];
			lg0 = p[0]; 
			vet_Inx.push_back(0);
			vet_Count.push_back(lg0);
		}
		else
		{
			vet_Inx.push_back(l0);
			vet_Count.push_back(1);
		}
		if (l1 == -1)
		{
			nLen *= p[1];
			lg1 = p[1]; 
			vet_Inx.push_back(0);
			vet_Count.push_back(lg1);
		}
		else
		{
			vet_Inx.push_back(l1);
			vet_Count.push_back(1);
		}
		if (l2 == -1)
		{
			nLen *= p[2];
			lg2 = p[2]; 
			vet_Inx.push_back(0);
			vet_Count.push_back(lg2);
		}
		else
		{
			vet_Inx.push_back(l2);
			vet_Count.push_back(1);
		}
 
		
		
		float fscale = 1.0f;
		float foffset = 0.0f;
 
		float* data = new float[nLen];
		pVar.getVar(vet_Inx, vet_Count, data);
		_dataVector_d vet_tmp(data, data + nLen);//转存,效率提升170倍
		if (fscale != 1.0f || foffset != 0.0f)
		{
			int n = 0;
			for (auto it : vet_tmp)
			{
				vet_tmp[n] = it * fscale + foffset;
				n++;
			}
		}
		vet_data.swap(vet_tmp);
		delete[]data;
 
	}
	break;
	case 4://4维
	{
		long nLen = 1;
		if (l0 == -1)
		{
			nLen *= p[0];
			lg0 = p[0];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg0);
		}
		else
		{
			vet_Inx.push_back(l0);
			vet_Count.push_back(1);
		}
		if (l1 == -1)
		{
			nLen *= p[1];
			lg1 = p[1];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg1);
		}
		else
		{
			vet_Inx.push_back(l1);
			vet_Count.push_back(1);
		}
		if (l2 == -1)
		{
			nLen *= p[2];
			lg2 = p[2];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg2);
		}
		else
		{
			vet_Inx.push_back(l2);
			vet_Count.push_back(1);
		}
		if (l3 == -1)
		{
			nLen *= p[3];
			lg3 = p[3];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg3);
		}
		else
		{
			vet_Inx.push_back(l3);
			vet_Count.push_back(1);
		}
 
		float* data = new float[nLen];
		pVar.getVar(vet_Inx, vet_Count, data);
		_dataVector_d vet_tmp(data, data + nLen);//转存,效率提升170倍
		vet_data.swap(vet_tmp);
		delete[]data;
		
	}
	break;
	case 5://5维
	{
		long nLen = 1;
		if (l0 == -1)
		{
			nLen *= p[0];
			lg0 = p[0];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg0);
		}
		else
		{
			vet_Inx.push_back(l0);
			vet_Count.push_back(1);
		}
		if (l1 == -1)
		{
			nLen *= p[1];
			lg1 = p[1];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg1);
		}
		else
		{
			vet_Inx.push_back(l1);
			vet_Count.push_back(1);
		}
		if (l2 == -1)
		{
			nLen *= p[2];
			lg2 = p[2];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg2);
		}
		else
		{
			vet_Inx.push_back(l2);
			vet_Count.push_back(1);
		}
		if (l3 == -1)
		{
			nLen *= p[3];
			lg3 = p[3];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg3);
		}
		else
		{
			vet_Inx.push_back(l3);
			vet_Count.push_back(1);
		}
		if (l4 == -1)
		{
			nLen *= p[4];
			lg4 = p[4];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg4);
		}
		else
		{
			vet_Inx.push_back(l4);
			vet_Count.push_back(1);
		}
 
		float* data = new float[nLen];
		pVar.getVar(vet_Inx, vet_Count, data);
		_dataVector_d vet_tmp(data, data + nLen);//转存,效率提升170倍
		vet_data.swap(vet_tmp);
		delete[]data;
		
	}
	break;
	default:
		break;
	}
}
 
bool ncReader::ReadData_F(_dataVector_f& vet_data, QString strEle, long l0 /*=-1*/, long l1/*=-1*/, long l2/*=-1*/, long l3 /*= -1*/, long l4 /*= -1*/)
{
	if (m_pDataFile->isNull() || !m_pDataFile)
		return false;
	if (l0 < -1 || l1 < -1 || l2 < -1 || l3 < -1 || l4 < -1)
		return false;
 
	long lg0 = 1, lg1 = 1, lg2 = 1, lg3 = 1, lg4 = 1, lg5 = 1;
	long *p = GetEleEdge(strEle);
 
	NcVar pVar = m_pDataFile->getVar(strEle.toStdString().c_str());
	if (pVar.isNull())
		return false;
 
	int nDims = pVar.getDimCount();
 
	std::map<std::string, NcVarAtt> map_atts = pVar.getAtts();//获取所有的属性,因为获取不存在的属性会崩溃
 
	std::vector<size_t> vet_Inx;//存放每个维度上索引(开始位置)
	std::vector<size_t> vet_Count;//存放索引(数量) value >=1
	vet_Inx.clear();
	switch (nDims)
	{
	case 1://1维
	{
		float* data = new float[p[0]];
		pVar.getVar(data);
 
		_dataVector_f vet_tmp(data, data + p[0]);
		vet_data.swap(vet_tmp);
		delete []data;
	}
	break;
	case 2://2维
	{
 
		long long nLen = 1;
 
		if (l0 == -1)
		{
			nLen *= p[0];
			lg0 = p[0];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg0);
		}
		else
		{
			vet_Inx.push_back(l0);
			vet_Count.push_back(1);
		}
		if (l1 == -1)
		{
			nLen *= p[1];
			lg1 = p[1];
			vet_Count.push_back(lg1);
			vet_Inx.push_back(0);
			vet_Count.push_back(lg1);
		}
		else
		{
			vet_Inx.push_back(l1);
			vet_Count.push_back(1);
		}
 
		float* data = new float[nLen];
		pVar.getVar(vet_Inx, vet_Count, data);
		_dataVector_f vet_tmp(data, data + nLen);//转存,效率提升170倍
		vet_data.swap(vet_tmp);
		delete[]data;
 
	}
	break;
	case 3://3维
	{
		long nLen = 1;
		if (l0 == -1)
		{
			nLen *= p[0];
			lg0 = p[0];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg0);
		}
		else
		{
			vet_Inx.push_back(l0);
			vet_Count.push_back(1);
		}
		if (l1 == -1)
		{
			nLen *= p[1];
			lg1 = p[1];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg1);
		}
		else
		{
			vet_Inx.push_back(l1);
			vet_Count.push_back(1);
		}
		if (l2 == -1)
		{
			nLen *= p[2];
			lg2 = p[2];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg2);
		}
		else
		{
			vet_Inx.push_back(l2);
			vet_Count.push_back(1);
		}
 
 
		//查看压缩值
		float fscale = 1.0f;
		float foffset = 0.0f;
		
		if (map_atts.find("scale_factor") != map_atts.end())
		{
			NcVarAtt AttT = pVar.getAtt("scale_factor");
			if (!AttT.isNull())
			{
				NcType TypeId = AttT.getType();
 
				if (TypeId == NC_FLOAT || TypeId == NC_DOUBLE)
					AttT.getValues(&fscale);
			}
		}
		
		if (map_atts.find("add_offset") != map_atts.end())
		{
			NcVarAtt AttS = pVar.getAtt("add_offset");
			if (!AttS.isNull())
			{
				NcType TypeId = AttS.getType();
 
				if (TypeId == NC_FLOAT || TypeId == NC_DOUBLE)
					AttS.getValues(&foffset);
			}
		}
 
		float* data = new float[nLen];
		pVar.getVar(vet_Inx, vet_Count, data);
		_dataVector_f vet_tmp(data, data + nLen);//转存
		if (fscale != 1.0f || foffset != 0.0f)
		{
			int n = 0;
			for (auto it : vet_tmp)
			{
				vet_tmp[n] = it * fscale + foffset;
				n++;
			}
		}
		vet_data.swap(vet_tmp);
		delete[]data;
		
	}
	break;
	case 4://4维
	{
		long nLen = 1;
		if (l0 == -1)
		{
			nLen *= p[0];
			lg0 = p[0];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg0);
		}
		else
		{
			vet_Inx.push_back(l0);
			vet_Count.push_back(1);
		}
		if (l1 == -1)
		{
			nLen *= p[1];
			lg1 = p[1];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg1);
		}
		else
		{
			vet_Inx.push_back(l1);
			vet_Count.push_back(1);
		}
		if (l2 == -1)
		{
			nLen *= p[2];
			lg2 = p[2];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg2);
		}
		else
		{
			vet_Inx.push_back(l2);
			vet_Count.push_back(1);
		}
		if (l3 == -1)
		{
			nLen *= p[3];
			lg3 = p[3];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg3);
		}
		else
		{
			vet_Inx.push_back(l3);
			vet_Count.push_back(1);
		}
 
		//查看压缩值
		float fscale = 1.0f;
		float foffset = 0.0f;
 
		if (map_atts.find("scale_factor") != map_atts.end())
		{
			NcVarAtt AttT = pVar.getAtt("scale_factor");
			if (!AttT.isNull())
			{
				NcType TypeId = AttT.getType();
 
				if (TypeId == NC_FLOAT || TypeId == NC_DOUBLE)
					AttT.getValues(&fscale);
			}
		}
 
		if (map_atts.find("add_offset") != map_atts.end())
		{
			NcVarAtt AttS = pVar.getAtt("add_offset");
			if (!AttS.isNull())
			{
				NcType TypeId = AttS.getType();
 
				if (TypeId == NC_FLOAT || TypeId == NC_DOUBLE)
					AttS.getValues(&foffset);
			}
		}
		//默认填充值
		float fFillVaue = 0.0f;
		if (map_atts.find("_FillValue") != map_atts.end())
		{
			NcVarAtt AttF = pVar.getAtt("_FillValue");
			if (!AttF.isNull())
			{
				NcType TypeId = AttF.getType();
 
				if (TypeId == NC_FLOAT || TypeId == NC_DOUBLE || TypeId == NC_SHORT)
					AttF.getValues(&fFillVaue);
			}
		}
		float* data = new float[nLen];
		pVar.getVar(vet_Inx, vet_Count, data);
		_dataVector_f vet_tmp(data, data + nLen);//转存
 
		int n = 0;
		for (auto it : vet_tmp)
		{
			if (fabs(it - fFillVaue) < 0.000001)
			{
				//not vaild value
				vet_tmp[n] = 9999;
			}
			else if (fscale != 1.0f || foffset != 0.0f)
			{
				vet_tmp[n] = it * fscale + foffset;
			}
			n++;
		}
 
		vet_data.swap(vet_tmp);
		delete[]data;
 
		
	}
	break;
	case 5://5维
	{	
		long nLen = 1;
		if (l0 == -1)
		{
			nLen *= p[0];
			lg0 = p[0];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg0);
		}
		else
		{
			vet_Inx.push_back(l0);
			vet_Count.push_back(1);
		}
		if (l1 == -1)
		{
			nLen *= p[1];
			lg1 = p[1];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg1);
		}
		else
		{
			vet_Inx.push_back(l1);
			vet_Count.push_back(1);
		}
		if (l2 == -1)
		{
			nLen *= p[2];
			lg2 = p[2];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg2);
		}
		else
		{
			vet_Inx.push_back(l2);
			vet_Count.push_back(1);
		}
		if (l3 == -1)
		{
			nLen *= p[3];
			lg3 = p[3];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg3);
		}
		else
		{
			vet_Inx.push_back(l3);
			vet_Count.push_back(1);
		}
		if (l4 == -1)
		{
			nLen *= p[4];
			lg4 = p[4];
			vet_Inx.push_back(0);
			vet_Count.push_back(lg4);
		}
		else
		{
			vet_Inx.push_back(l4);
			vet_Count.push_back(1);
		}
 
		float* data = new float[nLen];
		pVar.getVar(vet_Inx, vet_Count, data);
		_dataVector_f vet_tmp(data, data + nLen);
		vet_data.swap(vet_tmp);
		delete[]data;
 
		
	}
	break;
	default:
		break;
	}
	return true;
}
 
long* ncReader::GetEleEdge(QString strElement)
{
	long *p = NULL;
	if (m_pDataFile->isNull() ||!m_pDataFile)
		return p;
 
	NcVar pVar = m_pDataFile->getVar(strElement.toStdString().c_str());
	if (pVar.isNull())
		return p;
 
	int nLen = pVar.getDimCount();
	if (nLen <= 0)
		return p;
 
	p = new long[nLen];
 
	for (int n = 0; n < nLen; n++)
	{
		int nSize = pVar.getDim(n).getSize();
		p[n] = nSize;
	}
	return p;
}
 
NcVar* ncReader::GetVar(QString strEle)
{
	if (m_pDataFile)
		return &(m_pDataFile->getVar(strEle.toStdString().c_str()));
	return nullptr;
}
 
QString ncReader::getfilePath()
{
	return curFilePath;
}
 
int ncReader::GetVarNums()
{
	if (m_pDataFile)
		return m_pDataFile->getDimCount();
 
	return 0;
}
 
void ncReader::GetVars(_dataVector_s &vet_Vars)
{
	if (!m_pDataFile)
		return;
	vet_Vars.clear();
	std::multimap<std::string, NcDim> dims = m_pDataFile->getDims();
 
	int nIndex = 0;
	for (auto it : dims)
	{
		vet_Vars.push_back(QString::fromStdString(it.first));
		nIndex++;
	}
}

相关推荐

  1. Qt+NetCDF 读取NC文件

    2024-04-21 04:14:03       13 阅读
  2. Python常配置文件读取方法

    2024-04-21 04:14:03       33 阅读
  3. MATLAB中读取NetCDF(.nc文件中的group中的数据

    2024-04-21 04:14:03       13 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-21 04:14:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-21 04:14:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-21 04:14:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-21 04:14:03       18 阅读

热门阅读

  1. Qt实现XYModem协议(三)

    2024-04-21 04:14:03       12 阅读
  2. 面向对象——类与对象

    2024-04-21 04:14:03       14 阅读
  3. stable diffusion本地部署教程

    2024-04-21 04:14:03       15 阅读
  4. AIOS: LLM Agent Operating System

    2024-04-21 04:14:03       15 阅读
  5. uni-app vue3 setup 如何使用 onShow

    2024-04-21 04:14:03       14 阅读
  6. SpringBoot Jar包在CentOS7.x上注册成服务并开机启动

    2024-04-21 04:14:03       12 阅读
  7. Python 一个简化地址解析的利器 addressrec

    2024-04-21 04:14:03       14 阅读
  8. js DOM模型常用方法复盘梳理

    2024-04-21 04:14:03       15 阅读
  9. 信号塔(树形dp)

    2024-04-21 04:14:03       8 阅读
  10. Ocr识别

    2024-04-21 04:14:03       12 阅读
  11. 音视频、网络带宽等常用概念详解

    2024-04-21 04:14:03       12 阅读
  12. pytorch中模型训练的学习率动态调整

    2024-04-21 04:14:03       11 阅读
  13. web应用使用spring

    2024-04-21 04:14:03       16 阅读
  14. 2024.4.20力扣每日一题——组合总和

    2024-04-21 04:14:03       11 阅读
  15. 游戏中的伤害类型

    2024-04-21 04:14:03       11 阅读