用Qt+NetCDF 读取NC文件

2024-04-17 16:20
文章标签 读取 qt nc netcdf

本文主要是介绍用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 >=1vet_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 >=1vet_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 valuevet_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++;}
}

这篇关于用Qt+NetCDF 读取NC文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/912283

相关文章

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

如何使用 Python 读取 Excel 数据

《如何使用Python读取Excel数据》:本文主要介绍使用Python读取Excel数据的详细教程,通过pandas和openpyxl,你可以轻松读取Excel文件,并进行各种数据处理操... 目录使用 python 读取 Excel 数据的详细教程1. 安装必要的依赖2. 读取 Excel 文件3. 读

Spring Boot读取配置文件的五种方式小结

《SpringBoot读取配置文件的五种方式小结》SpringBoot提供了灵活多样的方式来读取配置文件,这篇文章为大家介绍了5种常见的读取方式,文中的示例代码简洁易懂,大家可以根据自己的需要进... 目录1. 配置文件位置与加载顺序2. 读取配置文件的方式汇总方式一:使用 @Value 注解读取配置方式二

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

基于Python实现读取嵌套压缩包下文件的方法

《基于Python实现读取嵌套压缩包下文件的方法》工作中遇到的问题,需要用Python实现嵌套压缩包下文件读取,本文给大家介绍了详细的解决方法,并有相关的代码示例供大家参考,需要的朋友可以参考下... 目录思路完整代码代码优化思路打开外层zip压缩包并遍历文件:使用with zipfile.ZipFil

Qt中QGroupBox控件的实现

《Qt中QGroupBox控件的实现》QGroupBox是Qt框架中一个非常有用的控件,它主要用于组织和管理一组相关的控件,本文主要介绍了Qt中QGroupBox控件的实现,具有一定的参考价值,感兴趣... 目录引言一、基本属性二、常用方法2.1 构造函数 2.2 设置标题2.3 设置复选框模式2.4 是否

QT进行CSV文件初始化与读写操作

《QT进行CSV文件初始化与读写操作》这篇文章主要为大家详细介绍了在QT环境中如何进行CSV文件的初始化、写入和读取操作,本文为大家整理了相关的操作的多种方法,希望对大家有所帮助... 目录前言一、CSV文件初始化二、CSV写入三、CSV读取四、QT 逐行读取csv文件五、Qt如何将数据保存成CSV文件前言

Qt中QUndoView控件的具体使用

《Qt中QUndoView控件的具体使用》QUndoView是Qt框架中用于可视化显示QUndoStack内容的控件,本文主要介绍了Qt中QUndoView控件的具体使用,具有一定的参考价值,感兴趣的... 目录引言一、QUndoView 的用途二、工作原理三、 如何与 QUnDOStack 配合使用四、自

Qt spdlog日志模块的使用详解

《Qtspdlog日志模块的使用详解》在Qt应用程序开发中,良好的日志系统至关重要,本文将介绍如何使用spdlog1.5.0创建满足以下要求的日志系统,感兴趣的朋友一起看看吧... 目录版本摘要例子logmanager.cpp文件main.cpp文件版本spdlog版本:1.5.0采用1.5.0版本主要

解决Java中基于GeoTools的Shapefile读取乱码的问题

《解决Java中基于GeoTools的Shapefile读取乱码的问题》本文主要讨论了在使用Java编程语言进行地理信息数据解析时遇到的Shapefile属性信息乱码问题,以及根据不同的编码设置进行属... 目录前言1、Shapefile属性字段编码的情况:一、Shp文件常见的字符集编码1、System编码