/** * Copyright 2005-2007 ECMWF * * Licensed under the GNU Lesser General Public License which * incorporates the terms and conditions of version 3 of the GNU * General Public License. * See LICENSE and gpl-3.0.txt for details. */ /************************************** * Enrico Fucile **************************************/ #include "grib_api_internal.h" #include /* This is used by make_class.pl START_CLASS_DEF CLASS = iterator SUPER = grib_iterator_class_gen IMPLEMENTS = previous;next IMPLEMENTS = init;destroy MEMBERS = double *las MEMBERS = double *los MEMBERS = long nap MEMBERS = long nam MEMBERS = long iScansNegatively END_CLASS_DEF */ /* START_CLASS_IMP */ /* Don't edit anything between START_CLASS_IMP and END_CLASS_IMP Instead edit values between START_CLASS_DEF and END_CLASS_DEF or edit "iterator.class" and rerun ./make_class.pl */ static void init_class (grib_iterator_class*); static int init (grib_iterator* i,grib_handle*,grib_arguments*); static int next (grib_iterator* i, double *lat, double *lon, double *val); static int previous (grib_iterator* ei, double *lat, double *lon, double *val); static int destroy (grib_iterator* i); typedef struct grib_iterator_regular{ grib_iterator it; /* Members defined in gen */ long carg; const char* missingValue; /* Members defined in regular */ double *las; double *los; long nap; long nam; long iScansNegatively; } grib_iterator_regular; extern grib_iterator_class* grib_iterator_class_gen; static grib_iterator_class _grib_iterator_class_regular = { &grib_iterator_class_gen, /* super */ "regular", /* name */ sizeof(grib_iterator_regular),/* size of instance */ 0, /* inited */ &init_class, /* init_class */ &init, /* constructor */ &destroy, /* destructor */ &next, /* Next Value */ &previous, /* Previous Value */ 0, /* Reset the counter */ 0, /* has next values */ }; grib_iterator_class* grib_iterator_class_regular = &_grib_iterator_class_regular; static void init_class(grib_iterator_class* c) { c->reset = (*(c->super))->reset; c->has_next = (*(c->super))->has_next; } /* END_CLASS_IMP */ static int next(grib_iterator* i, double *lat, double *lon, double *val){ grib_iterator_regular* self = (grib_iterator_regular*)i; if((long)i->e >= (long)(i->nv-1)) return 0; i->e++; *lat = self->las[(long)floor(i->e/self->nap)]; *lon = self->los[(long)i->e%self->nap]; *val = i->data[i->e]; return 1; } static int previous(grib_iterator* i, double *lat, double *lon, double *val){ grib_iterator_regular* self = (grib_iterator_regular*)i; if(i->e < 0) return 0; *lat = self->las[(long)floor(i->e/self->nap)]; *lon = self->los[i->e%self->nap]; *val = i->data[i->e]; i->e--; return 1; } static int destroy(grib_iterator* i){ grib_iterator_regular* self = (grib_iterator_regular*)i; const grib_context *c = i->h->context; grib_context_free(c,self->las); grib_context_free(c,self->los); return GRIB_SUCCESS; } static int init(grib_iterator* i,grib_handle* h,grib_arguments* args) { grib_iterator_regular* self = (grib_iterator_regular*)i; int ret = GRIB_SUCCESS; long nap; long nam; double idir; double lof,lol; long loi; const char* longoffirst = grib_arguments_get_name(h,args,self->carg++); const char* idirec = grib_arguments_get_name(h,args,self->carg++); const char* nalpar = grib_arguments_get_name(h,args,self->carg++); const char* nalmer = grib_arguments_get_name(h,args,self->carg++); const char* iScansNegatively = grib_arguments_get_name(h,args,self->carg++); if((ret = grib_get_double_internal(h,longoffirst, &lof))) return ret; if((ret = grib_get_double_internal(h,"longitudeOfLastGridPointInDegrees", &lol))) return ret; if((ret = grib_get_double_internal(h,idirec, &idir))) return ret; if((ret = grib_get_long_internal(h,nalpar, &nap))) return ret; if((ret = grib_get_long_internal(h,nalmer, &nam))) return ret; if((ret = grib_get_long_internal(h,iScansNegatively,&self->iScansNegatively))) return ret; idir=fabs(lof-lol)/(nap-1); if (self->iScansNegatively) { idir=-idir; } else { if (lof+(nap-2)*idir>360) lof-=360; else if (lof+nap*idir>360) idir=360.0/(float)nap; } self->nap = nap; self->nam = nam; self->las = grib_context_malloc(h->context,nam*sizeof(double)); self->los = grib_context_malloc(h->context,nap*sizeof(double)); for( loi = 0; loi < nap; loi++ ) { self->los[loi] = lof; lof += idir ; } return ret; }