目标尽可能地少解码。永远不要解码整个已加载的 GRIB 消息。可以使用 grib_dump -D <grib_file>
查看到底有多少个 ecCodes key。
用于解码的主要函数:
int codes_get_long (codes_handle *h, const char *key, long *value);
int codes_get_double (codes_handle *h, const char *key, double *value)
int codes_get_string (codes_handle *h, const char *key, char *mesg, size_t *length)
int codes_get_long_array (codes_handle *h, const char *key, long *vals, size_t *length)
int codes_get_double_array (codes_handle *h, const char *key, double *vals, size_t *length)
获取一个(数组)数据的大小:
int codes_get_size(codes_handle* h, const char* key,size_t *size);
int grib_get_size(grib_handle* h, const char* key,size_t *size);
详细输出 grib 消息的内容:
void codes_dump_content(codes_handle* h,FILE* out,const char* mode, unsigned long option_flags,void* arg);
void grib_dump_content(grib_handle* h,FILE* out,const char* mode, unsigned long option_flags,void* arg);
检查某个 key 是否被定义(存在):
int codes_is_defined(codes_handle* h, const char* key);
int grib_is_defined(grib_handle* h, const char* key);
检查某个 key 的值是否是缺失值:
int codes_is_missing(codes_handle* h, const char* key, int* err);
int grib_is_missing(grib_handle* h, const char* key, int* err);
统计文件中的消息个数:
int codes_count_in_file(codes_context* c, FILE* f,int* n);
int grib_count_in_file(grib_context* c, FILE* f,int* n);
#include <iostream>
#include <eccodes.h>
using namespace std;
int main(int argc, char** argv)
{
if(argc < 2)
{
cout<<"Usage: "<<argv[0]<<" grib_file_path";
return 1;
}
const char* file_path = argv[1];
FILE* in = fopen(file_path, "rb");
if(!in)
{
cout<<"ERROR: unable to open file "<<file_path<<endl;
return 1;
}
int err = 0;
codes_handle *h = nullptr;
while((h=codes_handle_new_from_file(nullptr, in, PRODUCT_GRIB, &err)) != nullptr)
{
long data_date = -1;
codes_get_long(h, "dataDate", &data_date);
long type_of_level = -1;
codes_get_long(h, "typeOfLevel", &type_of_level);
long level = -1;
codes_get_long(h, "level", &level);
size_t size;
codes_get_size(h, "values", &size);
double *values = new double[size];
codes_get_double_array(h, "values", values, &size);
cout<<data_date<<" "<<type_of_level<<" "<<level<<" "<<size<<" "<<values[size-1]<<endl;
delete [] values;
codes_handle_delete(h);
}
fclose(in);
return 0;
}
将上面的代码替换为以 grib_
开头的函数
#include <iostream>
#include <grib_api.h>
using namespace std;
int main(int argc, char** argv)
{
if(argc < 2)
{
cout<<"Usage: "<<argv[0]<<" grib_file_path";
return 1;
}
const char* file_path = argv[1];
FILE* in = fopen(file_path, "rb");
if(!in)
{
cout<<"ERROR: unable to open file "<<file_path<<endl;
return 1;
}
int err = 0;
grib_handle *h = nullptr;
while((h=grib_handle_new_from_file(nullptr, in, &err)) != nullptr)
{
long data_date = -1;
grib_get_long(h, "dataDate", &data_date);
long type_of_level = -1;
grib_get_long(h, "typeOfLevel", &type_of_level);
long level = -1;
grib_get_long(h, "level", &level);
size_t size;
grib_get_size(h, "values", &size);
double *values = new double[size];
grib_get_double_array(h, "values", values, &size);
cout<<data_date<<" "<<type_of_level<<" "<<level<<" "<<size<<" "<<values[size-1]<<endl;
delete [] values;
grib_handle_delete(h);
}
fclose(in);
return 0;
}
ecCodes 的宗旨是提供高层次的 key 集合和不同的函数,用于检索或计算已加载 GRIB 消息中的额外信息。
对于不同的应用:
codes_get_data
codes_grib_nearest_find
codes_get_double_elements