基于GDAL库,读取海洋风场数据(.nc格式)c++版经过这⼀段时间的对海洋数据的处理,接触了⼤量的与海洋相关的数据,例如海洋地形、海洋表⾯温度、盐度、湿度、云场、风场等数据,除了地形数据是grd格式外,其他的都是nc格式的数据。本⽂将以海洋风场数据为例,进⾏nc格式⽂件的读取。
海洋风场数据(ccmp_wind)⼀般情况下会包含三个数据集:第⼀个数据集是uwnd(standard_name = "eastward_wind"),第⼆个数据集是vwnd(standard_name = "northward_wind"),第三个数据集是nobs或者wspd。前两个数据集是⽮量数据,表⽰此处的风场⽅向最后⼀个数据集是标量数据,代表此处的风速。每个数据集中数据的存储⼜分为四个波段(也可以说是图层),⼀天的观测时间分为四个时间点,所以有四个图层。
GDAL库可以提供对nc格式数据的读取,本次数据的读取是在qt+vs2017环境下配置gdal库和netcdf库,环境的配置可以在⽹上找
到,GDAL库的配置可以根据《GDAL源码剖析和开发指南》书中的内容进⾏编译和配置,配置完成后就可以运⾏数据,读取nc⽂件。
数据读取的代码如下:
头⽂件:
1 #ifndef CCMPFILEREAD_H
旷古绝伦2#define CCMPFILEREAD_H
3class ccmpFileRead
4 {
5public:
6void ccmpFileRead::fileread(const char*ccmpFilename);
7 };
8
9
10
11#endif// CCMPFILEREAD_H
源⽂件:
1 #include "ccmpfileread.h"
2
3 #include <gdal_priv.h>
4 #include <vector>
5 #include <QVector>
6
7 #include <string>
8 #include <QString>
9 #include <QStringList>
10 #include <QDebug>
义正辞严
11
12 #include <fstream>
痛彻心扉的歌词13
14using namespace std;
15
16void ccmpFileRead::fileread(const char *ccmpFilename)
17 {
18 vector <string> vFileSets;
空的多音字组词19 vector <string> pStrDesc;
20 vector<vector<float>> allSSTPixelNum1,allSSTPixelNum2,allSSTPixelNum3;
21
22
23 GDALAllRegister();
24 CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");//中⽂路径
25 GDALDatat* fileDatat = (GDALDatat*) GDALOpen(ccmpFilename,GA_ReadOnly);//打开HDF数据集
26if (fileDatat == NULL)
27 {
28return;
29 }
30
31char** sublist = GDALGetMetadata((GDALDatatH) fileDatat,"SUBDATASETS");//获得数据的字符串,可以打印出来看看⾃⼰需要的数据在那
32
33int iCount = CSLCount(sublist);
34if(iCount <= 0){
治疗糖尿病的偏方35 qDebug() << "该⽂件没有⼦数据" << endl;
36 GDALClo((GDALDriverH)fileDatat);
37 }
38
39//存储数据集信息
40for(int i = 0; sublist[i] != NULL;i++)
41 {
42
43 qDebug() << sublist[i] << endl;
44
45if(i%2 != 0)
46 {
47continue;
48 }
49
50//三个数据集:uwnd vwnd wspd 只读取前两个数据集,第三个数据集是补充数据集
51
52string tmpstr = sublist[i];
53 tmpstr = tmpstr.substr(tmpstr.find_first_of("=")+1);
54const char *tmpc_str = tmpstr.c_str();
55
56string tmpdsc = sublist[i+1];
57 tmpdsc = tmpdsc.substr(tmpdsc.find_first_of("=")+1);
58
59 GDALDatat* hTmpDt = (GDALDatat*)GDALOpen(tmpc_str,GA_ReadOnly);//打开该数据
60
61if (hTmpDt != NULL)
62 {
63 vFileSets.push_back(tmpc_str);
64 }
65if(&pStrDesc != NULL){
66 pStrDesc.push_back(tmpdsc);
67 }
68 GDALClo(hTmpDt);
69 }
70
71
72//三个数据集分别读取
73
74 qDebug() << "read uwnd ......" << endl;
75
76 QString qtmpdsc1 = QString::fromStdString(pStrDesc[0]);//锁定某⼀个数据集
77
78 qDebug()<<qtmpdsc1<<endl;
79
80float *lineData = NULL;
81if (qtmpdsc1!=NULL)
82 {
83 GDALDatat *tempDt = (GDALDatat *)GDALOpen(vFileSets[0].data(), GA_ReadOnly);
84int BandNum = tempDt->GetRasterCount();
85
86int panBandmap[1] ={1};
87 lineData = new float[1 * 200*200];
88 tempDt->RasterIO(GF_Read,508,112,32,24,lineData,50,50,GDT_Float32,1,panBandmap,0,0,0);
89
90lol妖姬
91for (int iLine = 0; iLine <tempDt->GetRasterYSize(); iLine++)
92 {
93 size(tempDt->GetRasterYSize());
94for (int iPixel = 0; iPixel < tempDt->GetRasterXSize(); iPixel++)
豁达是什么意思
95 {
96 allSSTPixelNum1[iLine].resize(tempDt->GetRasterXSize());
97 tempDt->RasterIO(GF_Read, 0, iLine, tempDt->GetRasterXSize(), 1,lineData, tempDt->GetRasterXSize(), 1, GDT_Float32, 1, panBandmap,0,0,0);
98 allSSTPixelNum1[iLine][iPixel] = lineData[iPixel];
99 }
100
101 }
102if(lineData)
103 {
104delete[]lineData;
105 lineData = NULL;
106 }
107
108 qDebug() << "uwnd read over!" << endl;
109
110 qDebug() <<"uwnd="<<'\n'<<allSSTPixelNum1[200]<<'\n'<<endl;
111
112 }
113
114//d读取vwnd数据集
115理财者
116 QString qtmpdsc2 = QString::fromStdString(pStrDesc[2]);
117
118if (qtmpdsc2!=NULL)
119 {
120 GDALDatat *tempDt = (GDALDatat *)GDALOpen(vFileSets[0].data(), GA_ReadOnly);
121int BandNum = tempDt->GetRasterCount();
122 qDebug()<<BandNum<<endl;
123int panBandmap[1] ={1};
124 lineData = new float[1 * 200*200];
125 tempDt->RasterIO(GF_Read,508,112,32,24,lineData,50,50,GDT_Float32,1,panBandmap,0,0,0);
126
127
128for (int iLine = 0; iLine <tempDt->GetRasterYSize(); iLine++)
129 {
130 size(tempDt->GetRasterYSize());
131for (int iPixel = 0; iPixel < tempDt->GetRasterXSize(); iPixel++)
132 {
133 allSSTPixelNum2[iLine].resize(tempDt->GetRasterXSize());
134 tempDt->RasterIO(GF_Read, 0, iLine, tempDt->GetRasterXSize(), 1,lineData, tempDt->GetRasterXSize(), 1, GDT_Float32, 1, panBandmap,0,0,0); 135 allSSTPixelNum2[iLine][iPixel] = lineData[iPixel];
136 }
137
138 }
139if(lineData)
140 {
141delete[]lineData;
142 lineData = NULL;
143 }
144
145 qDebug() << "vwnd read over!" << endl;
146
147 qDebug() <<"vwnd="<<'\n'<<allSSTPixelNum2[200]<<'\n'<<endl;
148
149 }
150
151//读取wspd数据
152
153 QString qtmpdsc3 = QString::fromStdString(pStrDesc[2]);
154
155if (qtmpdsc3!=NULL)
156 {
157 GDALDatat *tempDt = (GDALDatat *)GDALOpen(vFileSets[0].data(), GA_ReadOnly);
158int BandNum = tempDt->GetRasterCount();
159 qDebug()<<BandNum<<endl;
160int panBandmap[1] ={1};
161 lineData = new float[1 * 200*200];
162 tempDt->RasterIO(GF_Read,508,112,32,24,lineData,50,50,GDT_Float32,1,panBandmap,0,0,0);
163
164
165for (int iLine = 0; iLine <tempDt->GetRasterYSize(); iLine++)
166 {
167 size(tempDt->GetRasterYSize());
168for (int iPixel = 0; iPixel < tempDt->GetRasterXSize(); iPixel++)
169 {
170 allSSTPixelNum3[iLine].resize(tempDt->GetRasterXSize());
171 tempDt->RasterIO(GF_Read, 0, iLine, tempDt->GetRasterXSize(), 1,lineData, tempDt->GetRasterXSize(), 1, GDT_Float32, 1, panBandmap,0,0,0); 172 allSSTPixelNum3[iLine][iPixel] = lineData[iPixel];
173 }
174
175 }
176
177if(lineData)
178 {
179delete[]lineData;
180 lineData = NULL;
181 }
182
183 qDebug() << "wspd read over!" << endl;
184
185 qDebug() <<"wspd="<<'\n'<<allSSTPixelNum3[200]<<'\n'<<endl;
186
187 GDALClo((GDALDatatH)tempDt);
188
189 }
190
191 GDALClo((GDALDriverH)fileDatat);
192 }
主函数调⽤:
1 #include <QCoreApplication>
2 #include <ccmpfileread.h>
3int main(int argc, char *argv[])
4 {
5 QCoreApplication a(argc, argv);
6 ccmpFileRead a1;
7 a1.fileread("E:/odp_workplace/odp_data/testdata/CCMP_Wind_Analysis_198707_V02.0_L3.");
();
9 }
输出结果:
如上图所⽰数据已经读取并显⽰成功。