对于做海洋数据处理的同学,会经常遇到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. 初识python: while循环 猜年龄小游戏

    知识点: 1.python注释方法: 单行注释: # 多行注释: '''注释内容 '''  (单引号或双引号都可以),亦可打印多行 例: #此处是单行注释信息 print('这里是打印内容') #这里 ...

  2. HDU 1009 FatMouse' Trade (贪心)

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1009 题目大意:肥鼠准备了 磅的猫粮,准备和看管仓库的猫交易,仓库里装有他最喜爱的食物 豆.仓库有 个 ...

  3. python+selenium 元素定位--iframe

    1. 一般webdriver要操作页面元素需要在Top Window的状态下,如下: 2.当浏览器显示iframe时,用正常的元素定位是没有效果的,需要将页面装换到iframe下再对页面元素进行操作 ...

  4. IDEA导入Web项目配置Tomcat启动

    1.导入项目 2.配置project 3.导入项目模块 配置Models 4.配置Libraries 5. 6. 7.配置tomcat

  5. 【Java】成员变量赋值执行顺序

    程序中成员变量赋值的执行顺序

  6. 【Java】方法

    文章目录 何谓方法 方法的定义 方法调用 方法重载 命令行传参 可变参数 递归 何谓方法 System.out.println(),是什么 Java方法是语句的集合,它们在一起执行一个功能 方法是解决 ...

  7. jmeter和JDK安装教程(Windows)

    1.JDK的安装及环境变量配置 1.JDK的下载安装 JDK官网下载地址:https://www.oracle.com/java/technologies/downloads 然后注册账号,开始下载, ...

  8. 利用栈实现括号匹配(python语言)

    原理: 右括号总是与最近的左括号匹配 --- 栈的后进先出 从左往右遍历字符串,遇到左括号就入栈,遇到右括号时,就出栈一个元素与其配对 当栈为空时,遇到右括号,则此右括号无与之匹配的左括号 当最终右括 ...

  9. 安全检测服务如何帮助社交类App提升应用自身和用户个人安全

    社交类App如今人手必备,且大部分功能.业务活动和产品价值均与用户紧密联系,流量的多少甚至影响着一款应用的生命周期.因此,开发者们开始关注内容合规.治理黑产.防盗防爬等应用安全方面的能力.识别虚假流量 ...

  10. gin中使用路由组

    package main import ( "github.com/gin-gonic/gin" ) func main() { router := gin.Default() / ...