void wbc_mzrm ( char *states, char *ststr, int *len1, int *iret ) /************************************************************************ * wbc_mzrm * * * * This function removes the specific marine zones listed above from * * the state id string. * * * * wbc_mzrm ( states, len1, len2, stzstr, sttstr, iret ) * * * * Input parameters: * * *states char String of state ids * * * * Output parameters: * * *ststr char States id string; no Mar. Zones * * *len1 int Length of ststr * * *iret int Return Code * * * ** * * Log: * * A. Hardy/NCEP 5/03 * * A. Hardy/NCEP 9/04 Added "SL" * * T. Piper/SAIC 02/05 Removed unused variable 'stnam' * ***********************************************************************/ { int ii, ier, ilen, ipos; /*-------------------------------------------------------------------*/ *iret = 0; ier = 0; ststr[0] = '\0'; /* * Remove unwanted marine zones listed above from state strings. */ ii = 0; while ( ( ii < NUM_ZNS ) ) { cst_rmst ( states, _mzones[ii], &ipos, states, &ier); if ( ipos > 0 ) { cst_rxbl ( states, states, &ilen, &ier); } ii++; } cst_lstr ( states, &ilen, &ier ); cst_ncpy ( ststr, states, ilen, &ier ); }
static void gemInfo_init( Geminfo* const gemInfo, Gribmsg* const gribMsg) { gb2_2gem(&curr_g2, &curr_gem, tbllist, &ier); if (ier != 0) { sprintf(g2name,"UNK\0"); sprintf(levelstmp,"LVL\0"); sprintf(fdats,"FHRS\0"); } else { sprintf(g2name,"%s\0",curr_gem.parm); cst_rmbl (g2name, g2name, &ilen, &ier ); if ( n > 0 ) strncat ( prods, ";", 1); sprintf(prods+strlen(prods),"%s\0",g2name); strptr[0] = (char *)malloc(12); cst_itoc ( &curr_gem.vcord, 1, (char **)(&strptr), &ier); cst_rxbl (curr_gem.unit, curr_gem.unit, &ilen, &ier); if ( ilen == 0 ) sprintf (curr_gem.unit, "-\0"); if ( curr_gem.level[1] == -1 ) sprintf(levelstmp,"%d %s %s\0",curr_gem.level[0],curr_gem.unit,strptr[0]); else sprintf(levelstmp,"%d-%d %s %s\0",curr_gem.level[0],curr_gem.level[1],curr_gem.unit,strptr[0]); cst_rmbl (curr_gem.gdattm1, curr_gem.gdattm1, &ilen, &ier ); cst_rmbl (curr_gem.gdattm2, curr_gem.gdattm2, &ilen, &ier ); if ( ilen > 0 ) sprintf(fdats,"%s-%s\0",curr_gem.gdattm1,curr_gem.gdattm2); else sprintf(fdats,"%s\0",curr_gem.gdattm1); ilen = 1; while ( ilen > 0 ) cst_rmst(fdats, "/", &ilen, fdats, &ier); free(strptr[0]); } }
int main (int argc , char **argv) /************************************************************************ * main * * * * Main program of createbinfo. * * * * Output (from printf) must be re-directed to the proper info file * * within the script. * * * * main(argc, argv) * * * * Input parameters: * * argc int number of parameters of command line * * argv char** parameter array of command line * * * * Output parameters: * * Return parameters: * * NONE * * * ** * * Log: * * D.W.Plummer/NCEP 12/98 * * T. Piper/GSC 8/00 Modified for new generic boundary info * * D.W.Plummer/NCEP 6/05 Incr accuracy from 2 decimal digits to 4* ***********************************************************************/ { char buff[256], id[7], name[64]; int i, ier, ilat, ilon, k, length, nparts, nptot, npts, num, pst; float fltptr[20], lat1, lat2, lon1, lon2, minlat, minlon, maxlat, maxlon; FILE *fp; long lpos, lposp; Bnd_t boundary; /*---------------------------------------------------------------------*/ /* * Print out the name of the BOUNDARY file. */ boundary.filename = (char *)malloc( sizeof(char) * strlen(argv[1]) + 1); strcpy ( boundary.filename, argv[1] ); printf("!\n! BOUNDARIES FILENAME \n%s\n!\n", boundary.filename ); fp = (FILE *)cfl_tbop ( boundary.filename, "bounds", &ier ); /* * Allocate and initialize boundary location structure */ boundary.nbnd = 0; boundary.bound = (BInfo_t *)malloc(MAX_BOUNDS*sizeof(BInfo_t)); for ( i = 0; i < MAX_BOUNDS; i++ ) { boundary.bound[i].name = (char *)malloc( sizeof(char) * MAX_NAMELEN + 1); boundary.bound[i].name[0] = '\0'; boundary.bound[i].info = (char *)malloc( sizeof(char) * MAX_NAMELEN + 1); boundary.bound[i].info[0] = '\0'; boundary.bound[i].strec = 0; boundary.bound[i].cenlat = RMISSD; boundary.bound[i].cenlon = RMISSD; boundary.bound[i].minlat = RMISSD; boundary.bound[i].minlon = RMISSD; boundary.bound[i].maxlat = RMISSD; boundary.bound[i].maxlon = RMISSD; boundary.bound[i].nparts = 0; } cfl_wher ( fp, &lpos, &ier ); cfl_trln ( fp, sizeof(buff), buff, &ier ); if ( ier == 0 ) { sscanf ( buff, "%s %s %d %d %d", id, name, &ilat, &ilon, &nparts ); boundary.bound[0].bndspt = (Bndsprt_t *)malloc(nparts*sizeof(Bndsprt_t)); /* Read the second header line */ cfl_trln ( fp, sizeof(buff), buff, &ier ); strcpy ( boundary.bound[0].info, buff); for ( k = 0; k < nparts; k++ ) { cfl_wher ( fp, &lposp, &ier ); cfl_trln ( fp, sizeof(buff), buff, &ier ); sscanf ( buff, "%d %f %f %f %f", &npts, &lat1, &lat2, &lon1, &lon2 ); boundary.bound[0].bndspt[k].minlat = G_MIN ( lat1, lat2 ); boundary.bound[0].bndspt[k].maxlat = G_MAX ( lat1, lat2 ); boundary.bound[0].bndspt[k].minlon = G_MIN ( lon1, lon2 ); boundary.bound[0].bndspt[k].maxlon = G_MAX ( lon1, lon2 ); boundary.bound[0].bndspt[k].strec = lposp; boundary.bound[0].bndspt[k].npts = npts / 2; cst_rxbl ( buff, buff, &length, &ier ); cst_rlst ( buff, ' ', RMISSD, (int) (sizeof(fltptr)/sizeof(float)), fltptr, &num, &ier); nptot = ( num - 5 ); while ( ier == 0 && nptot < npts ) { cfl_trln ( fp, sizeof(buff), buff, &ier ); if ( ier == 0 ) { cst_rxbl ( buff, buff, &length, &ier ); cst_rlst ( buff, ' ', RMISSD, sizeof(fltptr)/sizeof(float), fltptr, &num, &ier); nptot += num; } /* Loop over all points in one part */ } } /* Loop over all parts in one bound */ if ( ier == 0 ) { strcpy ( boundary.bound[0].name, name ); boundary.bound[0].strec = lpos; boundary.bound[0].cenlat = ilat / 100.0; boundary.bound[0].cenlon = ilon / 100.0; boundary.bound[0].nparts = nparts; boundary.nbnd++; } } while ( ier == 0 ) { cfl_wher ( fp, &lpos, &ier ); cfl_trln ( fp, sizeof(buff), buff, &ier ); if ( ier == 0 ) { boundary.nbnd++; pst = boundary.nbnd - 1; sscanf ( buff, "%s %s %d %d %d", id, name, &ilat, &ilon, &nparts ); strcpy ( boundary.bound[pst].name, name ); boundary.bound[pst].strec = lpos; boundary.bound[pst].cenlat = ilat / 100.0; boundary.bound[pst].cenlon = ilon / 100.0; boundary.bound[pst].nparts = nparts; /* Read the second header line */ cfl_trln ( fp, sizeof(buff), buff, &ier ); strcpy ( boundary.bound[pst].info, buff); boundary.bound[pst].bndspt = (Bndsprt_t *)malloc(nparts*sizeof(Bndsprt_t)); for ( k = 0; k < nparts; k++ ) { cfl_wher ( fp, &lposp, &ier ); cfl_trln ( fp, sizeof(buff), buff, &ier ); sscanf ( buff, "%d %f %f %f %f", &npts, &lat1, &lat2, &lon1, &lon2 ); boundary.bound[pst].bndspt[k].minlat = G_MIN(lat1,lat2); boundary.bound[pst].bndspt[k].maxlat = G_MAX(lat1,lat2); boundary.bound[pst].bndspt[k].minlon = G_MIN(lon1,lon2); boundary.bound[pst].bndspt[k].maxlon = G_MAX(lon1,lon2); boundary.bound[pst].bndspt[k].strec = lposp; boundary.bound[pst].bndspt[k].npts = npts / 2; cst_rxbl( buff, buff, &length, &ier ); cst_rlst( buff, ' ', RMISSD, (int) (sizeof(fltptr)/sizeof(float)), fltptr, &num, &ier); nptot = ( num - 5 ); while ( ier == 0 && nptot < npts ) { cfl_trln ( fp, sizeof(buff), buff, &ier ); if ( ier == 0 ) { cst_rxbl ( buff, buff, &length, &ier ); cst_rlst ( buff, ' ', RMISSD, sizeof(fltptr)/sizeof(float), fltptr, &num, &ier); nptot += num; } } } } } boundary.maxpts = 0; for ( i = 0; i < boundary.nbnd; i++ ) { minlat = 90.0; minlon = 360.0; maxlat = -90.0; maxlon = -360.0; for ( k = 0; k < boundary.bound[i].nparts; k++ ) { minlat=G_MIN ( minlat, boundary.bound[i].bndspt[k].minlat ); minlon=G_MIN ( minlon, boundary.bound[i].bndspt[k].minlon ); maxlat=G_MAX ( maxlat, boundary.bound[i].bndspt[k].maxlat ); maxlon=G_MAX ( maxlon, boundary.bound[i].bndspt[k].maxlon ); boundary.maxpts = G_MAX ( boundary.maxpts, boundary.bound[i].bndspt[k].npts ); } boundary.bound[i].minlat = minlat; boundary.bound[i].minlon = minlon; boundary.bound[i].maxlat = maxlat; boundary.bound[i].maxlon = maxlon; } /* * Print out number of bounds. */ printf("! TOTAL NUMBER OF BOUNDS\n%d\n!\n", boundary.nbnd ); printf("! MAX NUMBER OF POINTS per BOUND\n%d\n!\n", boundary.maxpts ); printf("! BOUNDARY STRUCTURE INFORMATION\n!\n" ); /* * Dump the information. */ for ( i = 0; i < boundary.nbnd; i++ ) { printf("!\n%-s %-12ld %-.2f %-.2f %-.2f %-.2f %-.2f %-.2f %-5d\n", boundary.bound[i].name, boundary.bound[i].strec, boundary.bound[i].cenlat, boundary.bound[i].cenlon, boundary.bound[i].minlat, boundary.bound[i].minlon, boundary.bound[i].maxlat, boundary.bound[i].maxlon, boundary.bound[i].nparts ); printf("%s\n", boundary.bound[i].info); for ( k = 0; k < boundary.bound[i].nparts; k++ ) { printf("\t%-12ld %-.2f %-.2f %-.2f %-.2f %-8d \n", boundary.bound[i].bndspt[k].strec, boundary.bound[i].bndspt[k].minlat, boundary.bound[i].bndspt[k].minlon, boundary.bound[i].bndspt[k].maxlat, boundary.bound[i].bndspt[k].maxlon, boundary.bound[i].bndspt[k].npts ); } } return(0); }
/** * Generates an LDM product-identifier from a GRIB edition 2 message. * * Atomic, * Idempotent, * Not thread-safe * * @param[in] data Pointer to the GRIB message. * @param[in] sz Length of the GRIB message in bytes. * @param[in] wmohead Pointer to the associated WMO header string. * @param[out] ident Pointer to a buffer to receive the LDM * product-identifier. * @param[in] identSize Size of the \c ident buffer in bytes. * @retval 0 Success. \c ident is set and NUL-terminated. * @retval 1 Invalid GRIB message. * @retval 2 GRIB message isn't edition 2. * @retval 3 System error. */ int grib2name ( char* const data, const size_t sz, const char* const wmohead, char* const ident, const size_t identSize) { #if USE_GRIB2_DECODER int status; DecodedGrib2Msg* decoded; if (status = g2d_new(&decoded, (unsigned char*)data, sz)) { log_add("Couldn't decode GRIB message"); status = G2D_INVALID == status ? 1 : G2D_NOT_2 ? 2 : 3; } else { if (status = setIdent(ident, identSize, decoded, wmohead)) { log_add("Couldn't set LDM product-identifier"); status = 1; } g2d_free(decoded); } /* "decoded" allocated */ return status; #else static StringBuf* paramNames; /* Buffer for parameter name(s) */ int iField; /* GRIB-2 field index */ int status; /* Function return code */ g2int listsec0[3]; /* GRIB-2 section 0 parameters */ g2int listsec1[13]; /* GRIB-2 section 1 parameters */ g2int numlocal; /* Number of GRIB section 2-s */ int model_id; /* ID of model */ int grid_id; /* ID of grid */ char fdats[80]; /* No idea */ char levelstmp[80]; /* Level? */ Gribmsg g2Msg; /* GRIB-2 message structure */ if (paramNames) { strBuf_clear(paramNames); } else { paramNames = strBuf_new(127); if (NULL == paramNames) { log_add("Couldn't allocate buffer for parameter name(s)"); return 3; } } g2Msg.cgrib2 = (unsigned char*)data; g2Msg.mlength = sz; g2Msg.gfld = NULL; g2Msg.field_tot = 0; if ((status = g2_info(g2Msg.cgrib2, g2Msg.mlength, listsec0, listsec1, &(g2Msg.field_tot), &numlocal)) != 0) return (2 == status) ? 2 : 1; if (g2Msg.field_tot <= 0) { log_add("GRIB-2 message has no data fields"); return 1; } for (iField = 0; iField < g2Msg.field_tot; iField++) { static char g2tables[5][LLMXLN]; /* GRIB tables */ static char* tbllist[5] = {g2tables[0], g2tables[1], g2tables[2], g2tables[3], g2tables[4]}; /* Addresses of GRIB tables */ Geminfo gemInfo; /* GEMPAK structure */ int const lastField = iField == g2Msg.field_tot - 1; status = g2_getfld(g2Msg.cgrib2, g2Msg.mlength, iField+1, 0, 0, &g2Msg.gfld); if (status) { log_add("Invalid GRIB-2 message: g2_getfld() status=%d", status); return (2 == status) ? 2 : 1; } /* "g2Msg.gfld" is allocated */ /* Initialize strings in Geminfo structure */ (void)memset(gemInfo.cproj, 0, sizeof(gemInfo.cproj)); (void)memset(gemInfo.parm, 0, sizeof(gemInfo.parm)); (void)memset(gemInfo.gdattm1, 0, sizeof(gemInfo.gdattm1)); (void)memset(gemInfo.gdattm2, 0, sizeof(gemInfo.gdattm2)); /* * In the original code, the last field determined the model ID. */ if (lastField) model_id = g2Msg.gfld->ipdtmpl[4]; /* * This assignment to "grid_id" isn't under the above "lastField" * conditional because "decode_g2gnum()" might have side-effects upon * which "gb2_2gem()" depends. */ grid_id = (g2Msg.gfld->griddef == 0) ? decode_g2gnum(g2Msg.gfld) : g2Msg.gfld->griddef; gb2_2gem(&g2Msg, &gemInfo, tbllist, &status); if (status) { log_add("Couldn't decode GRIB2 message. WMO header=\"%s\"", wmohead); log_flush_error(); if (lastField) { (void)strcpy(fdats, "FHRS"); /* safe */ (void)strcpy(levelstmp, "LVL"); /* safe */ } } else { char g2name[13]; /**< Name of product/parameter */ int ilen; /**< Length of resulting string */ (void)strcpy(g2name, gemInfo.parm); /* both 13 bytes */ cst_rmbl(g2name, g2name, &ilen, &status); if (iField) strBuf_appendString(paramNames, ";"); strBuf_appendString(paramNames, g2name); cst_rxbl(gemInfo.unit, gemInfo.unit, &ilen, &status); if (ilen == 0) (void)strcpy(gemInfo.unit, "-"); /* safe */ cst_rmbl(gemInfo.gdattm1, gemInfo.gdattm1, &ilen, &status); cst_rmbl(gemInfo.gdattm2, gemInfo.gdattm2, &ilen, &status); /* * In the original code, the last field determined the following * parameters. */ if (lastField) { static char strBuf[5]; /* Holds 4-char string */ static char* strptr = strBuf; /* For "cst_itoc()" */ if (ilen > 0) (void)snprintf(fdats, sizeof(fdats), "%s-%s", gemInfo.gdattm1, gemInfo.gdattm2); else (void)snprintf(fdats, sizeof(fdats), "%s", gemInfo.gdattm1); for (ilen = 1; ilen > 0; cst_rmst(fdats, "/", &ilen, fdats, &status)); cst_itoc(&gemInfo.vcord, 1, &strptr, &status); if (gemInfo.level[1] == -1) (void)snprintf(levelstmp, sizeof(levelstmp), "%d %s %s", gemInfo.level[0], gemInfo.unit, strptr); else (void)snprintf(levelstmp, sizeof(levelstmp), "%d-%d %s %s", gemInfo.level[0], gemInfo.level[1], gemInfo.unit, strptr); } } g2_free(g2Msg.gfld); g2Msg.gfld = NULL; } /* * See if the WMO header can be used for grid 0 products */ if ((grid_id == 0) && (strlen(wmohead) > 11) && (wmohead[7] == 'K') && (wmohead[8] == 'W')) { int wmoGridId = wmo_to_gridid(&wmohead[0], &wmohead[2]); if (wmoGridId > 0) grid_id = wmoGridId; } (void)snprintf(ident, identSize, "grib2/%s/%s/#%03d/%s/%s/%s", s_pds_center((int)listsec1[0], (int)listsec1[1]), s_pds_model((int)listsec1[0], model_id), grid_id, fdats, strBuf_toString(paramNames), levelstmp); return 0; #endif }
void grib2name ( char *filename, int seqno, char *data, size_t sz, char *ident ) { int i, n, ier, ilen; int unpack=0, expand=0; g2int listsec0[3],listsec1[13],numlocal; int model_id, grid_id; char g2name[13], fdats[80]; char prodtmp[255]; char levelstmp[80]; char prods[128]; static char datyp[]="grib2", slashstr[]="/"; static int tblinit=0; static char *strptr[5]; Gribmsg curr_g2; Geminfo curr_gem; static char g2tables[5][LLMXLN] = { 0 }, *tbllist[5]; curr_g2.cgrib2 = (unsigned char *)data; curr_g2.mlength = sz; curr_g2.gfld = NULL; curr_g2.field_tot = 0; if ( !tblinit) { for (i = 0; i < 5; i++) tbllist[i] = g2tables[i]; tblinit = !0; } /* modify below to pass message size as a failsafe check */ /*if ( ( ier = g2_info ( curr_g2.cgrib2, listsec0,listsec1, &(curr_g2.field_tot), &numlocal) ) != 0 ) */ if ( ( ier = g2_info ( curr_g2.cgrib2, curr_g2.mlength, listsec0,listsec1, &(curr_g2.field_tot), &numlocal) ) != 0 ) return; prods[0] = '\0'; for ( n=0; n < curr_g2.field_tot; n++) { ier=g2_getfld( curr_g2.cgrib2, curr_g2.mlength, n+1, unpack, expand, &curr_g2.gfld); /* initialize strings in geminfo structure */ memset ( curr_gem.cproj, 0, sizeof(curr_gem.cproj)); memset ( curr_gem.parm, 0, sizeof(curr_gem.parm)); memset ( curr_gem.gdattm1, 0, sizeof(curr_gem.gdattm1)); memset ( curr_gem.gdattm2, 0, sizeof(curr_gem.gdattm2)); model_id = curr_g2.gfld->ipdtmpl[4]; grid_id = curr_g2.gfld->griddef; gb2_2gem (&curr_g2, &curr_gem, tbllist, &ier); if ( ier != 0 ) { sprintf(g2name,"UNK\0"); sprintf(levelstmp,"LVL\0"); sprintf(fdats,"FHRS\0"); } else { sprintf(g2name,"%s\0",curr_gem.parm); cst_rmbl (g2name, g2name, &ilen, &ier ); if ( n > 0 ) strncat ( prods, ";", 1); sprintf(prods+strlen(prods),"%s\0",g2name); strptr[0] = (char *)malloc(12); cst_itoc ( &curr_gem.vcord, 1, (char **)(&strptr), &ier); cst_rxbl (curr_gem.unit, curr_gem.unit, &ilen, &ier); if ( ilen == 0 ) sprintf (curr_gem.unit, "-\0"); if ( curr_gem.level[1] == -1 ) sprintf(levelstmp,"%d %s %s\0",curr_gem.level[0],curr_gem.unit,strptr[0]); else sprintf(levelstmp,"%d-%d %s %s\0",curr_gem.level[0],curr_gem.level[1],curr_gem.unit,strptr[0]); cst_rmbl (curr_gem.gdattm1, curr_gem.gdattm1, &ilen, &ier ); cst_rmbl (curr_gem.gdattm2, curr_gem.gdattm2, &ilen, &ier ); if ( ilen > 0 ) sprintf(fdats,"%s-%s\0",curr_gem.gdattm1,curr_gem.gdattm2); else sprintf(fdats,"%s\0",curr_gem.gdattm1); ilen = 1; while ( ilen > 0 ) cst_rmst(fdats, slashstr, &ilen, fdats, &ier); free(strptr[0]); } g2_free(curr_g2.gfld); curr_g2.gfld = NULL; } sprintf(prodtmp,"%s/%s/%s/#%03d/%s/%s/%s! %06d\0", datyp, s_pds_center((int)listsec1[0],(int)listsec1[1]), s_pds_model((int)listsec1[0],model_id), grid_id, fdats, prods, levelstmp,seqno); if(strlen(filename) < 253) { strcpy(ident,filename); strncat(ident," !",2); strncat(ident,prodtmp,253-strlen(filename)); } else { strncpy(ident,filename,255); ident[255] = '\0'; } return; }