对于做海洋数据处理的同学,会经常遇到nc格式的文件,nc文件的格式全称是NetCDF,具体的详细解释请查询官网【https://www.unidata.ucar.edu/software/netcdf/docs/index.html】,一般从全球大洋数据库里面下载的温盐、风场及云量等数据,基本上是nc文件格式,每一个文件里面包含多个数据集,例如最简单的海面表温数据(Sea surface temperature data),数据范围是全球,空间分辨率为0.25 *0.25(~25km),时间分辨率为3 hour,所以一天的观测数据里面包含着两个子数据集(subDataset),一是海洋表温数据集,另一个是遗失数据说明信息数据集,在第一个子数据集(海洋表温数据集)内,又会包含分层数据,也就是每隔3个小时时间分辨率下的表温数据。

  基于前期查询李民录老师的《GDAL源码剖析与开发指南》一书才了解到,GDAL库本身是支持上述文件的读取的,故编译GDAL库(2.3.2版本),编译器采用MSVC2017版本,开发平台采用QT 5.11.2版本,由于QT本身不具有MSVC编译器配套的调试器,所以去微软官网下载了相应的调试器(winsdksetup.exe,安装的时候只选择安装Debugging Tools for Windows即可);经过查找GDAL官网的资料,GDAL库如若进行nc文件的读取和创建,必须还要单独下载NetCDF库文件,安装好后,配置环境变量即可,编译GDAL库时,设定好opt文件,开始编译,编译成功后即可通过下述参考博客1(Qt配置GDAL)方法,配置GDAL库。

  配置完成以后,即可进行文件的读取工作,话不多说,献上代码

读取-头文件

 1 #ifndef NCFILEREAD_H
2 #define NCFILEREAD_H
3
4
5 class ncFileRead
6 {
7 public:
8 void ncFileRead::fileRead(const char *ncFileName);
9 };
10
11 #endif // NCFILEREAD_H

读取-源文件

  1 #include "ncfileread.h"
2
3 #include <gdal_priv.h>
4 #include <vector>
5 #include <QVector>
6 #include <string>
7 #include <QString>
8 #include <QStringList>
9 #include <QDebug>
10
11 using namespace std;
12
13 void ncFileRead::fileRead(const char *ncFileName)
14 {
15 vector <string> vFileSets;
16 vector <string> pStrDesc;
17 vector<vector<float>> allSSTPixelNum;
18
19 GDALAllRegister();
20 CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");//中文路径
21 GDALDataset* fileDataset = (GDALDataset*) GDALOpen(ncFileName,GA_ReadOnly);//打开HDF数据集
22 if (fileDataset == NULL)
23 {
24 return;
25 }
26
27 char** sublist = GDALGetMetadata((GDALDatasetH) fileDataset,"SUBDATASETS");//获得数据的字符串,可以打印出来看看自己需要的数据在那
28
29 int iCount = CSLCount(sublist);
30 if(iCount <= 0){
31 qDebug() << "该文件没有子数据" << endl;
32 GDALClose((GDALDriverH)fileDataset);
33 }
34
35 //存储数据集信息
36 for(int i = 0; sublist[i] != NULL;i++){
37
38 qDebug() << sublist[i] << endl;
39
40 if(i%2 != 0){
41 continue;
42 }
43
44 /**
45 * 01、海洋表温度数据集 float32
46 * 02、数据丢失补充信息 int8
47 * */
48 string tmpstr = sublist[i];
49 tmpstr = tmpstr.substr(tmpstr.find_first_of("=")+1);
50 const char *tmpc_str = tmpstr.c_str();
51
52 string tmpdsc = sublist[i+1];
53 tmpdsc = tmpdsc.substr(tmpdsc.find_first_of("=")+1);
54
55 GDALDataset* hTmpDt = (GDALDataset*)GDALOpen(tmpc_str,GA_ReadOnly);//打开该数据
56
57 if (hTmpDt != NULL)
58 {
59 vFileSets.push_back(tmpc_str);
60 }
61 if(&pStrDesc != NULL){
62 pStrDesc.push_back(tmpdsc);
63 }
64 GDALClose(hTmpDt);
65 }
66
67
68 //数据处理
69
70 qDebug() << "read RasterBand(1) ......" << endl;
71
72 //读取第一个波段
73
74 QString qtmpdsc = QString::fromStdString(pStrDesc[0]);
75 QStringList qtmpdsclist = qtmpdsc.split(" ");
76 QString dataset_name = qtmpdsclist[1];
77
78 float *lineData = NULL;
79 if (dataset_name == "sea_surface_temperature")
80 {
81 GDALDataset *tempDt = (GDALDataset *)GDALOpen(vFileSets[0].data(), GA_ReadOnly);
82 int BandNum = tempDt->GetRasterCount();
83
84 GDALRasterBand * poBand = tempDt->GetRasterBand(1);
85 lineData = new float[1 * poBand->GetXSize()];
86 for (int iLine = 0; iLine < poBand->GetYSize(); iLine++)
87 {
88 allSSTPixelNum.resize(poBand->GetYSize());
89 for (int iPixel = 0; iPixel < poBand->GetXSize(); iPixel++)
90 {
91 allSSTPixelNum[iLine].resize(poBand->GetXSize());
92 poBand->RasterIO(GF_Read, 0, iLine, poBand->GetXSize(), 1,lineData, poBand->GetXSize(), 1, GDT_Float32, 0, 0);
93 allSSTPixelNum[iLine][iPixel] = lineData[iPixel];
94 }
95 }
96 if (lineData)
97 {
98 delete[]lineData;
99 lineData = NULL;
100 }
101 GDALClose((GDALDatasetH)tempDt);
102 }
103
104
105 qDebug() << "read complete!" << endl;
106
107 GDALClose((GDALDriverH)fileDataset);
108
109 }

主函数调用

 1 #include <QCoreApplication>
2
3 #include "ncfileread.h"
4 #include <QWidget>
5
6 int main(int argc, char *argv[])
7 {
8 QCoreApplication a(argc, argv);
9
10 ncFileRead nfr;
11 nfr.fileRead("F:/Data File/test/SEAFLUX-OSB-CDR_V02R00_SST_D20060101_C20160824.nc");
12
13 return a.exec();
14 }

文件读取结果

  至此,nc文件的读取工作已经完成,数据读取上来以后,即可进行进一步的数据处理工作。

致谢

  感谢李民录老师的指导,以及其他不知姓名的的博主,再次感谢你们对于技术的分享!

参考博客

1、Qt配置GDAL【https://blog.csdn.net/u010670734/article/details/53106786?locationNum=13&fps=1】

2、使用GDAL读取necdf数据【https://blog.csdn.net/bluels01/article/details/8091260】

3、使用GDAL获取HDF等数据集中的图像【https://blog.csdn.net/liminlu0314/article/details/8478339】

基于GDAL库,读取.nc文件(以海洋表温数据为例)C++版的更多相关文章

  1. 基于GDAL库海洋表温日平均计算工具设计与实现 C++版

    技术背景 在对物理海洋数据处理过程中,表层温度是众多要素中的一种,本文书要是针对海洋表温数据批量日平均处理的一个工具设计.首先要在对当前的SST数据文件作一下简要的说明,SST全称为sea surfe ...

  2. 使用C#版本的gdal库打开hdf文件

    作者:朱金灿 来源:http://blog.csdn.net/clever101 最近应同事的请求帮忙研究下使用C#版的gdal库读取hdf文件,今天算是有一点成果,特地做一些记录. 首先是编译C#版 ...

  3. 基于GDAL库,读取海洋风场数据(.nc格式)c++版

    经过这一段时间的对海洋数据的处理,接触了大量的与海洋相关的数据,例如海洋地形.海洋表面温度.盐度.湿度.云场.风场等数据,除了地形数据是grd格式外,其他的都是nc格式的数据.本文将以海洋风场数据为例 ...

  4. 基于GDAL库,读取.grd文件(以海洋地形数据为例)C++版

    技术背景 海洋地形数据主要是通过美国全球地形起伏数据(GMT)获得,数据格式为grd(GSBG)二进制数据,打开软件通过是Surfer软件,surfer软件可进行数据的编辑处理,以及进一步的可视化表达 ...

  5. 关于基于GDAL库QT软件平台下C++语言开发使用说明

    背景前提 地理空间数据抽象库(GDAL)是一个用于读取和编写栅格和矢量地理空间数据格式的计算机软件库,由开源地理空间基金会在许可的X / MIT风格免费软件许可下发布. 作为一个库,它为调用应用程序提 ...

  6. 基于GDAL库,读取.grd文件(以海洋地形数据为例)Java版

    技术背景 海洋地形数据主要是通过美国全球地形起伏数据(GMT)获得,数据格式为grd(GSBG)二进制数据,打开软件通过是Surfer软件,surfer软件可进行数据的编辑处理,以及进一步的可视化表达 ...

  7. C++调用GDAL库读取并输出tif文件,并计算斑块面积输出景观指数:CSD

    部分源码选自GDAL库的官方网址:www.gdal.org,其余的代码为笔者自己编写. // readfile.cpp : 定义控制台应用程序的入口点. // /* part of the codes ...

  8. GDAL库——读取图像并提取基本信息

    GDAL库是一个跨平台的栅格地理数据格式库,包括读取.写入.转换.处理各种栅格数据格式(有些特定的格式对一些操作如写入等不支持).它使用了一个单一的抽象数据模型就支持了大多数的栅格数据.这里有GDAL ...

  9. java读取nc文件的问题,前端ajax 发送参数进行交互的实例

    1.问题背景: 需要解析nc文件的数据源,获取一个三维数据,并计算器开发值. java 后台处理: 定以一个实例来接收解析的数据并返回给前端. package cn.edu.shou.domain; ...

随机推荐

  1. vue中把一个事件绑定到子组件上

    官网上是这样描述的 你可能有很多次想要在一个组件的根元素上直接监听一个原生事件.这时,你可以使用 v-on的 .native 修饰符 父组件App.vue <template> <d ...

  2. vue - public 引入 <script>报错 Uncaught SyntaxError: Unexpected token '<'

    1.现象 原本我是直接在母版引入 <script type="application/javascript" src="static/config.js" ...

  3. react中关于create-react-app2里css相关配置

    先看 webpack.config.dev.js 里的相关代码: // style files regexes const cssRegex = /\.css$/; const cssModuleRe ...

  4. [转]浮点运算decimal.js

    开发过程中免不了有浮点运算,JavaScript浮点运算的精度问题会带来一些困扰 JavaScript 只有一种数字类型 ( Number ) JavaScript采用 IEEE 754 标准双精度浮 ...

  5. mysql之突破secure_file_priv写webshell

    在某些情况下,当我们进入了一个网站的phpMyAdmin时,想通过select into outfile来写shell,但是通常都会报错. 这是因为在mysql 5.6.34版本以后 secure_f ...

  6. idea同时启动多个微服务模块进行管理

    1,打开IDEA项目中的 .idea 下 的workspace.xml 找到文件中的 RunDashboard 配置块,增加如下圈起来的地方 代码: <option name="con ...

  7. 【Java】代码块

    代码块 代码块的作用:用来初始化类.对象 代码块如果有修饰的话,只能使用static 分类:静态代码块.非静态代码块 静态代码块 static{ } 内部可以有输出语句 随着类的加载而执行,而且只执行 ...

  8. elasticsearch拼写纠错之Term Suggester

    一.什么是拼写纠错 拼写纠错就是搜索引擎可以智能的感知用户输入关键字的错误,并使用纠正过的关键字进行搜索展示给用户:拼写纠错是一种改善用户体验的功能: elasticsearch提供了以下不同类型的s ...

  9. HTML+CSS+Javascript实现轮播图效果

    HTML+CSS+Javascript实现轮播图效果 注意:根据自己图片大小来更改轮播图大小. <!doctype html> <html> <head> < ...

  10. JDK原子操作类

    在Atomic包里一共提供了13个类,属于4种类型的原子更新方式,分别是原子更新基本类型.原子更新数组.原子更新引用和原子更新属性(字段).Atomic包里的类基本都是使用Unsafe实现的包装类. ...