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;
}
Пример #2
0
int codes_get_gaussian_latitudes(long truncation,double* latitudes)
{
    return grib_get_gaussian_latitudes(truncation,latitudes);
}
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;
}