Support for legacy GRIB2 encoded with discipline=192

This commit is contained in:
Shahram Najm 2019-01-08 13:41:41 +00:00
parent 9a6059ca9d
commit a977fec79c
1 changed files with 103 additions and 15 deletions

View File

@ -160,17 +160,10 @@ static void dump(grib_accessor* a, grib_dumper* dumper)
static int concept_condition_expression_true(grib_handle* h,grib_concept_condition* c) {
long lval;
double dval;
long lres=0;
double dres=0.0;
const char *cval;
char buf[80];
char tmp[80];
size_t len = sizeof(buf);
size_t size=sizeof(tmp);
int ok = 0;
int err=0;
int type = grib_expression_native_type(h,c->expression);
const int type = grib_expression_native_type(h,c->expression);
switch(type)
{
@ -180,17 +173,27 @@ static int concept_condition_expression_true(grib_handle* h,grib_concept_conditi
(lval == lres);
break;
case GRIB_TYPE_DOUBLE:
case GRIB_TYPE_DOUBLE: {
double dval;
double dres=0.0;
grib_expression_evaluate_double(h,c->expression,&dres);
ok = (grib_get_double(h,c->name,&dval) == GRIB_SUCCESS) &&
(dval == dres);
break;
}
case GRIB_TYPE_STRING: {
const char *cval;
char buf[80];
char tmp[80];
size_t len = sizeof(buf);
size_t size=sizeof(tmp);
case GRIB_TYPE_STRING:
ok = (grib_get_string(h,c->name,buf,&len) == GRIB_SUCCESS) &&
((cval = grib_expression_evaluate_string(h,c->expression,tmp,&size,&err)) != NULL) &&
(err==0) && (grib_inline_strcmp(buf,cval) == 0);
break;
}
default:
/* TODO: */
@ -425,14 +428,53 @@ static int unpack_double(grib_accessor* a, double* val, size_t *len)
return ret;
}
static long guess_paramId(grib_handle* h)
{
int err = 0;
long discipline, category, number;
err=grib_get_long(h,"discipline",&discipline);
if (err || discipline != 192)
return -1;
err=grib_get_long(h,"parameterCategory",&category);
if (err) return -1;
err=grib_get_long(h,"parameterNumber",&number);
if (err) return -1;
if (category==128) return number;
else return (category * 1000 + number);
}
/* Return -1 if cannot match */
static long get_ECMWF_local_paramId(grib_accessor* a, grib_handle* h)
{
int err = 0;
long edition, centre;
if (h->product_kind != PRODUCT_GRIB)
return -1;
err=grib_get_long(h,"centre",&centre);
if (err) return -1;
err=grib_get_long(h,"edition",&edition);
if (err) return -1;
if (edition==2 && centre==98 && strncmp(a->name,"paramId",7)==0) {
return guess_paramId(h);
}
return -1;
}
static int unpack_long(grib_accessor* a, long* val, size_t *len)
{
/* TODO properly calling concept_evaluate_long ! */
const char *p = concept_evaluate(a);
if(!p) {
grib_handle* h = grib_handle_of_accessor(a);
long pid = get_ECMWF_local_paramId(a, h);
if (pid != -1) {
*val = pid;
*len = 1;
return GRIB_SUCCESS;
}
if (a->creator->defaultkey)
return grib_get_long_internal(grib_handle_of_accessor(a),a->creator->defaultkey,val);
return grib_get_long_internal(h,a->creator->defaultkey,val);
return GRIB_NOT_FOUND;
}
@ -460,16 +502,62 @@ static void destroy(grib_context* c,grib_accessor* a)
*/
}
static int is_local_ecmwf_grib2_param_key(grib_accessor* a, long edition, long centre)
{
if (edition==2 && centre==98) {
if (a->parent->owner && a->parent->owner->name && strcmp(a->parent->owner->name,"parameters")==0)
return 1;
}
return 0;
}
/* Try to get the name, shortName, units etc for a GRIB2 message with
* local ECMWF coding i.e. discipline=192 etc
*/
static const char* get_ECMWF_local_parameter(grib_accessor* a, grib_handle* h)
{
int err = 0;
const char* key_name = a->name; /*this is the key whose value we want*/
long edition, centre;
if (h->product_kind != PRODUCT_GRIB)
return NULL;
err=grib_get_long(h,"centre",&centre);
if (err) return NULL;
err=grib_get_long(h,"edition",&edition);
if (err) return NULL;
if (is_local_ecmwf_grib2_param_key(a,edition,centre)) {
/* Must be one of: 'name', 'shortName', 'units', 'cfName' etc */
grib_accessor* a2 = NULL;
long pid_guess = guess_paramId(h);
if (pid_guess == -1) return NULL;
/* Change the paramId so we can get the other string key*/
err = grib_set_long(h, "paramId", pid_guess);
if (err) return NULL;
/* Get the string value of key. Do not call grib_get_string() to avoid
* dangers of infinite recursion as that calls unpack_string()!
*/
a2 = grib_find_accessor(h, key_name);
if (!a2) return NULL;
return concept_evaluate(a2);
}
return NULL;
}
static int unpack_string (grib_accessor* a, char* val, size_t *len)
{
size_t slen ;
const char *p = concept_evaluate(a);
if(!p) {
if (a->creator->defaultkey)
return grib_get_string_internal(grib_handle_of_accessor(a),a->creator->defaultkey,val,len);
grib_handle* h = grib_handle_of_accessor(a);
p = get_ECMWF_local_parameter(a, h);
if (!p) {
if (a->creator->defaultkey)
return grib_get_string_internal(h,a->creator->defaultkey,val,len);
return GRIB_NOT_FOUND;
return GRIB_NOT_FOUND;
}
}
slen = strlen(p) +1;