经过这一段时间的对海洋数据的处理,接触了大量的与海洋相关的数据,例如海洋地形、海洋表面温度、盐度、湿度、云场、风场等数据,除了地形数据是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+