经过这一段时间的对海洋数据的处理, 接触了大量的与海洋相关的数据, 例如海洋地形, 海洋表面温度, 盐度, 湿度, 云场, 风场等数据, 除了地形数据是 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 文件.
数据读取的代码如下:
头文件:
- #ifndef CCMPFILEREAD_H
- #define CCMPFILEREAD_H
- class ccmpFileRead
- {
- public:
- void ccmpFileRead::fileread(const char*ccmpFilename);
- };
- #endif // CCMPFILEREAD_H
源文件:
- #include "ccmpfileread.h"
- #include <gdal_priv.h>
- #include <vector>
- #include <QVector>
- #include <string>
- #include <QString>
- #include <QStringList>
- #include <QDebug>
- #include <fstream>
- using namespace std;
- void ccmpFileRead::fileread(const char *ccmpFilename)
- {
- vector <string> vFileSets;
- vector <string> pStrDesc;
- vector<vector<float>> allSSTPixelNum1,allSSTPixelNum2,allSSTPixelNum3;
- GDALAllRegister();
- CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");// 中文路径
- GDALDataset* fileDataset = (GDALDataset*) GDALOpen(ccmpFilename,GA_ReadOnly);// 打开 HDF 数据集
- if (fileDataset == NULL)
- {
- return;
- }
- char** sublist = GDALGetMetadata((GDALDatasetH) fileDataset,"SUBDATASETS");// 获得数据的字符串, 可以打印出来看看自己需要的数据在那
- int iCount = CSLCount(sublist);
- if(iCount <= 0){
- qDebug() <<"该文件没有子数据" << endl;
- GDALClose((GDALDriverH)fileDataset);
- }
- // 存储数据集信息
- for(int i = 0; sublist[i] != NULL;i++)
- {
- qDebug() << sublist[i] << endl;
- if(i%2 != 0)
- {
- continue;
- }
- // 三个数据集: uwnd vwnd wspd 只读取前两个数据集, 第三个数据集是补充数据集
- string tmpstr = sublist[i];
- tmpstr = tmpstr.substr(tmpstr.find_first_of("=")+1);
- const char *tmpc_str = tmpstr.c_str();
- string tmpdsc = sublist[i+1];
- tmpdsc = tmpdsc.substr(tmpdsc.find_first_of("=")+1);
- GDALDataset* hTmpDt = (GDALDataset*)GDALOpen(tmpc_str,GA_ReadOnly);// 打开该数据
- if (hTmpDt != NULL)
- {
- vFileSets.push_back(tmpc_str);
- }
- if(&pStrDesc != NULL){
- pStrDesc.push_back(tmpdsc);
- }
- GDALClose(hTmpDt);
- }
- // 三个数据集分别读取
- qDebug() << "read uwnd ......" << endl;
- QString qtmpdsc1 = QString::fromStdString(pStrDesc[0]);// 锁定某一个数据集
- qDebug()<<qtmpdsc1<<endl;
- float *lineData = NULL;
- if (qtmpdsc1!=NULL)
- {
- GDALDataset *tempDt = (GDALDataset *)GDALOpen(vFileSets[0].data(), GA_ReadOnly);
- int BandNum = tempDt->GetRasterCount();
- int panBandmap[1] ={1};
- lineData = new float[1 * 200*200];
- tempDt->RasterIO(GF_Read,508,112,32,24,lineData,50,50,GDT_Float32,1,panBandmap,0,0,0);
- for (int iLine = 0; iLine <tempDt->GetRasterYSize(); iLine++)
- {
- allSSTPixelNum1.resize(tempDt->GetRasterYSize());
- for (int iPixel = 0; iPixel <tempDt->GetRasterXSize(); iPixel++)
- {
- allSSTPixelNum1[iLine].resize(tempDt->GetRasterXSize());
- tempDt->RasterIO(GF_Read, 0, iLine, tempDt->GetRasterXSize(), 1,lineData, tempDt->GetRasterXSize(), 1, GDT_Float32, 1, panBandmap,0,0,0);
- allSSTPixelNum1[iLine][iPixel] = lineData[iPixel];
- }
- }
- if(lineData)
- {
- delete[]lineData;
- lineData = NULL;
- }
- qDebug() <<"uwnd read over!" << endl;
- qDebug() <<"uwnd="<<'\n'<<allSSTPixelNum1[200]<<'\n'<<endl;
- }
- //d 读取 vwnd 数据集
- QString qtmpdsc2 = QString::fromStdString(pStrDesc[2]);
- if (qtmpdsc2!=NULL)
- {
- GDALDataset *tempDt = (GDALDataset *)GDALOpen(vFileSets[0].data(), GA_ReadOnly);
- int BandNum = tempDt->GetRasterCount();
- qDebug()<<BandNum<<endl;
- int panBandmap[1] ={1};
- lineData = new float[1 * 200*200];
- tempDt->RasterIO(GF_Read,508,112,32,24,lineData,50,50,GDT_Float32,1,panBandmap,0,0,0);
- for (int iLine = 0; iLine <tempDt->GetRasterYSize(); iLine++)
- {
- allSSTPixelNum2.resize(tempDt->GetRasterYSize());
- for (int iPixel = 0; iPixel <tempDt->GetRasterXSize(); iPixel++)
- {
- allSSTPixelNum2[iLine].resize(tempDt->GetRasterXSize());
- tempDt->RasterIO(GF_Read, 0, iLine, tempDt->GetRasterXSize(), 1,lineData, tempDt->GetRasterXSize(), 1, GDT_Float32, 1, panBandmap,0,0,0);
- allSSTPixelNum2[iLine][iPixel] = lineData[iPixel];
- }
- }
- if(lineData)
- {
- delete[]lineData;
- lineData = NULL;
- }
- qDebug() <<"vwnd read over!" << endl;
- qDebug() <<"vwnd="<<'\n'<<allSSTPixelNum2[200]<<'\n'<<endl;
- }
- // 读取 wspd 数据
- QString qtmpdsc3 = QString::fromStdString(pStrDesc[2]);
- if (qtmpdsc3!=NULL)
- {
- GDALDataset *tempDt = (GDALDataset *)GDALOpen(vFileSets[0].data(), GA_ReadOnly);
- int BandNum = tempDt->GetRasterCount();
- qDebug()<<BandNum<<endl;
- int panBandmap[1] ={1};
- lineData = new float[1 * 200*200];
- tempDt->RasterIO(GF_Read,508,112,32,24,lineData,50,50,GDT_Float32,1,panBandmap,0,0,0);
- for (int iLine = 0; iLine <tempDt->GetRasterYSize(); iLine++)
- {
- allSSTPixelNum3.resize(tempDt->GetRasterYSize());
- for (int iPixel = 0; iPixel <tempDt->GetRasterXSize(); iPixel++)
- {
- allSSTPixelNum3[iLine].resize(tempDt->GetRasterXSize());
- tempDt->RasterIO(GF_Read, 0, iLine, tempDt->GetRasterXSize(), 1,lineData, tempDt->GetRasterXSize(), 1, GDT_Float32, 1, panBandmap,0,0,0);
- allSSTPixelNum3[iLine][iPixel] = lineData[iPixel];
- }
- }
- if(lineData)
- {
- delete[]lineData;
- lineData = NULL;
- }
- qDebug() <<"wspd read over!" << endl;
- qDebug() <<"wspd="<<'\n'<<allSSTPixelNum3[200]<<'\n'<<endl;
- GDALClose((GDALDatasetH)tempDt);
- }
- GDALClose((GDALDriverH)fileDataset);
- }
主函数调用:
- #include <QCoreApplication>
- #include <ccmpfileread.h>
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
- ccmpFileRead a1;
- a1.fileread("E:/odp_workplace/odp_data/testdata/CCMP_Wind_Analysis_198707_V02.0_L3.5_RSS.nc");
- return a.exec();
- }
输出结果:
如上图所示数据已经读取并显示成功.
来源: https://www.cnblogs.com/KunZ586/p/10060424.html