grib中数据读取并导出到文本文件中
grib中数据读取并导出到文本文件中
零、一些废话
最近忙着赶项目加上家里的事比较多,就没有来得及更新博客,今天主要讲解一下grib数据的查看方法和读取方法。grib数据没有找到好的可视化工具打开它,官网提供的一个可视化工具叫Metview,此工具的安装过程相当的复杂,搞了将近3个小时最后还是没有安装成功,由于项目比较紧就果断的先放弃啦。这种方法不行,还可以使用ecCodes提供的自带命令行方式把grib数据中的一条一条的消息导出到一个.txt文件中,然后使用notepad++查找需要的字段,这种方法笨一点但是却很好使。特别提示千万不要使用打开nc文件的工具panoply去打开grib文件找到相应的字段去读取,你会发现你一直读出不对的,因为该工具会自动处理grib中的消息字段,你看到的并不是真正的grib数据中的字段。当然,除非你把grib转化成nc格式的文件去读。
一、官网提供的命令行方法
方法链接:https://confluence.ecmwf.int/display/ECC/GRIB+tools ,截图如下:
上图中划线部分是方法所在的列表以及一个把grib数据导出到txt文件中的方法。
二、把grib数据导出到txt文件工具grib_dump
不知道怎么安装ecCodes请参考我的这篇博客:https://blog.csdn.net/toby54king/article/details/81592080
使用方法看下面截图:
第一步是要找到你编译后的工具所在的目录(一般在eccodes-2.8.0-Source/build/bin
),然后按照图中的操作即可,工具中其他命令请自行了解一下,grib_dump这个命令对于我们完成数据解析已经够啦。
三、查找所需要的字段
由于这种方法比较笨,你只能模糊查找部分字段去找到你需要的字段信息,建议你从搜索“name”开始查找,等你多差几次就能找到一些规律了,规律自己领悟吧。下面是截取的一条消息,消息中的可能用到的部分我加了注释讲解,其他内容自己学习吧:
#============== MESSAGE 1128 ( length=68024 ) ==============
GRIB {
editionNumber = 1;
table2Version = 128;
# European Centre for Medium-Range Weather Forecasts (common/c-1.table)
centre = 98;
generatingProcessIdentifier = 148;
# 10 metre U wind component (m s**-1) (grib1/2.98.128.table)
indicatorOfParameter = 165;
# Surface (of the Earth, which includes sea surface) (grib1/local/ecmf/3.table , grib1/3.table)
indicatorOfTypeOfLevel = 1;
level = 0;
# Forecast product valid at reference time + P1 (P1>0) (grib1/local/ecmf/5.table , grib1/5.table)
timeRangeIndicator = 0;
# Unknown code table entry (grib1/0.ecmf.table)
subCentre = 0;
paramId = 165;
#-READ ONLY- cfNameECMF = unknown;
#-READ ONLY- cfName = unknown;
#-READ ONLY- cfVarNameECMF = u10;
#-READ ONLY- cfVarName = u10;
#-READ ONLY- units = m s**-1;
#-READ ONLY- nameECMF = 10 metre U wind component; // 1、可能需要的字段名字
#-READ ONLY- name = 10 metre U wind component;
decimalScaleFactor = 0;
dataDate = 20170720; // 2、时间
dataTime = 0;
# Hour (stepUnits.table)
stepUnits = 1;
stepRange = 60;
startStep = 60;
endStep = 60;
#-READ ONLY- marsParam = 165.128;
# Forecasting Systems with Variable Resolution (grib1/localDefinitionNumber.98.table)
localDefinitionNumber = 30;
# Operational archive (mars/class.table)
marsClass = 1;
# Perturbed forecast (mars/type.table)
marsType = 11;
# Ensemble prediction system (mars/stream.table)
marsStream = 1035;
experimentVersionNumber = 0001;
perturbationNumber = 46;
numberOfForecastsInEnsemble = 51;
oceanAtmosphereCoupling = 2;
legBaseDate = 20170720;
legBaseTime = 0;
legNumber = 1;
referenceDate = 0;
climateDateFrom = 0;
climateDateTo = 0;
shortName = 10u;
GDSPresent = 1;
bitmapPresent = 0;
numberOfVerticalCoordinateValues = 0;
Ni = 281; // 3、经纬度行列号
Nj = 161;
latitudeOfFirstGridPointInDegrees = 70; // 4、经纬度起始结束数值
longitudeOfFirstGridPointInDegrees = 40;
earthIsOblate = 0;
uvRelativeToGrid = 0;
latitudeOfLastGridPointInDegrees = -10;
longitudeOfLastGridPointInDegrees = 180;
iScansNegatively = 0;
jScansPositively = 0;
jPointsAreConsecutive = 0;
#-READ ONLY- alternativeRowScanning = 0;
jDirectionIncrementInDegrees = 0.5; // 5、经纬度步长间隔
iDirectionIncrementInDegrees = 0.5;
#-READ ONLY- numberOfDataPoints = 45241;
#-READ ONLY- numberOfValues = 45241;
missingValue = 9999; // 6、无效值
#-READ ONLY- binaryScaleFactor = -6;
#-READ ONLY- referenceValue = -21.7665;
sphericalHarmonics = 0;
complexPacking = 0;
integerPointValues = 0;
additionalFlagPresent = 0;
packingType = grid_simple;
bitsPerValue = 12;
values(45241) = { // 7、显示出的部分数值
-5.04773, -5.12585, -5.0946, -5.14148, -5.11023,
-5.01648, -5.0946, -5.31335, -5.29773, -5.18835,
-5.23523, -5.32898, -5.2196, -4.9696, -4.8446,
-4.68835, -4.32898, -3.89148, -3.5321, -3.04773,
-2.23523, -1.54773, -1.43835, -1.5321, -1.42273,
-1.42273, -2.0321, -2.76648, -3.26648, -3.68835,
-4.18835, -4.42273, -4.4071, -4.43835, -4.2196,
-3.42273, -2.7196, -2.87585, -3.57898, -3.8446,
-3.76648, -3.17273, -2.98523, -2.70398, -2.31335,
-1.81335, -1.36023, -1.17273, -0.891479, -0.313354,
0.405396, 1.06165, 1.76477, 2.42102, 2.92102,
3.2179, 3.4679, 3.4054, 2.62415, 2.45227,
2.87415, 2.9054, 1.42102, -0.907104, -1.92273,
-2.11023, -0.985229, 0.0147705, 0.546021, 0.467896,
0.749146, 1.2804, 1.49915, 0.655396, 0.374146,
1.01477, 1.4054, 1.20227, 0.842896, 1.56165,
1.63977, 0.921021, 0.186646, 0.171021, 0.796021,
1.13977, 1.12415, 0.952271, 0.905396, 1.23352,
1.43665, 1.1554, 1.29602, 2.01477, 2.92102,
2.9679, 2.4054, 2.26477, 2.3429, 2.62415
... 45141 more values
}
#-READ ONLY- numberOfCodedValues = 45241;
#-READ ONLY- maximum = 17.4366;
#-READ ONLY- minimum = -21.7665;
#-READ ONLY- average = -0.531135;
#-READ ONLY- numberOfMissing = 0;
#-READ ONLY- standardDeviation = 4.24001;
#-READ ONLY- skewness = -0.0364773;
#-READ ONLY- kurtosis = 0.156673;
#-READ ONLY- isConstant = 0;
gridType = regular_ll;
#-READ ONLY- getNumberOfValues = 45241;
}
四、数据字段的读取
主要用到的函数如下,代码自己组织学习吧:
1、grib-api中是一个全局静态变量static grib_context default_grib_context
2、打开文件函数FILE* file = fopen(fileName,“r”)
3、获取文件内含有的grib message个数函数:grib_count_in_file
4、获得经纬度、步长、行列号等用到的函数grib_get_double、grib_get_long
5、获取数据的值用到的函数grib_get_size、grib_get_double_array
特别提醒:经纬度的计算需要根据起始经纬度、终止经纬度、经纬度间隔值、经纬度的步长去计算才行,
每种要素的经纬度范围都是不一样的。如果起始经纬度大于终止纬度减去间隔,反之,加上间隔。
说明:自己对ecodes库了解并不是特别深入,如有错误欢迎指正。