void codes_get_reduced_row(long pl,double lon_first,double lon_last,long* npoints,long* ilon_first, long* ilon_last ) { grib_get_reduced_row(pl,lon_first,lon_last,npoints,ilon_first,ilon_last); }
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 init(grib_iterator* iter,grib_handle* h,grib_arguments* args) { int ret=GRIB_SUCCESS,j; double lat_first=0,lon_first=0,lat_last=0,lon_last=0,d=0; double* lats; size_t plsize=0; int l=0; long* pl; long nj=0,order=0,ilon_first,ilon_last,i; long row_count=0; grib_context* c=h->context; grib_iterator_gaussian_reduced* self = (grib_iterator_gaussian_reduced*)iter; const char* slat_first = grib_arguments_get_name(h,args,self->carg++); const char* slon_first = grib_arguments_get_name(h,args,self->carg++); const char* slat_last = grib_arguments_get_name(h,args,self->carg++); const char* slon_last = grib_arguments_get_name(h,args,self->carg++); const char* sorder = grib_arguments_get_name(h,args,self->carg++); const char* spl = grib_arguments_get_name(h,args,self->carg++); const char* snj = grib_arguments_get_name(h,args,self->carg++); if((ret = grib_get_double_internal(h, slat_first,&lat_first)) != GRIB_SUCCESS) return ret; if((ret = grib_get_double_internal(h, slon_first,&lon_first)) != GRIB_SUCCESS) return ret; if((ret = grib_get_double_internal(h, slat_last,&lat_last)) != GRIB_SUCCESS) return ret; if((ret = grib_get_double_internal(h, slon_last,&lon_last)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(h, sorder,&order)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(h, snj,&nj)) != GRIB_SUCCESS) return ret; lats=(double*)grib_context_malloc(h->context,sizeof(double)*order*2); if((ret = grib_get_gaussian_latitudes(order, lats)) != GRIB_SUCCESS) return ret; if((ret = grib_get_size(h,spl,&plsize)) != GRIB_SUCCESS) return ret; pl=(long*)grib_context_malloc(c,sizeof(long)*plsize); grib_get_long_array_internal(h,spl,pl, &plsize); self->las = grib_context_malloc(h->context,iter->nv*sizeof(double)); self->los = grib_context_malloc(h->context,iter->nv*sizeof(double)); while (lon_last<0) lon_last+=360; while (lon_first<0) lon_first+=360; d=fabs(lats[0]-lats[1]); if ( (fabs(lat_first-lats[0]) >= d ) || (fabs(lat_last+lats[0]) >= d ) || lon_first != 0 || fabs(lon_last - (360.0-90.0/order)) > 90.0/order ) { /*sub area*/ /*find starting latitude */ while (fabs(lat_first-lats[l]) > d ) {l++;} iter->e=0; for (j=0;j<plsize;j++) { row_count=0; /*printf("lat=%g\n",lats[j+l]);*/ grib_get_reduced_row(pl[j],lon_first,lon_last, &row_count,&ilon_first,&ilon_last); if (ilon_first>ilon_last) ilon_first-=pl[j]; for (i=ilon_first;i<=ilon_last;i++) { self->los[iter->e]=((i)*360.0)/pl[j]; self->las[iter->e]=lats[j+l]; iter->e++; } } } else { /*global*/ iter->e=0; for (j=0;j<plsize;j++) { row_count=pl[j]; for (i=0;i<row_count;i++) { self->los[iter->e]=(i*360.0)/row_count; self->las[iter->e]=lats[j]; iter->e++; } } } iter->e = -1; grib_context_free(h->context,lats); grib_context_free(h->context,pl); return ret; }
static int init(grib_iterator* iter,grib_handle* h,grib_arguments* args) { int ret=GRIB_SUCCESS, j, is_global=0; double lat_first=0,lon_first=0,lat_last=0,lon_last=0; double angular_precision = 1.0/1000000.0; double* lats; size_t plsize=0; long* pl; long max_pl=0; long nj=0,order=0,ilon_first,ilon_last,i; long row_count=0; long editionNumber = 0; grib_context* c=h->context; grib_iterator_gaussian_reduced* self = (grib_iterator_gaussian_reduced*)iter; const char* slat_first = grib_arguments_get_name(h,args,self->carg++); const char* slon_first = grib_arguments_get_name(h,args,self->carg++); const char* slat_last = grib_arguments_get_name(h,args,self->carg++); const char* slon_last = grib_arguments_get_name(h,args,self->carg++); const char* sorder = grib_arguments_get_name(h,args,self->carg++); const char* spl = grib_arguments_get_name(h,args,self->carg++); const char* snj = grib_arguments_get_name(h,args,self->carg++); if((ret = grib_get_double_internal(h, slat_first,&lat_first)) != GRIB_SUCCESS) return ret; if((ret = grib_get_double_internal(h, slon_first,&lon_first)) != GRIB_SUCCESS) return ret; if((ret = grib_get_double_internal(h, slat_last,&lat_last)) != GRIB_SUCCESS) return ret; if((ret = grib_get_double_internal(h, slon_last,&lon_last)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(h, sorder,&order)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(h, snj,&nj)) != GRIB_SUCCESS) return ret; if (grib_get_long(h, "editionNumber", &editionNumber)==GRIB_SUCCESS) { if (editionNumber == 1) angular_precision = 1.0/1000; } lats=(double*)grib_context_malloc(h->context,sizeof(double)*order*2); if (!lats) return GRIB_OUT_OF_MEMORY; if((ret = grib_get_gaussian_latitudes(order, lats)) != GRIB_SUCCESS) return ret; if((ret = grib_get_size(h,spl,&plsize)) != GRIB_SUCCESS) return ret; Assert(plsize); pl=(long*)grib_context_malloc(c,sizeof(long)*plsize); if (!pl) return GRIB_OUT_OF_MEMORY; grib_get_long_array_internal(h,spl,pl, &plsize); self->las = (double*)grib_context_malloc(h->context,iter->nv*sizeof(double)); if (!self->las) return GRIB_OUT_OF_MEMORY; self->los = (double*)grib_context_malloc(h->context,iter->nv*sizeof(double)); if (!self->los) return GRIB_OUT_OF_MEMORY; while (lon_last<0) lon_last+=360; while (lon_first<0) lon_first+=360; /* Find the maximum element of "pl" array, do not assume it's 4*N! */ /* This could be an Octahedral Gaussian Grid */ max_pl = pl[0]; for (j=1; j<plsize; j++) { if (pl[j] > max_pl) max_pl = pl[j]; } is_global = is_gaussian_global(lat_first, lat_last, lon_first, lon_last, max_pl, lats, angular_precision); if ( !is_global ) { int l=0; /*sub area*/ /*find starting latitude */ const double d = fabs(lats[0] - lats[1]); while (fabs(lat_first-lats[l]) > d ) {l++;} iter->e=0; for (j=0;j<plsize;j++) { row_count=0; grib_get_reduced_row(pl[j],lon_first,lon_last, &row_count,&ilon_first,&ilon_last); if (ilon_first>ilon_last) ilon_first-=pl[j]; for (i=ilon_first;i<=ilon_last;i++) { #ifdef DEBUG Assert(iter->e < iter->nv); #endif self->los[iter->e]=((i)*360.0)/pl[j]; self->las[iter->e]=lats[j+l]; iter->e++; } } } else { /*global*/ iter->e=0; for (j=0;j<plsize;j++) { row_count=pl[j]; for (i=0;i<row_count;i++) { #ifdef DEBUG Assert(iter->e < iter->nv); #endif self->los[iter->e]=(i*360.0)/row_count; self->las[iter->e]=lats[j]; iter->e++; } } } iter->e = -1; grib_context_free(h->context,lats); grib_context_free(h->context,pl); return ret; }