static int location(grib_handle* h,int n,double *lat,double* lon) { int err=0; grib_iterator* iter = grib_iterator_new(h,0,&err); int i = 0; double val; if(!iter) return 0; while(grib_iterator_next(iter,lat,lon,&val)) { if(i++ == n) { grib_iterator_delete(iter); return 1; } } grib_iterator_delete(iter); return 0; }
static int unpack_double (grib_accessor* a, double* val, size_t *len) { grib_context* c=a->context; int ret = 0; double* v=val; double lat,lon,value; size_t size=0; long count=0; grib_iterator* iter=grib_iterator_new(grib_handle_of_accessor(a),0,&ret); if (ret!=GRIB_SUCCESS) { if (iter) grib_iterator_delete(iter); grib_context_log(c,GRIB_LOG_ERROR,"unable to create iterator"); return ret; } size=0; ret=value_count(a,&count); if (ret) return ret; size=count; if (*len<size) { if (iter) grib_iterator_delete(iter); return GRIB_ARRAY_TOO_SMALL; } while(grib_iterator_next(iter,&lat,&lon,&value)) { *(v++)=lat;*(v++)=lon;*(v++)=value; } grib_iterator_delete(iter); *len=size; return ret; }
static int get_distinct(grib_accessor* a,double** val,long* len) { long count=0; double prev; double *v=NULL; double *v1=NULL; double dummy; int ret=0; int i; size_t size=*len; grib_context* c=a->parent->h->context; grib_iterator* iter=grib_iterator_new(a->parent->h,0,&ret); if (ret!=GRIB_SUCCESS) { if (iter) grib_iterator_delete(iter); grib_context_log(c,GRIB_LOG_ERROR,"unable to create iterator"); return ret; } v=(double*)grib_context_malloc_clear(c,size*sizeof(double)); if (!v) { grib_context_log(c,GRIB_LOG_ERROR, "unable to allocate %ld bytes",(long)size*sizeof(double)); return GRIB_OUT_OF_MEMORY; } *val=v; while(grib_iterator_next(iter,v++,&dummy,&dummy)) {} grib_iterator_delete(iter); v=*val; qsort(v,*len,sizeof(double),&compare_doubles); v1=(double*)grib_context_malloc_clear(c,size*sizeof(double)); if (!v1) { grib_context_log(c,GRIB_LOG_ERROR, "unable to allocate %ld bytes",(long)size*sizeof(double)); return GRIB_OUT_OF_MEMORY; } prev=v[0]; v1[0]=prev; count=1; for (i=1;i<*len;i++) { if (v[i]!=prev) { prev=v[i]; v1[count]=prev; count++; } } grib_context_free(c,v); *val=v1; *len=count; return GRIB_SUCCESS; }
int grib_get_data(grib_handle* h,double* lats, double* lons,double* values) { int err=0; grib_iterator* iter=NULL; double *lat,*lon,*val; iter=grib_iterator_new(h,0,&err); if (!iter || err!=GRIB_SUCCESS) return err; lat=lats; lon=lons; val=values; while(grib_iterator_next(iter,lat++,lon++,val++)) {} grib_iterator_delete( iter); return err; }
static int unpack_double (grib_accessor* a, double* val, size_t *len) { grib_context* c=a->parent->h->context; grib_accessor_latitudes* self = (grib_accessor_latitudes*)a; int ret = 0; double* v=val; double dummy=0; size_t size=0; grib_iterator* iter=NULL; self->save=1; size=value_count(a); if (*len<size) return GRIB_ARRAY_TOO_SMALL; self->save=0; /* self->lats are computed in _value_count*/ if (self->lats) { int i; *len=self->size; for (i=0;i<size;i++) val[i]=self->lats[i]; grib_context_free(c,self->lats); self->lats=NULL; self->size=0; return GRIB_SUCCESS; } iter=grib_iterator_new(a->parent->h,0,&ret); if (ret!=GRIB_SUCCESS) { if (iter) grib_iterator_delete(iter); grib_context_log(c,GRIB_LOG_ERROR,"unable to create iterator"); return ret; } while(grib_iterator_next(iter,v++,&dummy,&dummy)) {} grib_iterator_delete(iter); *len=size; return ret; }
void InputGrib::getLocationsCore(std::vector<Location>& iLocations) const { #ifdef WITH_GRIB std::string filename = getLocationFilename(); FILE* fid = fopen(filename.c_str(),"r"); if(!fid) { Global::logger->write("No sample file available for Grib", Logger::error); } else { int err = 0; grib_handle* h = grib_handle_new_from_file(0,fid,&err); if (h == NULL) { std::stringstream ss; ss << "Unable to create handle from file " << filename; Global::logger->write(ss.str(),Logger::error); } // Iterate over all locations grib_iterator* iter=grib_iterator_new(h,0,&err); if (err != GRIB_SUCCESS) GRIB_CHECK(err,0); int id = 0; double lat, lon; double value; while(grib_iterator_next(iter,&lat,&lon,&value)) { float elev = 0;//elevs[i]; assert(lat <= 90 && lat >= -90); Location loc(getName(), id, lat, lon); loc.setElev(elev); iLocations.push_back(loc); id++; } grib_iterator_delete(iter); grib_handle_delete(h); } fclose(fid); #else Global::logger->write("InputGrib: Program not compiled with GRIB", Logger::error); #endif }
grib_iterator* codes_grib_iterator_new(grib_handle* h, unsigned long flags,int* error) { return grib_iterator_new(h,flags,error); }
static int 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) { grib_nearest_latlon_reduced* self = (grib_nearest_latlon_reduced*) nearest; int ret=0,kk=0,ii=0,jj=0; int j=0; long* pla=NULL; long* pl=NULL; size_t nvalues=0; grib_iterator* iter=NULL; double lat=0,lon=0; long iradius; double radius; int ilat=0,ilon=0; if( (ret = grib_get_size(h,self->values_key,&nvalues))!= GRIB_SUCCESS) return ret; nearest->values_count = nvalues; if (grib_is_missing(h,self->radius,&ret)) { grib_context_log(h->context, GRIB_LOG_DEBUG,"Key '%s' is missing", self->radius); return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; } if( (ret = grib_get_long(h,self->radius,&iradius))!= GRIB_SUCCESS) return ret; radius=((double)iradius)/1000.0; if (!nearest->h || (flags & GRIB_NEAREST_SAME_GRID)==0) { double dummy=0; double olat=1.e10; long n=0; ilat=0,ilon=0; if (grib_is_missing(h,self->Nj,&ret)) { grib_context_log(h->context, GRIB_LOG_DEBUG,"Key '%s' is missing", self->Nj); return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; } if( (ret = grib_get_long(h,self->Nj,&n))!= GRIB_SUCCESS) return ret; self->lats_count=n; if (self->lats) grib_context_free(nearest->context,self->lats); self->lats=(double*)grib_context_malloc( nearest->context, self->lats_count* sizeof(double)); if (!self->lats) return GRIB_OUT_OF_MEMORY; if (self->lons) grib_context_free(nearest->context,self->lons); self->lons=(double*)grib_context_malloc( nearest->context, nearest->values_count*sizeof(double)); if (!self->lons) return GRIB_OUT_OF_MEMORY; iter=grib_iterator_new(h,0,&ret); if (ret) { grib_context_log(h->context,GRIB_LOG_ERROR,"unable to create iterator"); return ret; } while(grib_iterator_next(iter,&lat,&lon,&dummy)) { if (olat!=lat) { self->lats[ilat++]=lat; olat=lat; } self->lons[ilon++]=lon; } self->lats_count=ilat; grib_iterator_delete(iter); } nearest->h=h; if (!self->distances || (flags & GRIB_NEAREST_SAME_POINT)==0 || (flags & GRIB_NEAREST_SAME_GRID)==0) { double* lons=NULL; int nlon=0; size_t plsize=0; long nplm1=0; int nearest_lons_found=0; double lon_first,lon_last; int islocal=0; long plmax; double dimin; if ((ret=grib_get_double(h,self->lonFirst,&lon_first))!=GRIB_SUCCESS) { grib_context_log(h->context,GRIB_LOG_ERROR, "grib_nearest_latlon_reduced.find(): unable to get %s %s\n",self->lonFirst, grib_get_error_message(ret)); return ret; } if ((ret=grib_get_double(h,self->lonLast,&lon_last))!=GRIB_SUCCESS) { grib_context_log(h->context,GRIB_LOG_ERROR, "grib_nearest_latlon_reduced.find(): unable to get %s %s\n",self->lonLast, grib_get_error_message(ret)); return ret; } plsize=self->lats_count; if( (ret=grib_get_size(h,self->pl,&plsize))!= GRIB_SUCCESS) return ret; pla=(long*)grib_context_malloc(h->context,plsize*sizeof(long)); if (!pla) return GRIB_OUT_OF_MEMORY; if( (ret=grib_get_long_array(h,self->pl,pla,&plsize))!= GRIB_SUCCESS) return ret; pl=pla; while ((*pl)==0) {pl++;} plmax=pla[0]; for (j=0;j<plsize;j++) if (plmax<pla[j]) plmax=pla[j]; dimin=360.0/plmax; if ( 360-fabs(lon_last-lon_first) < 2 * dimin ) {islocal=0;} else {islocal=1;} if (islocal) for (j=0;j<plsize;j++) pla[j]--; /* printf("XXXX islocal=%d\n",islocal); */ while (inlon<0) inlon+=360; while (inlon>360) inlon-=360; ilat=self->lats_count; if (self->lats[ilat-1] > self->lats[0]) { if (inlat < self->lats[0] || inlat > self->lats[ilat-1]) return GRIB_OUT_OF_AREA; } else { if (inlat > self->lats[0] || inlat < self->lats[ilat-1]) return GRIB_OUT_OF_AREA; } if (!self->distances) self->distances=(double*)grib_context_malloc( nearest->context,4*sizeof(double)); if (!self->distances) return GRIB_OUT_OF_MEMORY; grib_binary_search(self->lats,ilat-1,inlat, &(self->j[0]),&(self->j[1])); nlon=0; for (jj=0;jj<self->j[0];jj++) nlon+=pl[jj]; nplm1=pl[self->j[0]]-1; lons=self->lons+nlon; nearest_lons_found=0; if (lons[nplm1]>lons[0]) { if (inlon< lons[0] || inlon > lons[nplm1]) { if (lons[nplm1]-lons[0]-360 <= lons[nplm1]-lons[nplm1-1]) { self->k[0]=0; self->k[1]=nplm1; nearest_lons_found=1; } else return GRIB_OUT_OF_AREA; } } else { if (inlon >lons[0] || inlon< lons[nplm1]) { if (lons[0]-lons[nplm1]-360 <= lons[0]-lons[1]) { self->k[0]=0; self->k[1]=nplm1; nearest_lons_found=1; } else return GRIB_OUT_OF_AREA; } } if (!nearest_lons_found) { grib_binary_search(lons,pl[self->j[0]]-1,inlon, &(self->k[0]),&(self->k[1])); } self->k[0]+=nlon; self->k[1]+=nlon; nlon=0; for (jj=0;jj<self->j[1];jj++) nlon+=pl[jj]; nplm1=pl[self->j[1]]-1; lons=self->lons+nlon; nearest_lons_found=0; if (lons[nplm1]>lons[0]) { if (inlon<lons[0] || inlon>lons[nplm1]) { if (lons[nplm1]-lons[0]-360 <= lons[nplm1]-lons[nplm1-1]) { self->k[2]=0; self->k[3]=nplm1; nearest_lons_found=1; } else return GRIB_OUT_OF_AREA; } } else { if (inlon>lons[0] || inlon<lons[nplm1]) { if (lons[0]-lons[nplm1]-360 <= lons[0]-lons[1]) { self->k[2]=0; self->k[3]=nplm1; nearest_lons_found=1; } else return GRIB_OUT_OF_AREA; } } if (!nearest_lons_found) { grib_binary_search(lons,pl[self->j[1]]-1,inlon, &(self->k[2]),&(self->k[3])); } self->k[2]+=nlon; self->k[3]+=nlon; kk=0; for (jj=0;jj<2;jj++) { for (ii=0;ii<2;ii++) { self->distances[kk]=grib_nearest_distance(radius,inlon,inlat, self->lons[self->k[kk]],self->lats[self->j[jj]]); kk++; } } grib_context_free(h->context,pla); } kk=0; for (jj=0;jj<2;jj++) { for (ii=0;ii<2;ii++) { distances[kk]=self->distances[kk]; outlats[kk]=self->lats[self->j[jj]]; outlons[kk]=self->lons[self->k[kk]]; grib_get_double_element_internal(h,self->values_key,self->k[kk],&(values[kk])); indexes[kk]=self->k[kk]; kk++; } } return GRIB_SUCCESS; }
int main(int argc, char* argv[]) { grib_handle *h1,*h2; int ret=0; FILE *f1,*f2; char* infile1; char* infile2; double *v1,*v2,*v,*gv; double *lon1,*lon2,*lon,*glon; double *lat1,*lat2,*lat,*glat; size_t size1,size2,size,gsize; double err1,err2,err; int i,j; grib_context* c; grib_iterator *iter1,*iter2; c=grib_context_get_default(); if (argc < 3) usage(argv[0]); infile1=argv[1]; infile2=argv[2]; f1=fopen(infile1,"r"); if (!f1) { perror(infile1); exit(1); } f2=fopen(infile2,"r"); if (!f2) { perror(infile2); exit(1); } while ((h1=grib_handle_new_from_file(0,f1,&ret))!=NULL) { if ((h2=grib_handle_new_from_file(c,f2,&ret))==NULL) { printf("unable to create handle from file %s\n",infile2); GRIB_CHECK(ret,0); exit(1); } GRIB_CHECK(grib_get_size(h1,"values",&size1),0); v1=malloc(size1*sizeof(double)); if (!v1) {printf("unable to allocate v1\n");exit(1);} lat1=malloc(size1*sizeof(double)); if (!lat1) {printf("unable to allocate lat1\n");exit(1);} lon1=malloc(size1*sizeof(double)); if (!lon1) {printf("unable to allocate lon1\n");exit(1);} GRIB_CHECK(grib_get_double(h1,"packingError",&err1),0); iter1=grib_iterator_new(h1,0,&ret); GRIB_CHECK(ret,0); GRIB_CHECK(grib_get_size(h2,"values",&size2),0); v2=malloc(size2*sizeof(double)); if (!v2) {printf("unable to allocate v2\n");exit(1);} lat2=malloc(size2*sizeof(double)); if (!lat2) {printf("unable to allocate lat2\n");exit(1);} lon2=malloc(size2*sizeof(double)); if (!lon2) {printf("unable to allocate lon2\n");exit(1);} GRIB_CHECK(grib_get_double(h2,"packingError",&err2),0); iter2=grib_iterator_new(h2,0,&ret); GRIB_CHECK(ret,0); lat=lat1; lon=lon1; v=v1; while(grib_iterator_next(iter1,lat,lon,v)) { lat++; if (*lon < 0 ) *lon+=360; lon++; v++; } lat=lat2; lon=lon2; v=v2; while(grib_iterator_next(iter2,lat,lon,v)) { lat++; if (*lon < 0 ) *lon+=360; lon++; v++; } if (size1 > size2) { lat=lat2;lon=lon2;v=v2; size=size2; glat=lat1;glon=lon1;gv=v1; gsize=size1; } else { lat=lat1;lon=lon1;v=v1; size=size1; glat=lat2;glon=lon2;gv=v2; gsize=size2; } if (err1>err2) err=err1; else err=err2; j=0; for (i=0;i<size;i++) { while (j < gsize && ( lat[i]!=glat[j] || lon[i]!=glon[j] ) ) j++; if (j == gsize) { j=0; while (j < gsize && ( lat[i]!=glat[j] || lon[i]!=glon[j] ) ) j++; } if (j==gsize) { printf("lat=%g lon=%g not found in global\n",lat[i],lon[i]); exit(1); } if (fabs(v[i]-gv[j])>err) { ret=1; printf("lat=%g lon=%g sub area value=%g global value=%g\n", lat[i],lon[i],v[i],gv[j]); } } free(v);free(gv);free(lat);free(glat);free(lon);free(glon); } fclose(f1); fclose(f2); return ret; }
int grib_tool_new_handle_action(grib_runtime_options* options, grib_handle* h) { int err=0; double *lat=0,*lon=0,*val=0; double missing_value=9999.; int skip_missing=1; char *kmiss=NULL, *p=NULL; char *missing_string=NULL; int i=0; grib_values* values=NULL; grib_iterator* iter = NULL; char* format=NULL; char* default_format="%.10e"; int print_keys=grib_options_on("p:"); long numberOfPoints=0; double *data_values=0,*lats=0,*lons=0; int n = 0; size_t size=0; if (grib_options_on("F:")) format=grib_options_get_option("F:"); else format=default_format; if ((err=grib_get_long(h,"numberOfPoints",&numberOfPoints)) !=GRIB_SUCCESS) { fprintf(dump_file,"ERROR: unable to get number of points\n"); return err; } iter=grib_iterator_new(h,0,&err); data_values=(double*)calloc(numberOfPoints+1,sizeof(double)); if (iter) { lats=(double*)calloc(numberOfPoints+1,sizeof(double)); lons=(double*)calloc(numberOfPoints+1,sizeof(double)); lat=lats; lon=lons; val=data_values; while(grib_iterator_next(iter,lat++,lon++,val++)) {} } else if (err==GRIB_NOT_IMPLEMENTED || err==GRIB_SUCCESS){ size=numberOfPoints; grib_get_double_array(h,"values",data_values,&size); if (size!=numberOfPoints) { if (!grib_options_on("q")) fprintf(dump_file,"ERROR: wrong number of points %d\n",(int)numberOfPoints); if (grib_options_on("f")) exit(1); } } else { grib_context_log(h->context,GRIB_LOG_ERROR, "%s",grib_get_error_message(err)); exit(err); } skip_missing=1; if (grib_options_on("m:")) { char* end=0; double mval=0; skip_missing=0; kmiss=grib_options_get_option("m:"); p=kmiss; while (*p != ':' && *p != '\0') p++; if (*p == ':' && *(p+1) != '\0') { *p='\0'; missing_string=strdup(p+1); } else { missing_string=strdup(kmiss); } mval=strtod(kmiss,&end); if (end==NULL) missing_value=mval; grib_set_double(h,"missingValue",missing_value); } if (iter) fprintf(dump_file,"Latitude, Longitude, "); fprintf(dump_file,"Value"); if (print_keys) for (i=0;i<options->print_keys_count; i++) fprintf(dump_file,", %s",options->print_keys[i].name); fprintf(dump_file,"\n"); if (print_keys) values=get_key_values(options,h); if (skip_missing==0){ for (i=0;i<numberOfPoints;i++) { if (iter) fprintf(dump_file,"%9.3f%9.3f ",lats[i],lons[i]); if (data_values[i] == missing_value) fprintf(dump_file,"%s",missing_string); else fprintf(dump_file,format,data_values[i]); if (print_keys) print_key_values(values,options->print_keys_count); fprintf(dump_file,"\n"); n++; } } else if ( skip_missing==1 ){ for (i=0;i<numberOfPoints;i++) { if (data_values[i] != missing_value){ if (iter) fprintf(dump_file,"%9.3f%9.3f ",lats[i],lons[i]); fprintf(dump_file,format,data_values[i]); if (print_keys) print_key_values(values,options->print_keys_count); fprintf(dump_file,"\n"); n++; } } } if (iter) grib_iterator_delete(iter); free(data_values); if (iter) { free(lats); free(lons); } return 0; }
static int 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) { grib_nearest_lambert_conformal* self = (grib_nearest_lambert_conformal*) nearest; int ret=0, i=0; size_t nvalues=0; long iradius; double radius; grib_iterator* iter=NULL; double lat=0,lon=0; /* array of candidates for nearest neighbours */ PointStore* neighbours = NULL; while (inlon<0) inlon+=360; while (inlon>360) inlon-=360; if( (ret = grib_get_size(h,self->values_key,&nvalues))!= GRIB_SUCCESS) return ret; nearest->values_count = nvalues; if (grib_is_missing(h,self->radius,&ret)) { grib_context_log(h->context, GRIB_LOG_DEBUG,"Key '%s' is missing", self->radius); return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; } if( (ret = grib_get_long(h,self->radius,&iradius))!= GRIB_SUCCESS) return ret; radius=((double)iradius)/1000.0; neighbours = (PointStore*)grib_context_malloc( nearest->context, nvalues*sizeof(PointStore) ); for(i=0; i<nvalues; ++i) { neighbours[i].m_dist = 1e10; /* set all distances to large number to begin with */ neighbours[i].m_lat=0; neighbours[i].m_lon=0; neighbours[i].m_value=0; neighbours[i].m_index=0; } /* GRIB_NEAREST_SAME_GRID not yet implemented */ { double the_value = 0; double min_dist = 1e10; size_t the_index = 0; int ilat=0, ilon=0; int idx_upper=0, idx_lower=0; double lat1=0, lat2=0; /* inlat will be between these */ double dist=0; const double LAT_DELTA = 10.0; /* in degrees */ if (grib_is_missing(h,self->Ni,&ret)) { grib_context_log(h->context, GRIB_LOG_DEBUG,"Key '%s' is missing", self->Ni); return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; } if (grib_is_missing(h,self->Nj,&ret)) { grib_context_log(h->context, GRIB_LOG_DEBUG,"Key '%s' is missing", self->Nj); return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; } self->lons_count=nvalues; /* Maybe overestimate but safe */ self->lats_count=nvalues; if (self->lats) grib_context_free(nearest->context,self->lats); self->lats=(double*)grib_context_malloc( nearest->context, nvalues* sizeof(double)); if (!self->lats) return GRIB_OUT_OF_MEMORY; if (self->lons) grib_context_free(nearest->context,self->lons); self->lons=(double*)grib_context_malloc( nearest->context, nvalues*sizeof(double)); if (!self->lons) return GRIB_OUT_OF_MEMORY; iter=grib_iterator_new(h,0,&ret); if (ret) return ret; /* First pass: collect all latitudes and longitudes */ while(grib_iterator_next(iter,&lat,&lon,&the_value)) { ++the_index; Assert(ilat < self->lats_count); Assert(ilon < self->lons_count); self->lats[ilat++]=lat; self->lons[ilon++]=lon; } /* See between which 2 latitudes our point lies */ qsort(self->lats, nvalues, sizeof(double), &compare_doubles_ascending); grib_binary_search(self->lats, self->lats_count-1, inlat, &idx_upper, &idx_lower); lat2 = self->lats[idx_upper]; lat1 = self->lats[idx_lower]; Assert(lat1<=lat2); /* Second pass: Iterate again and collect candidate neighbours */ grib_iterator_reset(iter); the_index=0; i = 0; while(grib_iterator_next(iter,&lat,&lon,&the_value)) { if (lat > lat2+LAT_DELTA || lat < lat1-LAT_DELTA) { /* Ignore latitudes too far from our point */ } else { dist = grib_nearest_distance(radius, inlon, inlat, lon, lat); if (dist < min_dist) min_dist = dist; /*printf("Candidate: lat=%.5f lon=%.5f dist=%f Idx=%ld Val=%f\n",lat,lon,dist,the_index,the_value);*/ /* store this candidate point */ neighbours[i].m_dist = dist; neighbours[i].m_index = the_index; neighbours[i].m_lat = lat; neighbours[i].m_lon = lon; neighbours[i].m_value = the_value; i++; } ++the_index; } /* Sort the candidate neighbours in ascending order of distance */ /* The first 4 entries will now be the closest 4 neighbours */ qsort(neighbours, nvalues, sizeof(PointStore), &compare_points); grib_iterator_delete(iter); } nearest->h=h; /* Sanity check for sorting */ #ifdef DEBUG for(i=0; i<nvalues-1; ++i) { Assert( neighbours[i].m_dist <= neighbours[i+1].m_dist); } #endif /* GRIB_NEAREST_SAME_XXX not yet implemented */ if (!self->distances) { self->distances=(double*)grib_context_malloc( nearest->context,4*sizeof(double)); } self->distances[0] = neighbours[0].m_dist; self->distances[1] = neighbours[1].m_dist; self->distances[2] = neighbours[2].m_dist; self->distances[3] = neighbours[3].m_dist; for(i=0; i <4; ++i) { distances[i] = neighbours[i].m_dist; outlats[i] = neighbours[i].m_lat; outlons[i] = neighbours[i].m_lon; indexes[i] = neighbours[i].m_index; values[i] = neighbours[i].m_value; /*printf("(%f,%f) i=%d d=%f v=%f\n",outlats[i],outlons[i],indexes[i],distances[i],values[i]);*/ } free(neighbours); return GRIB_SUCCESS; }
static int find(grib_nearest* nearest, grib_handle* h, double inlat, double inlon,unsigned long flags, double* outlats,double* outlons, double *values, double *distances,double *distances,int *indexes,size_t *len) { grib_nearest_reduced* self = (grib_nearest_reduced*) nearest; int ret=0,kk=0,ii=0,jj=0; double* pl=NULL; int ilat; size_t nvalues=0; if (!nearest->h || (flags & GRIB_NEAREST_SAME_DATA)==0 || nearest->h!=h) { grib_iterator* iter=NULL; double lat=0,lon=0; if( (ret = grib_get_size(h,self->values_key,&nvalues))!= GRIB_SUCCESS) return ret; nearest->values_count = nvalues; if (nearest->values) grib_context_free(nearest->context,nearest->values); nearest->values = grib_context_malloc(h->context,nvalues*sizeof(double)); if (!nearest->values) return GRIB_OUT_OF_MEMORY; ret=grib_get_double_array_internal( h,self->values_key, nearest->values,&(nearest->values_count)); if (ret!=GRIB_SUCCESS) grib_context_log(nearest->context,GRIB_LOG_ERROR, "nearest: unable to get values array"); if (!nearest->h || (flags & GRIB_NEAREST_SAME_GRID)==0) { double dummy=0; double olat=1.e10; ilat=0,ilon=0; long n=0; if (grib_is_missing(h,self->Nj,&ret)) { grib_context_log(h->context, GRIB_LOG_DEBUG,"Key '%s' is missing", self->Nj); return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; } if( (ret = grib_get_long(h,self->Nj,&n))!= GRIB_SUCCESS) return ret; self->lats_count=n; if (self->lats) grib_context_free(nearest->context,self->lats); self->lats=grib_context_malloc( nearest->context, self->lats_count* sizeof(double)); if (!self->lats) return GRIB_OUT_OF_MEMORY; if (self->lons) grib_context_free(nearest->context,self->lons); self->lons=grib_context_malloc( nearest->context, nearest->values_count*sizeof(double)); if (!self->lons) return GRIB_OUT_OF_MEMORY; iter=grib_iterator_new(h,0,&ret); while(grib_iterator_next(iter,&lat,&lon,&dummy)) { if (olat!=lat) {self->lats[ilat++]=lat;olat=lat;} self->lons[ilon++]=lon; } grib_iterator_delete(iter); } nearest->h=h; } if (!self->distances || (flags & GRIB_NEAREST_SAME_POINT)==0 || (flags & GRIB_NEAREST_SAME_GRID)==0) { double* lons=NULL; int nlon=0; int plsize=0; self->distances=(double*)grib_context_malloc( nearest->context,4*sizeof(double)); if (!self->distances) return GRIB_OUT_OF_MEMORY; grib_binary_search(self->lats,self->lats_count-1,inlat, &(self->j[0]),&(self->j[1])); plsize=self->lats_count; pl=(double*)grib_context_malloc(h->context,plsize*sizeof(double)); if (!pl) return GRIB_OUT_OF_MEMORY; if( (ret=grib_get_double_array(h,"pl",pl,&plsize))!= GRIB_SUCCESS) return ret; nlon=0; for (jj=0;jj<self->j[0];jj++) { nlon+=pl[jj]; } lons=self->lons+nlon; grib_binary_search(lons,pl[self->j[0]]-1,inlon, &(self->k[0]),&(self->k[1])); self->k[0]+=nlon; self->k[1]+=nlon; nlon=0; for (jj=0;jj<self->j[1];jj++) { nlon+=pl[jj]; } lons=self->lons+nlon; grib_binary_search(lons,pl[self->j[1]]-1,inlon, &(self->k[2]),&(self->k[3])); self->k[2]+=nlon; self->k[3]+=nlon; kk=0; for (ii=0;ii<2;ii++) { for (jj=0;jj<2;jj++) { self->distances[kk]=grib_nearest_distance(radius,inlon,inlat, self->lons[self->k[kk]],self->lats[self->j[jj]]); kk++; } } grib_context_free(h->context,pl); } kk=0; for (ii=0;ii<2;ii++) { for (jj=0;jj<2;jj++) { distances[kk]=self->distances[kk]; outlats[kk]=self->lats[self->j[jj]]; outlons[kk]=self->lons[self->k[kk]]; values[kk]=nearest->values[self->k[kk]]; indexes[kk]=self->k[kk]; kk++; } } return GRIB_SUCCESS; }
static int 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) { grib_nearest_reduced* self = (grib_nearest_reduced*) nearest; int ret=0,kk=0,ii=0,jj=0; long* pla=NULL; long* pl=NULL; size_t nvalues=0; grib_iterator* iter=NULL; double lat=0,lon=0; long iradius; double radius; int ilat=0,ilon=0; if( (ret = grib_get_size(h,self->values_key,&nvalues))!= GRIB_SUCCESS) return ret; nearest->values_count = nvalues; if (grib_is_missing(h,self->radius,&ret)) { grib_context_log(h->context, GRIB_LOG_DEBUG,"Key '%s' is missing", self->radius); return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; } if( (ret = grib_get_long(h,self->radius,&iradius))!= GRIB_SUCCESS) return ret; radius=((double)iradius)/1000.0; if (!nearest->h || (flags & GRIB_NEAREST_SAME_GRID)==0) { double dummy=0; double olat=1.e10; long n=0; ilat=0,ilon=0; if (grib_is_missing(h,self->Nj,&ret)) { grib_context_log(h->context, GRIB_LOG_DEBUG,"Key '%s' is missing", self->Nj); return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; } if( (ret = grib_get_long(h,self->Nj,&n))!= GRIB_SUCCESS) return ret; self->lats_count=n; if (self->lats) grib_context_free(nearest->context,self->lats); self->lats=(double*)grib_context_malloc( nearest->context, self->lats_count* sizeof(double)); if (!self->lats) return GRIB_OUT_OF_MEMORY; if (self->lons) grib_context_free(nearest->context,self->lons); self->lons=(double*)grib_context_malloc( nearest->context, nearest->values_count*sizeof(double)); if (!self->lons) return GRIB_OUT_OF_MEMORY; iter=grib_iterator_new(h,0,&ret); while(grib_iterator_next(iter,&lat,&lon,&dummy)) { if (olat!=lat) { self->lats[ilat++]=lat; olat=lat; } self->lons[ilon++]=lon; } self->lats_count=ilat; grib_iterator_delete(iter); } nearest->h=h; if (!self->distances || (flags & GRIB_NEAREST_SAME_POINT)==0 || (flags & GRIB_NEAREST_SAME_GRID)==0) { double* lons=NULL; int nlon=0; size_t plsize=0; long nplm1=0; int nearest_lons_found=0; long global=0; double lon_first,lon_last; long row_count,ilon_first,ilon_last; /*TODO global from the def file*/ global=1; grib_get_long(h,"global",&global); if (!global) { /*TODO longitudeOfFirstGridPointInDegrees from the def file*/ if ((ret=grib_get_double(h,"longitudeOfFirstGridPointInDegrees",&lon_first))!=GRIB_SUCCESS) { grib_context_log(h->context,GRIB_LOG_ERROR, "grib_nearest_reduced.find(): unable to get longitudeOfFirstGridPointInDegrees %s\n", grib_get_error_message(ret)); return ret; } /*TODO longitudeOfLastGridPointInDegrees from the def file*/ if ((ret=grib_get_double(h,"longitudeOfLastGridPointInDegrees",&lon_last))!=GRIB_SUCCESS) { grib_context_log(h->context,GRIB_LOG_ERROR, "grib_nearest_reduced.find(): unable to get longitudeOfLastGridPointInDegrees %s\n", grib_get_error_message(ret)); return ret; } /* if (lon_last<0) lon_last+=360; */ /* if (lon_first<0) lon_first+=360; */ } else { while (inlon<0) inlon+=360; while (inlon>360) inlon-=360; } ilat=self->lats_count; if (self->lats[ilat-1] > self->lats[0]) { if (inlat < self->lats[0] || inlat > self->lats[ilat-1]) return GRIB_OUT_OF_AREA; } else { if (inlat > self->lats[0] || inlat < self->lats[ilat-1]) return GRIB_OUT_OF_AREA; } if (!self->distances) self->distances=(double*)grib_context_malloc( nearest->context,4*sizeof(double)); if (!self->distances) return GRIB_OUT_OF_MEMORY; grib_binary_search(self->lats,ilat-1,inlat, &(self->j[0]),&(self->j[1])); plsize=self->lats_count; if( (ret=grib_get_size(h,self->pl,&plsize))!= GRIB_SUCCESS) return ret; pla=(long*)grib_context_malloc(h->context,plsize*sizeof(long)); if (!pla) return GRIB_OUT_OF_MEMORY; if( (ret=grib_get_long_array(h,self->pl,pla,&plsize))!= GRIB_SUCCESS) return ret; pl=pla; while ((*pl)==0) {pl++;} nlon=0; if (global) { for (jj=0;jj<self->j[0];jj++) nlon+=pl[jj]; nplm1=pl[self->j[0]]-1; } else { nlon=0; for (jj=0;jj<self->j[0];jj++) { row_count=0;ilon_first=0;ilon_last=0; grib_get_reduced_row(pl[jj],lon_first,lon_last,&row_count,&ilon_first,&ilon_last); nlon+=row_count; } row_count=0;ilon_first=0;ilon_last=0; grib_get_reduced_row(pl[self->j[0]],lon_first,lon_last,&row_count,&ilon_first,&ilon_last); nplm1=row_count-1; } lons=self->lons+nlon; nearest_lons_found=0; if (lons[nplm1]>lons[0]) { if (inlon< lons[0] || inlon > lons[nplm1]) { if (lons[nplm1]-lons[0]-360 <= lons[nplm1]-lons[nplm1-1]) { self->k[0]=0; self->k[1]=nplm1; nearest_lons_found=1; } else return GRIB_OUT_OF_AREA; } } else { if (inlon >lons[0] || inlon< lons[nplm1]) { if (lons[0]-lons[nplm1]-360 <= lons[0]-lons[1]) { self->k[0]=0; self->k[1]=nplm1; nearest_lons_found=1; } else return GRIB_OUT_OF_AREA; } } if (!nearest_lons_found) { if (!global) { row_count=0;ilon_first=0;ilon_last=0; grib_get_reduced_row(pl[self->j[0]],lon_first,lon_last,&row_count,&ilon_first,&ilon_last); } else { row_count=pl[self->j[0]]; } grib_binary_search(lons,row_count-1,inlon, &(self->k[0]),&(self->k[1])); } self->k[0]+=nlon; self->k[1]+=nlon; nlon=0; if (global) { for (jj=0;jj<self->j[1];jj++) nlon+=pl[jj]; nplm1=pl[self->j[1]]-1; } else { long row_count,ilon_first,ilon_last; for (jj=0;jj<self->j[1];jj++) { row_count=0;ilon_first=0;ilon_last=0; grib_get_reduced_row(pl[jj],lon_first,lon_last,&row_count,&ilon_first,&ilon_last); nlon+=row_count; } row_count=0;ilon_first=0;ilon_last=0; grib_get_reduced_row(pl[self->j[1]],lon_first,lon_last,&nplm1,&ilon_first,&ilon_last); nplm1--; } lons=self->lons+nlon; nearest_lons_found=0; if (lons[nplm1]>lons[0]) { if (inlon<lons[0] || inlon>lons[nplm1]) { if (lons[nplm1]-lons[0]-360 <= lons[nplm1]-lons[nplm1-1]) { self->k[2]=0; self->k[3]=nplm1; nearest_lons_found=1; } else return GRIB_OUT_OF_AREA; } } else { if (inlon>lons[0] || inlon<lons[nplm1]) { if (lons[0]-lons[nplm1]-360 <= lons[0]-lons[1]) { self->k[2]=0; self->k[3]=nplm1; nearest_lons_found=1; } else return GRIB_OUT_OF_AREA; } } if (!nearest_lons_found) { if (!global) { row_count=0;ilon_first=0;ilon_last=0; grib_get_reduced_row(pl[self->j[1]],lon_first,lon_last,&row_count,&ilon_first,&ilon_last); } else { row_count=pl[self->j[1]]; } grib_binary_search(lons,row_count-1,inlon, &(self->k[2]),&(self->k[3])); } self->k[2]+=nlon; self->k[3]+=nlon; kk=0; for (jj=0;jj<2;jj++) { for (ii=0;ii<2;ii++) { self->distances[kk]=grib_nearest_distance(radius,inlon,inlat, self->lons[self->k[kk]],self->lats[self->j[jj]]); kk++; } } grib_context_free(h->context,pla); } kk=0; for (jj=0;jj<2;jj++) { for (ii=0;ii<2;ii++) { distances[kk]=self->distances[kk]; outlats[kk]=self->lats[self->j[jj]]; outlons[kk]=self->lons[self->k[kk]]; grib_get_double_element_internal(h,self->values_key,self->k[kk],&(values[kk])); indexes[kk]=self->k[kk]; kk++; } } return GRIB_SUCCESS; }
static int 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) { grib_nearest_regular* self = (grib_nearest_regular*) nearest; int ret=0,kk=0,ii=0,jj=0; size_t nvalues=0; long iradius; double radius; grib_iterator* iter=NULL; double lat=0,lon=0; while (inlon<0) inlon+=360; while (inlon>360) inlon-=360; if( (ret = grib_get_size(h,self->values_key,&nvalues))!= GRIB_SUCCESS) return ret; nearest->values_count = nvalues; if (grib_is_missing(h,self->radius,&ret)) { grib_context_log(h->context, GRIB_LOG_DEBUG,"Key '%s' is missing", self->radius); return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; } if( (ret = grib_get_long(h,self->radius,&iradius))!= GRIB_SUCCESS) return ret; radius=((double)iradius)/1000.0; if (!nearest->h || (flags & GRIB_NEAREST_SAME_GRID)==0) { double dummy=0; double olat=1.e10, olon=1.e10; int ilat=0,ilon=0; long n=0; if (grib_is_missing(h,self->Ni,&ret)) { grib_context_log(h->context, GRIB_LOG_DEBUG,"Key '%s' is missing", self->Ni); return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; } if (grib_is_missing(h,self->Nj,&ret)) { grib_context_log(h->context, GRIB_LOG_DEBUG,"Key '%s' is missing", self->Nj); return ret ? ret : GRIB_GEOCALCULUS_PROBLEM; } if ((ret = grib_get_long(h,self->Ni,&n))!= GRIB_SUCCESS) return ret; self->lons_count=n; if ((ret = grib_get_long(h,self->Nj,&n))!= GRIB_SUCCESS) return ret; self->lats_count=n; if (self->lats) grib_context_free(nearest->context,self->lats); self->lats=(double*)grib_context_malloc( nearest->context, self->lats_count* sizeof(double)); if (!self->lats) return GRIB_OUT_OF_MEMORY; if (self->lons) grib_context_free(nearest->context,self->lons); self->lons=(double*)grib_context_malloc( nearest->context, self->lons_count*sizeof(double)); if (!self->lons) return GRIB_OUT_OF_MEMORY; iter=grib_iterator_new(h,0,&ret); while(grib_iterator_next(iter,&lat,&lon,&dummy)) { if (olat != lat) { self->lats[ilat++]=lat; olat=lat; } if (ilon<self->lons_count && olon != lon) { self->lons[ilon++]=lon ; olon=lon; } } grib_iterator_delete(iter); } nearest->h=h; if (!self->distances || (flags & GRIB_NEAREST_SAME_POINT)==0 || (flags & GRIB_NEAREST_SAME_GRID)==0) { int nearest_lons_found=0; if (self->lats[self->lats_count-1] > self->lats[0]) { if (inlat<self->lats[0] || inlat>self->lats[self->lats_count-1]) return GRIB_OUT_OF_AREA; } else { if (inlat > self->lats[0] || inlat < self->lats[self->lats_count-1]) return GRIB_OUT_OF_AREA; } if (self->lons[self->lons_count-1] > self->lons[0]) { if (inlon<self->lons[0] || inlon>self->lons[self->lons_count-1]) { /* try to scale*/ if (inlon>0) inlon-=360; else inlon+=360; if (inlon<self->lons[0] || inlon>self->lons[self->lons_count-1]) { if ( self->lons[0]+360-self->lons[self->lons_count-1]<= self->lons[1]-self->lons[0]) { /*it's a global field in longitude*/ self->i[0]=0; self->i[1]=self->lons_count-1; nearest_lons_found=1; } else return GRIB_OUT_OF_AREA; } } } else { if (inlon>self->lons[0] || inlon<self->lons[self->lons_count-1]) { /* try to scale*/ if (inlon>0) inlon-=360; else inlon+=360; if (self->lons[0]-self->lons[self->lons_count-1]-360 <= self->lons[0]-self->lons[1]) { /*it's a global field in longitude*/ self->i[0]=0; self->i[1]=self->lons_count-1; nearest_lons_found=1; } else if (inlon>self->lons[0] || inlon<self->lons[self->lons_count-1]) return GRIB_OUT_OF_AREA; } } grib_binary_search(self->lats,self->lats_count-1,inlat, &(self->j[0]),&(self->j[1])); if (!nearest_lons_found) grib_binary_search(self->lons,self->lons_count-1,inlon, &(self->i[0]),&(self->i[1])); if (!self->distances) self->distances=(double*)grib_context_malloc( nearest->context,4*sizeof(double)); if (!self->k) self->k=(int*)grib_context_malloc( nearest->context,4*sizeof(int)); kk=0; for (jj=0;jj<2;jj++) { for (ii=0;ii<2;ii++) { self->k[kk]=self->i[ii]+self->lons_count*self->j[jj]; self->distances[kk]=grib_nearest_distance(radius,inlon,inlat, self->lons[self->i[ii]],self->lats[self->j[jj]]); kk++; } } } kk=0; /* * Brute force algorithm: * First unpack all the values into an array. Then when we need the 4 points * we just index into this array so no need to call grib_get_double_element_internal * * if (nearest->values) grib_context_free(nearest->context,nearest->values); * nearest->values = grib_context_malloc(h->context,nvalues*sizeof(double)); * if (!nearest->values) return GRIB_OUT_OF_MEMORY; * ret = grib_get_double_array(h, self->values_key, nearest->values ,&nvalues); * if (ret) return ret; */ for (jj=0;jj<2;jj++) { for (ii=0;ii<2;ii++) { distances[kk]=self->distances[kk]; outlats[kk]=self->lats[self->j[jj]]; outlons[kk]=self->lons[self->i[ii]]; grib_get_double_element_internal(h,self->values_key,self->k[kk],&(values[kk])); /* Using the brute force approach described above */ /* Assert(self->k[kk] < nvalues); */ /* values[kk]=nearest->values[self->k[kk]]; */ indexes[kk]=self->k[kk]; kk++; } } return GRIB_SUCCESS; }
static int 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) { grib_nearest_regular* self = (grib_nearest_regular*) nearest; int ret=0,kk=0,ii=0,jj=0; size_t nvalues=0; long iradius; double radius; if( (ret = grib_get_long(h,self->radius,&iradius))!= GRIB_SUCCESS) return ret; radius=((double)iradius)/1000.0; if (!nearest->h || (flags & GRIB_NEAREST_SAME_DATA)==0 || nearest->h!=h) { grib_iterator* iter=NULL; double lat=0,lon=0; if( (ret = grib_get_size(h,self->values_key,&nvalues))!= GRIB_SUCCESS) return ret; nearest->values_count = nvalues; if (nearest->values) grib_context_free(nearest->context,nearest->values); nearest->values = grib_context_malloc(h->context,nvalues*sizeof(double)); if (!nearest->values) return GRIB_OUT_OF_MEMORY; ret=grib_get_double_array_internal( h,self->values_key, nearest->values,&(nearest->values_count)); if (ret!=GRIB_SUCCESS) grib_context_log(nearest->context,GRIB_LOG_ERROR, "nearest: unable to get values array"); if (!nearest->h || (flags & GRIB_NEAREST_SAME_GRID)==0) { double dummy=0; double olat=1.e10, olon=1.e10; int ilat=0,ilon=0; long n=0; if( (ret = grib_get_long(h,self->Ni,&n))!= GRIB_SUCCESS) return ret; self->lons_count=n; if( (ret = grib_get_long(h,self->Nj,&n))!= GRIB_SUCCESS) return ret; self->lats_count=n; if (self->lats) grib_context_free(nearest->context,self->lats); self->lats=grib_context_malloc( nearest->context, self->lats_count* sizeof(double)); if (!self->lats) return GRIB_OUT_OF_MEMORY; if (self->lons) grib_context_free(nearest->context,self->lons); self->lons=grib_context_malloc( nearest->context, self->lons_count*sizeof(double)); if (!self->lons) return GRIB_OUT_OF_MEMORY; iter=grib_iterator_new(h,0,&ret); if (ret) { grib_context_log(nearest->context,GRIB_LOG_ERROR,"unable to create iterator"); return ret; } while(grib_iterator_next(iter,&lat,&lon,&dummy)) { if (olat != lat) { self->lats[ilat++]=lat; olat=lat; } if (ilon<self->lons_count && olon != lon) { self->lons[ilon++]=lon; olon=lon; } } grib_iterator_delete(iter); } nearest->h=h; } if (!self->distances || (flags & GRIB_NEAREST_SAME_POINT)==0 || (flags & GRIB_NEAREST_SAME_GRID)==0) { grib_binary_search(self->lats,self->lats_count-1,inlat, &(self->j[0]),&(self->j[1])); grib_binary_search(self->lons,self->lons_count-1,inlon, &(self->i[0]),&(self->i[1])); if (!self->distances) self->distances=(double*)grib_context_malloc( nearest->context,4*sizeof(double)); if (!self->k) self->k=(int*)grib_context_malloc( nearest->context,4*sizeof(int)); kk=0; for (ii=0;ii<2;ii++) { for (jj=0;jj<2;jj++) { self->k[kk]=self->i[ii]+self->lons_count*self->j[jj]-1; self->distances[kk]=grib_nearest_distance(radius,inlon,inlat, self->lons[self->i[ii]],self->lats[self->j[jj]]); kk++; } } } kk=0; for (ii=0;ii<2;ii++) { for (jj=0;jj<2;jj++) { distances[kk]=self->distances[kk]; outlats[kk]=self->lats[self->j[jj]]; outlons[kk]=self->lons[self->i[ii]]; values[kk]=nearest->values[self->k[kk]]; indexes[kk]=self->k[kk]; kk++; } } return GRIB_SUCCESS; }