GRIB API学习笔记05——GRIB APIs 第一部分

目录

参见3A1-grib_api_1.pdf

1.1.  介绍

首先考虑是否真的需要写程序?
GRIB命令行工具是否能完成任务
在气象模式和某些后处理中需要编解码GRIB数据
写程序比试着获取工具或脚本更有效率

1.2.  GRIB API库

使用ANSI C 99编写,只需要jasper库用与jpeg2000的编解码(windroc注:openjpeg也可以),编译时使用—disable-jpeg将不使用jpeg库。

1.3.  Fortran 90接口

参看第二章

1.4.  从GRIBEX迁移到GRIB API

略过

1.5.  C接口

1.5.1.   特点

头文件 #include “grib_api.h”
export GRIB_API_VERSION=1.9.16
编译:
IBM:
xlc myprogram.c $GRIB_API_INCLUDE $GRIB_API_LIB –lm
Linux:
[gcc|pgcc] myprogram.c $GRIB_API_INCLUDE $GRIB_API_LIB –lm
主要不同点:
C接口更精确,例如指定类型的函数,如grib_get_double()
没有一些辅助函数,如grib_open_file()

1.5.2.   错误检查

GRIB_CHECK为GRIB API函数的内置错误检查。
[cpp]GRIB_CHECK(grib_get_long(h,”Ni”,&Ni),0);[/cpp]
或者将错误码作为函数参数:
[cpp]
h = grib_handle_new_from_file(0,in,&err);
GRIB_CHECK(err,0);
[/cpp]
也可以手动检查状态:
[cpp]
err = grib_get_long(h,”Ni”,&Ni);
if (err != 0) {
printf(“Error: %s \n unable to get long variable\n”,grib_get_error_message(err));
exit(1); }
[/cpp]

1.5.3.   加载/释放GRIB消息

grib_handle *h;
提供访问解析过的grib数值的结构体

grib_handle* grib_handle_new_from_file(grib_context *c, FILE *fp, int *error)

从文件创建句柄

需要在之前打开文件

fp=fopen(filename,”r”)

在程序结束时释放文件指针

       fclose(fp)

grib_context *c 通常被设为0

grib_handle * grib_handle_new_from_…

samples (grib_context *c, const char *res_name)

来自样本文件

message (grib_context *c, void *data, size_t length)

来自内存
grib_handle_delete(h);
释放句柄

1.5.4.   解码

int grib_get_double(grib_handle *h, const char *key, double *value)
获取key的双精度值。如果多个key有相同的名字,返回最后一个。长整形long也有类似的函数。

int grib_get_string(grib_handle *h, const char *key, char *message, size_t *length)

返回一个key的字符串string值,如果多个key有相同的名字,返回最后一个。字符串保存在预先申请的长度为length的内存空间中。

字节类型byte也有类似的函数。

int grib_get_double_array(grib_handle *h, const char *key, double *values, size_t *length)

返回key的双精度数组

使用int grib_get_size(grib_handle *h, const char *key, size_t *length) 区获取某个key中编码的数据的个数(长度)。

长整形数组(long array)也有类似的函数。

int grib_nearest_find(grib_nearest * nearest, grib_handle * h, double inlat, double inlon, unsigned long flags, double * outlats, double * outlons, double * values, double * distances, int * indexes, size_t * len)

寻找给定经纬度点的4个最近邻点和他们的距离。

flags应该被设为0或者是以下值:

GRIB_NEAREST_SAME_POINT

GRIB_NEAREST_SAME_GRID

outlats, outlons, values, distances和indexes需要事先申请空间,并且d len应该设为4

1.6.  Python接口

1.6.1.   特点

使用import gribapi加载

我在Fedora 19中安装grib api库,python接口安装到

/usr/local/lib64/python2.7/site-packages/grib_api

但python只搜索

/usr/lib/python2.7/site-packages

找不到gribapi模块。需要将第一个目录加到python搜索目录中。可以使用.pth文件,在/usr/lib/python2.7/site-packages中添加grib_api.pth文件,内容为grib api的python接口位置:

/usr/local/lib64/python2.7/site-packages/grib_api

就可以找到gribapi模块了。

下面给出的代码前省略模块gribapi,实际使用需要加上,或者使用

from gribapi import *

导入相关函数

低层,函数式
提供大部分C函数的对应函数
使用NumPy模块操控数据

1.6.2.   加载/释放GRIB消息

gid = grib_new_from_file(file, headers_only=False)

返回文件中GRIB消息的句柄
要求输入文件为python文件对象
目前不推荐使用headers_only选项

gid = grib_new_from_samples(samplename)

返回示例目录下的消息句柄

gid = grib_new_from_message(message)

返回内存中消息的句柄

grib_release(gid)

释放句柄

1.6.3.   解码

value = grib_get(gid, key, type=None)

按原始格式返回gid所指向的消息中key的值。
或者,使用type关键字选择返回值的格式(int,str或float)
values = grib_get_array(gid, key, type=None)

返回数组key的内容,格式为NumPy的ndarray或python数组,类型type只可以为int或float

values = grib_get_values(gid)

返回数值的一维数组
values = grib_get_elements(gid, key, indexes)
获取指定key的特定元素列表?
Retrieve the elements of the key array for the indexes specified in the input.
出错时,抛出异常GribInternalError(封装C API的错误)

1.6.4.   实用工具

[outlat, outlon, value, distance, index] = grib_find_nearest(gid, inlat, inlon, is_lsm=False, npoints=1)

寻找指定经纬度最近的点

npoints=4时,返回4个最近的点。

iter_id = grib_iterator_new(gid,mode)

[lat,lon,value] = grib_iterator_next(iterid)

grib_iterator_delete(iter_id)

1.7.  参考

GRIB-1, GRIB-2:
<//www.wmo.int/pages/prog/www/WMOCodes.html>
GRIB API:
https://software.ecmwf.int/wiki/display/GRIB/GRIB+API/
GRIB API Fortran, C or Python interfaces:
f90: https://software.ecmwf.int/wiki/display/GRIB/Fortran+package+grib_api
C: https://software.ecmwf.int/wiki/display/GRIB/Module+Index
Python: https://software.ecmwf.int/wiki/display/GRIB/Python+package+gribapi
GRIB API examples:
https://software.ecmwf.int/wiki/display/GRIB/Grib+API+examples
GRIBEX – GRIB API conversion
https://software.ecmwf.int/wiki/display/GRIB/GRIBEX+keys