int f_lola(ARG4) { int nx, ny, nxny, i, j, k; float latitude, longitude; double x0,dx, y0,dy; unsigned long int size; unsigned char *lola_gds; struct local_struct { int nlat, nlon; double lat0, lon0, dlat, dlon; FILE *out; /* int iptr[nxny]; */ int *iptr; }; struct local_struct *save; char open_mode[4]; /* initialization phase */ if (mode == -1) { decode = latlon = 1; if (sscanf(arg1,"%lf:%d:%lf", &x0, &nx, &dx) != 3) { fatal_error("lola parsing longitudes lon0:nx:dlon %s", arg1); } if (sscanf(arg2,"%lf:%d:%lf", &y0,&ny,&dy) != 3) { fatal_error("lola parsing latitudes lat0:nx:dlat %s", arg2); } if (strcmp(arg4,"spread") != 0 && strcmp(arg4,"text") != 0 && strcmp(arg4,"grib") != 0 && strcmp(arg4,"bin") != 0) fatal_error("lola bad write mode %s", arg4); strcpy(open_mode, file_append ? "a" : "w"); if (strcmp(arg4,"bin") == 0 || strcmp(arg4,"grib") == 0) strcat(open_mode,"b"); nxny = nx*ny; save = (struct local_struct *)malloc( sizeof(struct local_struct)); if (save == NULL) fatal_error("lola memory allocation ",""); *local = save; save->nlon = nx; save->lon0 = x0; save->dlon = dx; save->nlat = ny; save->lat0 = y0; save->dlat = dy; save->iptr = (int *) malloc(nx*ny * sizeof(int)); save->out = fopen(arg3,open_mode); if (save->out == NULL) fatal_error("lola could not open file %s", arg3); return 0; } /* cleanup phase */ if (mode == -2) return 0; /* processing phase */ save = *local; nx = save->nlon; ny = save->nlat; nxny = nx*ny; if (new_GDS) { if (output_order != wesn) fatal_error("lola only works in we:sn order",""); if (lat == NULL || lon == NULL || data == NULL) fatal_error("lola: no val",""); /* find the nearest points for the grid */ closest_init(sec); k = 0; for (j = 0; j < ny; j++) { latitude = save->lat0 + j*save->dlat; for (i = 0; i < nx; i++) { longitude = save->lon0 + i*save->dlon; save->iptr[k++] = closest(sec, latitude, longitude); } } } if (strcmp(arg4,"spread") == 0) { k = 0; fprintf(save->out, "longitude, latitude, value,\n"); for (j = 0; j < ny; j++) { latitude = save->lat0 + j*save->dlat; for (i = 0; i < nx; i++) { longitude = save->lon0 + i*save->dlon; fprintf(save->out, "%.2f, %.2f, %g,\n",longitude,latitude,data[save->iptr[k++]]); } } } else if (strcmp(arg4,"bin") == 0) { i = nxny * sizeof(float); if (header) fwrite((void *) &i, sizeof(int), 1, save->out); for (i = 0; i < nxny; i++) { fwrite(data + save->iptr[i], sizeof(float), 1, save->out); } if (header) fwrite((void *) &i, sizeof(int), 1, save->out); } else if (strcmp(arg4,"text") == 0) { /* text output */ if (header == 1) { fprintf(save->out ,"%d %d\n", nx, ny); } for (i = 0; i < nxny; i++) { fprintf(save->out, text_format, data[save->iptr[i]]); fprintf(save->out, ((i+1) % text_column) ? " " : "\n"); } } else if (strcmp(arg4,"grib") == 0) { printf("grib writer"); for (i = 0; i < nxny; i++) { fprintf(save->out, "%g\n", data[save->iptr[i]]); } } if (flush_mode) fflush(save->out); return 0; }
int f_lola(ARG4) { int nx, ny, j, k; int i, nxny; double latitude, longitude; double x0,dx, y0,dy; unsigned char *new_sec[8]; float *tmp, t; struct local_struct { int nlat, nlon; double lat0, lon0, dlat, dlon; FILE *out; int *iptr; }; struct local_struct *save; char open_mode[4]; /* initialization phase */ if (mode == -1) { decode = latlon = 1; if (sscanf(arg1,"%lf:%d:%lf", &x0, &nx, &dx) != 3) { fatal_error("lola parsing longitudes lon0:nx:dlon %s", arg1); } if (sscanf(arg2,"%lf:%d:%lf", &y0,&ny,&dy) != 3) { fatal_error("lola parsing latitudes lat0:nx:dlat %s", arg2); } if (strcmp(arg4,"spread") != 0 && strcmp(arg4,"text") != 0 && strcmp(arg4,"grib") != 0 && strcmp(arg4,"bin") != 0) fatal_error("lola bad write mode %s", arg4); if (strcmp(arg4,"grib") == 0 && (dx <= 0 || dy <= 0)) fatal_error("lola parsing, for grib dlat > 0 and dlon > 0",""); strcpy(open_mode, file_append ? "a" : "w"); if (strcmp(arg4,"bin") == 0 || strcmp(arg4,"grib") == 0) strcat(open_mode,"b"); nxny = nx*ny; *local = save = (struct local_struct *)malloc( sizeof(struct local_struct)); if (save == NULL) fatal_error("lola memory allocation ",""); if (x0 < 0.0) x0 += 360.0; if (x0 >= 360.0) x0 -= 360.0; if (x0 < 0.0 || x0 >= 360.0) fatal_error("-lola: bad initial longitude",""); if (nx <= 0) fatal_error_i("-lola: bad nlon %d", nx); save->nlon = nx; save->lon0 = x0; save->dlon = dx; if (y0 < -90.0 || y0 > 90.0) fatal_error("-lola: bad initial latitude",""); if (ny <= 0) fatal_error_i("-lola: bad nlat %d", ny); save->nlat = ny; save->lat0 = y0; save->dlat = dy; save->iptr = (int *) malloc(nx*ny * sizeof(int)); if (save->iptr == NULL) fatal_error("-lola: memory allocation",""); if ((save->out = ffopen(arg3,open_mode)) == NULL) fatal_error("lola could not open file %s", arg3); return 0; } /* cleanup phase */ if (mode == -2) return 0; /* processing phase */ save = *local; nx = save->nlon; ny = save->nlat; nxny = nx*ny; if (new_GDS) { // if (output_order != wesn) fatal_error("lola only works in we:sn order",""); if (lat == NULL || lon == NULL || data == NULL) fatal_error("lola: no val",""); /* find the nearest points for the grid */ closest_init(sec); k = 0; for (j = 0; j < ny; j++) { latitude = save->lat0 + j*save->dlat; for (i = 0; i < nx; i++) { longitude = save->lon0 + i*save->dlon; save->iptr[k++] = closest(sec, latitude, longitude); } } } if (strcmp(arg4,"spread") == 0) { k = 0; fprintf(save->out, "longitude, latitude, value,\n"); for (j = 0; j < ny; j++) { latitude = save->lat0 + j*save->dlat; for (i = 0; i < nx; i++) { t = save->iptr[k] >= 0 ? data[save->iptr[k]] : UNDEFINED; if (DEFINED_VAL(t)) { longitude = save->lon0 + i*save->dlon; if (longitude >= 360.0) longitude -= 360.0; fprintf(save->out, "%.6lf, %.6lf, %g,\n",longitude,latitude,t); } k++; } } } else if (strcmp(arg4,"bin") == 0) { i = nxny * sizeof(float); if (header) fwrite((void *) &i, sizeof(int), 1, save->out); for (i = 0; i < nxny; i++) { t = save->iptr[i] >= 0 ? data[save->iptr[i]] : UNDEFINED; fwrite(&t, sizeof(float), 1, save->out); } if (header) fwrite((void *) &i, sizeof(int), 1, save->out); } else if (strcmp(arg4,"text") == 0) { /* text output */ if (header == 1) { fprintf(save->out ,"%d %d\n", nx, ny); } for (i = 0; i < nxny; i++) { t = save->iptr[i] >= 0 ? data[save->iptr[i]] : UNDEFINED; fprintf(save->out, text_format, t); fprintf(save->out, ((i+1) % text_column) ? " " : "\n"); } } else if (strcmp(arg4,"grib") == 0) { /* make new_sec[] with new grid definition */ for (i = 0; i < 8; i++) new_sec[i] = sec[i]; new_sec[3] = sec3_lola(nx, save->lon0, save->dlon, ny, save->lat0, save->dlat, sec, NULL, NULL); /* get grid values */ tmp = (float *) malloc(nx*ny * sizeof (float)); if (tmp == NULL) fatal_error("-lola: memory allocation",""); for (i = 0; i < nxny; i++) tmp[i] = save->iptr[i] >= 0 ? data[save->iptr[i]] : UNDEFINED; grib_wrt(new_sec, tmp, nx*ny, nx, ny, use_scale, dec_scale, bin_scale, wanted_bits, max_bits, grib_type, save->out); free(tmp); } if (flush_mode) fflush(save->out); return 0; }
/* * HEADER:100:irr_grid:output:3:make irregular grid, nearest neighbor, X=lon-lat list Y=radius (km) Z=output grib file */ int f_irr_grid(ARG3) { int i, k, m; struct local_struct { int ngrid; double *lon_lat_list, radius; FILE *out; int *iptr; int last_GDS_change_no; }; struct local_struct *save; const char *t; unsigned char *p; double tmp; float *array; unsigned char *new_sec[8], *new_sec3; /* initialization phase */ if (mode == -1) { decode = latlon = 1; *local = save = (struct local_struct *)malloc( sizeof(struct local_struct)); if (save == NULL) fatal_error("irr_grid: memory allocation",""); /* count number of colons */ t = arg1; i = 0; while (*t) { if (*t++ == ':') i++; } if (i % 2 != 1) fatal_error("irr_grid: need lon0:lat0:lon1:lat1:..:lonN:latN",""); save->ngrid = (i + 1)/2; save->lon_lat_list = (double *) malloc(save->ngrid * 2 * sizeof(double)); save->iptr = (int *) malloc(save->ngrid * sizeof(int)); if (save->lon_lat_list == NULL || save->iptr == NULL ) fatal_error("irr_grid: memory allocation",""); t = arg1; k = sscanf(t, "%lf%n", &tmp, &m); if (k != 1) fatal_error("irr_grid: lat-lon list, %s",t); save->lon_lat_list[0] = tmp; t += m; for (i = 1; i < 2*save->ngrid; i++) { k = sscanf(t, ":%lf%n", &tmp, &m); if (k != 1) fatal_error("irr_grid: lat-lon list, %s",t); save->lon_lat_list[i] = tmp; t += m; } for (i = 0 ; i < save->ngrid; i++) { tmp = save->lon_lat_list[i*2]; if (tmp < 0.0) save->lon_lat_list[i*2] = tmp + 360.0; if (tmp > 360.0) save->lon_lat_list[i*2] = tmp - 360.0; if (fabs(save->lon_lat_list[i*2+1]) > 90.0) fatal_error("irr_grid: bad latitude",""); } if (sscanf(arg2,"%lf",&(save->radius)) != 1) fatal_error("irr_grid: radius %s", arg2); if ((save->out = ffopen(arg3, file_append ? "ab" : "wb" )) == NULL) fatal_error("irr_grid could not open file %s", arg3); } if (mode < 0) return 0; save = (struct local_struct *) *local; if (save->last_GDS_change_no != GDS_change_no) { save->last_GDS_change_no = GDS_change_no; if (lat == NULL || lon == NULL || data == NULL) fatal_error("irr_grid: no val",""); /* find the nearest points for the grid */ closest_init(sec); for (i = 0; i < save->ngrid; i++) { save->iptr[i] = closest(sec, save->lon_lat_list[i*2+1], save->lon_lat_list[i*2]); } } array = (float *) malloc(save->ngrid * sizeof(float)); new_sec3 = (unsigned char *) malloc((30+8*save->ngrid) * sizeof(unsigned char)); if (array == NULL || new_sec3 == NULL) fatal_error("irr_grid: memory allocation",""); /* sec3 = grid defintion */ uint_char(30+save->ngrid*8, new_sec3); new_sec3[4] = 3; // sec3 new_sec3[5] = 0; // use table 3.1 uint_char(save->ngrid, new_sec3+6); new_sec3[10] = 0; // no optional list octets new_sec3[11] = 0; uint2_char(130, new_sec3+12); p = code_table_3_2_location(sec); if (p == NULL) { // no earth descripition for (i = 14; i < 30; i++) { new_sec3[i] = 255; } } else { for (i = 14; i < 30; i++) { new_sec3[i] = p[i-14]; } } /* make new_sec[] with new grid definition */ for (i = 0; i < 8; i++) new_sec[i] = sec[i]; new_sec[3] = new_sec3; for (i = 0; i < save->ngrid; i++) { array[i] = save->iptr[i] >= 0 ? data[save->iptr[i]] : UNDEFINED; int_char( (int) (save->lon_lat_list[i*2+1] * 1000000.0), new_sec3 + 30 + i*8); uint_char( (int) (save->lon_lat_list[i*2] * 1000000.0), new_sec3 + 34 + i*8); } grib_wrt(new_sec, array, save->ngrid, save->ngrid, 1, use_scale, dec_scale, bin_scale, wanted_bits, max_bits, grib_type, save->out); free(array); free(new_sec3); return 0; }