From 577b88c622e10010fc302f33b069cbac4e63c80e Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Fri, 23 Oct 2015 12:55:11 +0100 Subject: [PATCH] grib_util_set_spec2 --- src/grib_api.h | 56 +++++++++++++++++++++++++++++- src/grib_util.c | 92 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 131 insertions(+), 17 deletions(-) diff --git a/src/grib_api.h b/src/grib_api.h index a495b2317..be548d33d 100644 --- a/src/grib_api.h +++ b/src/grib_api.h @@ -1357,7 +1357,6 @@ typedef struct grib_util_grid_spec { long uvRelativeToGrid; double latitudeOfSouthernPoleInDegrees; double longitudeOfSouthernPoleInDegrees; - double angleOfRotationInDegrees; /* Scanning mode */ long iScansNegatively; @@ -1384,6 +1383,54 @@ typedef struct grib_util_grid_spec { } grib_util_grid_spec; +typedef struct grib_util_grid_spec2 { + + int grid_type; + const char* grid_name; /* e.g. N320 */ + + /* Grid */ + long Ni; + long Nj; + + double iDirectionIncrementInDegrees; + double jDirectionIncrementInDegrees; + + double longitudeOfFirstGridPointInDegrees; + double longitudeOfLastGridPointInDegrees; + + double latitudeOfFirstGridPointInDegrees; + double latitudeOfLastGridPointInDegrees; + + /* Rotation */ + long uvRelativeToGrid; + double latitudeOfSouthernPoleInDegrees; + double longitudeOfSouthernPoleInDegrees; + double angleOfRotationInDegrees; + + /* Scanning mode */ + long iScansNegatively; + long jScansPositively; + + /* Gaussian number */ + long N; + + /* bitmap */ + long bitmapPresent; + double missingValue; + + /* pl list for reduced */ + const long *pl; + long pl_size; + + /* Spherical harmonics */ + long truncation; + + /* polar stereographic */ + double orientationOfTheGridInDegrees; + long DyInMetres; + long DxInMetres; + +} grib_util_grid_spec2; #define GRIB_UTIL_PACKING_TYPE_SAME_AS_INPUT 0 #define GRIB_UTIL_PACKING_TYPE_SPECTRAL_COMPLEX 1 @@ -1437,6 +1484,13 @@ grib_handle *grib_util_set_spec(grib_handle *h, size_t data_values_count, int *err); +grib_handle *grib_util_set_spec2(grib_handle *h, + const grib_util_grid_spec2 *grid_spec, + const grib_util_packing_spec *packing_spec, /* NULL for defaults (same as input) */ + int flags, + const double *data_values, + size_t data_values_count, + int *err); /* --------------------------------------- */ diff --git a/src/grib_util.c b/src/grib_util.c index 016b3943c..42eb30635 100644 --- a/src/grib_util.c +++ b/src/grib_util.c @@ -330,7 +330,7 @@ static grib_trie* init_list(const char* name) { return 0; } -static void print_values(grib_context* c, const grib_util_grid_spec* spec, const double* data_values,size_t data_values_count,const grib_values *values,int count) +static void print_values(grib_context* c, const grib_util_grid_spec2* spec, const double* data_values,size_t data_values_count,const grib_values *values,int count) { int i; printf("ECCODES DEBUG grib_util grib_set_values: setting %d values \n",count); @@ -374,6 +374,56 @@ grib_handle* grib_util_set_spec(grib_handle* h, size_t data_values_count, int* err) { + /* Create a spec v2 from spec v1 */ + grib_util_grid_spec2 spec2; + Assert(h); + + spec2.grid_type=spec->grid_type; + spec2.Ni=spec->Ni; + spec2.Nj=spec->Nj; + spec2.iDirectionIncrementInDegrees=spec->iDirectionIncrementInDegrees; + spec2.jDirectionIncrementInDegrees=spec->jDirectionIncrementInDegrees; + spec2.longitudeOfFirstGridPointInDegrees=spec->longitudeOfFirstGridPointInDegrees; + spec2.longitudeOfLastGridPointInDegrees=spec->longitudeOfLastGridPointInDegrees; + spec2.latitudeOfFirstGridPointInDegrees=spec->latitudeOfFirstGridPointInDegrees; + spec2.latitudeOfLastGridPointInDegrees=spec->latitudeOfLastGridPointInDegrees; + spec2.uvRelativeToGrid=spec->uvRelativeToGrid; + spec2.latitudeOfSouthernPoleInDegrees=spec->latitudeOfSouthernPoleInDegrees; + spec2.longitudeOfSouthernPoleInDegrees=spec->longitudeOfSouthernPoleInDegrees; + spec2.iScansNegatively=spec->iScansNegatively; + spec2.jScansPositively=spec->jScansPositively; + spec2.N=spec->N; + spec2.bitmapPresent=spec->bitmapPresent; + spec2.missingValue=spec->missingValue; + spec2.pl=spec->pl; + spec2.pl_size=spec->pl_size; + spec2.truncation=spec->truncation; + spec2.orientationOfTheGridInDegrees=spec->orientationOfTheGridInDegrees; + spec2.DyInMetres=spec->DyInMetres; + spec2.DxInMetres=spec->DxInMetres; + + /* New data members of spec2 take default values */ + spec2.angleOfRotationInDegrees = 0; + spec2.grid_name= NULL; + + return grib_util_set_spec2( + h, + &spec2, + packing_spec, + flags, + data_values, + data_values_count, + err); +} + +grib_handle* grib_util_set_spec2(grib_handle* h, + const grib_util_grid_spec2 *spec, + const grib_util_packing_spec *packing_spec, + int flags, + const double* data_values, + size_t data_values_count, + int* err) +{ #define SET_LONG_VALUE(n,v) do { Assert(count<1024); values[count].name = n; values[count].type = GRIB_TYPE_LONG; values[count].long_value = v; count++; } while(0) #define SET_DOUBLE_VALUE(n,v) do { Assert(count<1024); values[count].name = n; values[count].type = GRIB_TYPE_DOUBLE; values[count].double_value = v; count++; } while(0) @@ -648,6 +698,15 @@ grib_handle* grib_util_set_spec(grib_handle* h, default : sprintf(name, "%s_pl_grib%ld", grid_type, editionNumber); } + + if (spec->pl && spec->grid_name) { + /* Cannot have BOTH pl and grid name specified */ + fprintf(stderr,"GRIB_UTIL_SET_SPEC: Cannot set BOTH pl and grid_name.\n"); + goto cleanup; + } + if (spec->grid_name) { + sprintf(name, "%s_grib%ld", spec->grid_name, editionNumber); + } } /* TODO: recycle tmp handle */ @@ -796,8 +855,6 @@ grib_handle* grib_util_set_spec(grib_handle* h, } /* Set rotation */ - /* FIXME: Missing angleOfRotationInDegrees */ - switch(spec->grid_type) { case GRIB_UTIL_GRID_SPEC_ROTATED_LL: case GRIB_UTIL_GRID_SPEC_ROTATED_GG: @@ -914,19 +971,8 @@ grib_handle* grib_util_set_spec(grib_handle* h, grib_handle_delete(tmp); Assert(*err == 0); - if (h->context->debug==-1) - print_values(h->context,spec,data_values,data_values_count,values,count); - - if((*err = grib_set_values(outh,values,count)) != 0) - { - fprintf(stderr,"SET_GRID_DATA_DESCRIPTION: Cannot set values %s\n",grib_get_error_message(*err)); - - for(i = 0; i < count; i++) - if(values[i].error) - fprintf(stderr," %s %s\n",values[i].name,grib_get_error_message(values[i].error)); - goto cleanup; - } - + /* Set "pl" array if provided (For reduced Gaussian grids) */ + /* See GRIB-857 */ Assert(spec->pl_size >= 0); if (spec->pl && spec->pl_size == 0) { fprintf(stderr, "pl array not NULL but pl_size == 0!\n"); @@ -939,6 +985,7 @@ grib_handle* grib_util_set_spec(grib_handle* h, if (spec->pl_size!=0 && (spec->grid_type==GRIB_UTIL_GRID_SPEC_REDUCED_GG || spec->grid_type==GRIB_UTIL_GRID_SPEC_REDUCED_ROTATED_GG)) { + Assert( spec->pl_size == 2 * spec->N ); *err=grib_set_long_array(outh,"pl",spec->pl,spec->pl_size); if (*err) { fprintf(stderr,"SET_GRID_DATA_DESCRIPTION: Cannot set pl %s\n",grib_get_error_message(*err)); @@ -946,6 +993,19 @@ grib_handle* grib_util_set_spec(grib_handle* h, } } + if (h->context->debug==-1) + print_values(h->context,spec,data_values,data_values_count,values,count); + + if((*err = grib_set_values(outh,values,count)) != 0) + { + fprintf(stderr,"SET_GRID_DATA_DESCRIPTION: Cannot set values %s\n",grib_get_error_message(*err)); + + for(i = 0; i < count; i++) + if(values[i].error) + fprintf(stderr," %s %s\n",values[i].name,grib_get_error_message(values[i].error)); + goto cleanup; + } + if((*err = grib_set_double_array(outh,"values",data_values,data_values_count)) != 0) { FILE* ferror;