经过这一段时间的对海洋数据的处理,接触了大量的与海洋相关的数据,例如海洋地形、海洋表面温度、盐度、湿度、云场、风场等数据,除了地形数据是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
- 3 class ccmpFileRead
- 4 {
- 5 public:
- 6 void 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
- 14 using namespace std;
- 15
- 16 void 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 GDALDataset* fileDataset = (GDALDataset*) GDALOpen(ccmpFilename,GA_ReadOnly);//打开HDF数据集
- 26 if (fileDataset == NULL)
- 27 {
- 28 return;
- 29 }
- 30
- 31 char** sublist = GDALGetMetadata((GDALDatasetH) fileDataset,"SUBDATASETS");//获得数据的字符串,可以打印出来看看自己需要的数据在那
- 32
- 33 int iCount = CSLCount(sublist);
- 34 if(iCount <= 0){
- 35 qDebug() << "该文件没有子数据" << endl;
- 36 GDALClose((GDALDriverH)fileDataset);
- 37 }
- 38
- 39 //存储数据集信息
- 40 for(int i = 0; sublist[i] != NULL;i++)
- 41 {
- 42
- 43 qDebug() << sublist[i] << endl;
- 44
- 45 if(i%2 != 0)
- 46 {
- 47 continue;
- 48 }
- 49
- 50 //三个数据集:uwnd vwnd wspd 只读取前两个数据集,第三个数据集是补充数据集
- 51
- 52 string tmpstr = sublist[i];
- 53 tmpstr = tmpstr.substr(tmpstr.find_first_of("=")+1);
- 54 const char *tmpc_str = tmpstr.c_str();
- 55
- 56 string tmpdsc = sublist[i+1];
- 57 tmpdsc = tmpdsc.substr(tmpdsc.find_first_of("=")+1);
- 58
- 59 GDALDataset* hTmpDt = (GDALDataset*)GDALOpen(tmpc_str,GA_ReadOnly);//打开该数据
- 60
- 61 if (hTmpDt != NULL)
- 62 {
- 63 vFileSets.push_back(tmpc_str);
- 64 }
- 65 if(&pStrDesc != NULL){
- 66 pStrDesc.push_back(tmpdsc);
- 67 }
- 68 GDALClose(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
- 80 float *lineData = NULL;
- 81 if (qtmpdsc1!=NULL)
- 82 {
- 83 GDALDataset *tempDt = (GDALDataset *)GDALOpen(vFileSets[0].data(), GA_ReadOnly);
- 84 int BandNum = tempDt->GetRasterCount();
- 85
- 86 int 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
- 90
- 91 for (int iLine = 0; iLine <tempDt->GetRasterYSize(); iLine++)
- 92 {
- 93 allSSTPixelNum1.resize(tempDt->GetRasterYSize());
- 94 for (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 }
- 102 if(lineData)
- 103 {
- 104 delete[]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
- 118 if (qtmpdsc2!=NULL)
- 119 {
- 120 GDALDataset *tempDt = (GDALDataset *)GDALOpen(vFileSets[0].data(), GA_ReadOnly);
- 121 int BandNum = tempDt->GetRasterCount();
- 122 qDebug()<<BandNum<<endl;
- 123 int 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
- 128 for (int iLine = 0; iLine <tempDt->GetRasterYSize(); iLine++)
- 129 {
- 130 allSSTPixelNum2.resize(tempDt->GetRasterYSize());
- 131 for (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 }
- 139 if(lineData)
- 140 {
- 141 delete[]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
- 155 if (qtmpdsc3!=NULL)
- 156 {
- 157 GDALDataset *tempDt = (GDALDataset *)GDALOpen(vFileSets[0].data(), GA_ReadOnly);
- 158 int BandNum = tempDt->GetRasterCount();
- 159 qDebug()<<BandNum<<endl;
- 160 int 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
- 165 for (int iLine = 0; iLine <tempDt->GetRasterYSize(); iLine++)
- 166 {
- 167 allSSTPixelNum3.resize(tempDt->GetRasterYSize());
- 168 for (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
- 177 if(lineData)
- 178 {
- 179 delete[]lineData;
- 180 lineData = NULL;
- 181 }
- 182
- 183 qDebug() << "wspd read over!" << endl;
- 184
- 185 qDebug() <<"wspd="<<'\n'<<allSSTPixelNum3[200]<<'\n'<<endl;
- 186
- 187 GDALClose((GDALDatasetH)tempDt);
- 188
- 189 }
- 190
- 191 GDALClose((GDALDriverH)fileDataset);
- 192 }
- 1 #include <QCoreApplication>
- 2 #include <ccmpfileread.h>
- 3 int 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.5_RSS.nc");
- 8 return a.exec();
- 9 }