经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
基于GDAL库,读取海洋风场数据(.nc格式)c++版
来源:cnblogs  作者:KunZ586  时间:2018/12/3 20:07:51  对本文有异议

        经过这一段时间的对海洋数据的处理,接触了大量的与海洋相关的数据,例如海洋地形、海洋表面温度、盐度、湿度、云场、风场等数据,除了地形数据是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. 1 #ifndef CCMPFILEREAD_H
  2. 2 #define CCMPFILEREAD_H
  3. 3 class ccmpFileRead
  4. 4 {
  5. 5 public:
  6. 6 void ccmpFileRead::fileread(const char*ccmpFilename);
  7. 7 };
  8. 8
  9. 9
  10. 10
  11. 11 #endif // CCMPFILEREAD_H

源文件:

  1. 1 #include "ccmpfileread.h"
  2. 2
  3. 3 #include <gdal_priv.h>
  4. 4 #include <vector>
  5. 5 #include <QVector>
  6. 6
  7. 7 #include <string>
  8. 8 #include <QString>
  9. 9 #include <QStringList>
  10. 10 #include <QDebug>
  11. 11
  12. 12 #include <fstream>
  13. 13
  14. 14 using namespace std;
  15. 15
  16. 16 void ccmpFileRead::fileread(const char *ccmpFilename)
  17. 17 {
  18. 18 vector <string> vFileSets;
  19. 19 vector <string> pStrDesc;
  20. 20 vector<vector<float>> allSSTPixelNum1,allSSTPixelNum2,allSSTPixelNum3;
  21. 21
  22. 22
  23. 23 GDALAllRegister();
  24. 24 CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");//中文路径
  25. 25 GDALDataset* fileDataset = (GDALDataset*) GDALOpen(ccmpFilename,GA_ReadOnly);//打开HDF数据集
  26. 26 if (fileDataset == NULL)
  27. 27 {
  28. 28 return;
  29. 29 }
  30. 30
  31. 31 char** sublist = GDALGetMetadata((GDALDatasetH) fileDataset,"SUBDATASETS");//获得数据的字符串,可以打印出来看看自己需要的数据在那
  32. 32
  33. 33 int iCount = CSLCount(sublist);
  34. 34 if(iCount <= 0){
  35. 35 qDebug() << "该文件没有子数据" << endl;
  36. 36 GDALClose((GDALDriverH)fileDataset);
  37. 37 }
  38. 38
  39. 39 //存储数据集信息
  40. 40 for(int i = 0; sublist[i] != NULL;i++)
  41. 41 {
  42. 42
  43. 43 qDebug() << sublist[i] << endl;
  44. 44
  45. 45 if(i%2 != 0)
  46. 46 {
  47. 47 continue;
  48. 48 }
  49. 49
  50. 50 //三个数据集:uwnd vwnd wspd 只读取前两个数据集,第三个数据集是补充数据集
  51. 51
  52. 52 string tmpstr = sublist[i];
  53. 53 tmpstr = tmpstr.substr(tmpstr.find_first_of("=")+1);
  54. 54 const char *tmpc_str = tmpstr.c_str();
  55. 55
  56. 56 string tmpdsc = sublist[i+1];
  57. 57 tmpdsc = tmpdsc.substr(tmpdsc.find_first_of("=")+1);
  58. 58
  59. 59 GDALDataset* hTmpDt = (GDALDataset*)GDALOpen(tmpc_str,GA_ReadOnly);//打开该数据
  60. 60
  61. 61 if (hTmpDt != NULL)
  62. 62 {
  63. 63 vFileSets.push_back(tmpc_str);
  64. 64 }
  65. 65 if(&pStrDesc != NULL){
  66. 66 pStrDesc.push_back(tmpdsc);
  67. 67 }
  68. 68 GDALClose(hTmpDt);
  69. 69 }
  70. 70
  71. 71
  72. 72 //三个数据集分别读取
  73. 73
  74. 74 qDebug() << "read uwnd ......" << endl;
  75. 75
  76. 76 QString qtmpdsc1 = QString::fromStdString(pStrDesc[0]);//锁定某一个数据集
  77. 77
  78. 78 qDebug()<<qtmpdsc1<<endl;
  79. 79
  80. 80 float *lineData = NULL;
  81. 81 if (qtmpdsc1!=NULL)
  82. 82 {
  83. 83 GDALDataset *tempDt = (GDALDataset *)GDALOpen(vFileSets[0].data(), GA_ReadOnly);
  84. 84 int BandNum = tempDt->GetRasterCount();
  85. 85
  86. 86 int panBandmap[1] ={1};
  87. 87 lineData = new float[1 * 200*200];
  88. 88 tempDt->RasterIO(GF_Read,508,112,32,24,lineData,50,50,GDT_Float32,1,panBandmap,0,0,0);
  89. 89
  90. 90
  91. 91 for (int iLine = 0; iLine <tempDt->GetRasterYSize(); iLine++)
  92. 92 {
  93. 93 allSSTPixelNum1.resize(tempDt->GetRasterYSize());
  94. 94 for (int iPixel = 0; iPixel < tempDt->GetRasterXSize(); iPixel++)
  95. 95 {
  96. 96 allSSTPixelNum1[iLine].resize(tempDt->GetRasterXSize());
  97. 97 tempDt->RasterIO(GF_Read, 0, iLine, tempDt->GetRasterXSize(), 1,lineData, tempDt->GetRasterXSize(), 1, GDT_Float32, 1, panBandmap,0,0,0);
  98. 98 allSSTPixelNum1[iLine][iPixel] = lineData[iPixel];
  99. 99 }
  100. 100
  101. 101 }
  102. 102 if(lineData)
  103. 103 {
  104. 104 delete[]lineData;
  105. 105 lineData = NULL;
  106. 106 }
  107. 107
  108. 108 qDebug() << "uwnd read over!" << endl;
  109. 109
  110. 110 qDebug() <<"uwnd="<<'\n'<<allSSTPixelNum1[200]<<'\n'<<endl;
  111. 111
  112. 112 }
  113. 113
  114. 114 //d读取vwnd数据集
  115. 115
  116. 116 QString qtmpdsc2 = QString::fromStdString(pStrDesc[2]);
  117. 117
  118. 118 if (qtmpdsc2!=NULL)
  119. 119 {
  120. 120 GDALDataset *tempDt = (GDALDataset *)GDALOpen(vFileSets[0].data(), GA_ReadOnly);
  121. 121 int BandNum = tempDt->GetRasterCount();
  122. 122 qDebug()<<BandNum<<endl;
  123. 123 int panBandmap[1] ={1};
  124. 124 lineData = new float[1 * 200*200];
  125. 125 tempDt->RasterIO(GF_Read,508,112,32,24,lineData,50,50,GDT_Float32,1,panBandmap,0,0,0);
  126. 126
  127. 127
  128. 128 for (int iLine = 0; iLine <tempDt->GetRasterYSize(); iLine++)
  129. 129 {
  130. 130 allSSTPixelNum2.resize(tempDt->GetRasterYSize());
  131. 131 for (int iPixel = 0; iPixel < tempDt->GetRasterXSize(); iPixel++)
  132. 132 {
  133. 133 allSSTPixelNum2[iLine].resize(tempDt->GetRasterXSize());
  134. 134 tempDt->RasterIO(GF_Read, 0, iLine, tempDt->GetRasterXSize(), 1,lineData, tempDt->GetRasterXSize(), 1, GDT_Float32, 1, panBandmap,0,0,0);
  135. 135 allSSTPixelNum2[iLine][iPixel] = lineData[iPixel];
  136. 136 }
  137. 137
  138. 138 }
  139. 139 if(lineData)
  140. 140 {
  141. 141 delete[]lineData;
  142. 142 lineData = NULL;
  143. 143 }
  144. 144
  145. 145 qDebug() << "vwnd read over!" << endl;
  146. 146
  147. 147 qDebug() <<"vwnd="<<'\n'<<allSSTPixelNum2[200]<<'\n'<<endl;
  148. 148
  149. 149 }
  150. 150
  151. 151 //读取wspd数据
  152. 152
  153. 153 QString qtmpdsc3 = QString::fromStdString(pStrDesc[2]);
  154. 154
  155. 155 if (qtmpdsc3!=NULL)
  156. 156 {
  157. 157 GDALDataset *tempDt = (GDALDataset *)GDALOpen(vFileSets[0].data(), GA_ReadOnly);
  158. 158 int BandNum = tempDt->GetRasterCount();
  159. 159 qDebug()<<BandNum<<endl;
  160. 160 int panBandmap[1] ={1};
  161. 161 lineData = new float[1 * 200*200];
  162. 162 tempDt->RasterIO(GF_Read,508,112,32,24,lineData,50,50,GDT_Float32,1,panBandmap,0,0,0);
  163. 163
  164. 164
  165. 165 for (int iLine = 0; iLine <tempDt->GetRasterYSize(); iLine++)
  166. 166 {
  167. 167 allSSTPixelNum3.resize(tempDt->GetRasterYSize());
  168. 168 for (int iPixel = 0; iPixel < tempDt->GetRasterXSize(); iPixel++)
  169. 169 {
  170. 170 allSSTPixelNum3[iLine].resize(tempDt->GetRasterXSize());
  171. 171 tempDt->RasterIO(GF_Read, 0, iLine, tempDt->GetRasterXSize(), 1,lineData, tempDt->GetRasterXSize(), 1, GDT_Float32, 1, panBandmap,0,0,0);
  172. 172 allSSTPixelNum3[iLine][iPixel] = lineData[iPixel];
  173. 173 }
  174. 174
  175. 175 }
  176. 176
  177. 177 if(lineData)
  178. 178 {
  179. 179 delete[]lineData;
  180. 180 lineData = NULL;
  181. 181 }
  182. 182
  183. 183 qDebug() << "wspd read over!" << endl;
  184. 184
  185. 185 qDebug() <<"wspd="<<'\n'<<allSSTPixelNum3[200]<<'\n'<<endl;
  186. 186
  187. 187 GDALClose((GDALDatasetH)tempDt);
  188. 188
  189. 189 }
  190. 190
  191. 191 GDALClose((GDALDriverH)fileDataset);
  192. 192 }

主函数调用:

  1. 1 #include <QCoreApplication>
  2. 2 #include <ccmpfileread.h>
  3. 3 int main(int argc, char *argv[])
  4. 4 {
  5. 5 QCoreApplication a(argc, argv);
  6. 6 ccmpFileRead a1;
  7. 7 a1.fileread("E:/odp_workplace/odp_data/testdata/CCMP_Wind_Analysis_198707_V02.0_L3.5_RSS.nc");
  8. 8 return a.exec();
  9. 9 }

输出结果:

如上图所示数据已经读取并显示成功。

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号