用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++;
}
}