[2759] | 1 | /* FILENAME: gribputpds.c */ |
---|
| 2 | #include <stdio.h> |
---|
| 3 | #include <stdlib.h> |
---|
| 4 | #include <string.h> |
---|
| 5 | #include <stdlib.h> |
---|
| 6 | #ifdef XT3_Catamount |
---|
| 7 | #include <features.h> |
---|
| 8 | #else |
---|
| 9 | #include <netinet/in.h> |
---|
| 10 | #endif |
---|
| 11 | #include "dprints.h" /* for dprints */ |
---|
| 12 | #include "gribfuncs.h" /* prototypes */ |
---|
| 13 | |
---|
| 14 | /* |
---|
| 15 | * |
---|
| 16 | **************************************************************************** |
---|
| 17 | * A. FUNCTION: gribputpds |
---|
| 18 | * Use the information provided to create a Product Defn Section of |
---|
| 19 | * the GRIB format and store it in the GRIB_HDR structure; |
---|
| 20 | * |
---|
| 21 | * INTERFACE: |
---|
| 22 | * int gribputpds (Data_Input, User_Input, pPDS_Input, ppgrib_hdr, errmsg) |
---|
| 23 | * |
---|
| 24 | * ARGUMENTS (I=input, O=output, I&O=input and output): |
---|
| 25 | * (I) DATA_INPUT Data_Input; |
---|
| 26 | * Structure containing info of this field (ids used in the Sections) |
---|
| 27 | * (I) USER_INPUT User_Input; |
---|
| 28 | * Structure containing encoder configuration data |
---|
| 29 | * (O) PDS_INPUT *pPDS_Input; |
---|
| 30 | * points to an empty Structure; to be filled with PDS info |
---|
| 31 | * retrieved from Data_Input and User_Input. |
---|
| 32 | * (I&O) GRIB_HDR **ppgrib_hdr; |
---|
| 33 | * points to Grib Header Structure; May already have 1 or more |
---|
| 34 | * GRIB sections in it; Will have PDS appended to its 'entire_msg', |
---|
| 35 | * 'pds_ptr', 'pds_len' and 'mesg_len' updated also. |
---|
| 36 | * (O) char *errmsg; |
---|
| 37 | * empty array, returned filled if error occurred |
---|
| 38 | * |
---|
| 39 | * RETURN CODE: |
---|
| 40 | * 0> no errors; |
---|
| 41 | * Grib Header structure now has PDS newly appended to its |
---|
| 42 | * entire_msg buffer, its sections length, message length, |
---|
| 43 | * and section pointers are updated. |
---|
| 44 | * 1> error, errmsg filled; |
---|
| 45 | * failed to make storage for PDS_GRIB, or |
---|
| 46 | * failed to enlarge 'entire_msg' to hold new PDS block; |
---|
| 47 | * 99> error in create_inpPDS() or inp2grib_PDS(); errmsg filled; |
---|
| 48 | ****************************************************************************/ |
---|
| 49 | |
---|
| 50 | #if PROTOTYPE_NEEDED |
---|
| 51 | int gribputpds ( DATA_INPUT Data_Input, |
---|
| 52 | USER_INPUT User_Input, |
---|
| 53 | PDS_INPUT *pPDS_Input, |
---|
| 54 | GRIB_HDR **ppgrib_hdr, |
---|
| 55 | char *errmsg) |
---|
| 56 | #else |
---|
| 57 | int gribputpds ( Data_Input, User_Input, pPDS_Input, ppgrib_hdr, errmsg) |
---|
| 58 | DATA_INPUT Data_Input; |
---|
| 59 | USER_INPUT User_Input; |
---|
| 60 | PDS_INPUT *pPDS_Input; |
---|
| 61 | GRIB_HDR **ppgrib_hdr; |
---|
| 62 | char *errmsg; |
---|
| 63 | #endif |
---|
| 64 | { |
---|
| 65 | PDS_GRIB *pPDS_Grib=0; /* true GRIB format for pds */ |
---|
| 66 | GRIB_HDR *gh; /* working var */ |
---|
| 67 | int stat= 0; /* status */ |
---|
| 68 | long newsize=0L; /* size of msg after adding PDS block */ |
---|
| 69 | /*void create_inpPDS (); |
---|
| 70 | int inp2grib_PDS ();*/ |
---|
| 71 | char *func= "GribPutPDS"; |
---|
| 72 | |
---|
| 73 | DPRINT1("\nEntering %s()......\n", func); |
---|
| 74 | /* |
---|
| 75 | * |
---|
| 76 | * A.1 FUNCTION create_inpPDS !void |
---|
| 77 | * !create internal struct PDS_INPUT from DATA_INPUT & USER_INPUT |
---|
| 78 | */ |
---|
| 79 | create_inpPDS (Data_Input, User_Input, pPDS_Input); |
---|
| 80 | |
---|
| 81 | /* |
---|
| 82 | * |
---|
| 83 | * A.2 MALLOC local struct PDS_GRIB, clear it out; |
---|
| 84 | * IF (fails) THEN |
---|
| 85 | * SET bad stat |
---|
| 86 | * RETURN |
---|
| 87 | * ELSE |
---|
| 88 | * CLEAR out the struct |
---|
| 89 | * ENDIF |
---|
| 90 | */ |
---|
| 91 | if ( !(pPDS_Grib= (PDS_GRIB *)malloc(sizeof(PDS_GRIB))) ) |
---|
| 92 | { |
---|
| 93 | sprintf(errmsg,"%s: failed storage for PDS_GRIB\n",func); |
---|
| 94 | stat=1; goto BYE; |
---|
| 95 | } |
---|
| 96 | else memset ((void *)pPDS_Grib, '\0', sizeof(PDS_GRIB)); |
---|
| 97 | |
---|
| 98 | /* |
---|
| 99 | * |
---|
| 100 | * A.3 FUNCTION inp2grib_PDS |
---|
| 101 | * !convert internal PDS_INPUT to true Grib format PDS_GRIB |
---|
| 102 | * IF (error) THEN |
---|
| 103 | * SAVE error from func in stat |
---|
| 104 | * RETURN |
---|
| 105 | * ENDIF |
---|
| 106 | */ |
---|
| 107 | if (stat = inp2grib_PDS (pPDS_Input, &pPDS_Grib, errmsg)) |
---|
| 108 | { upd_child_errmsg (func, errmsg); |
---|
| 109 | goto BYE; |
---|
| 110 | } |
---|
| 111 | /* |
---|
| 112 | * |
---|
| 113 | * A.4 CALCULATE new msg length after adding new PDS |
---|
| 114 | */ |
---|
| 115 | DPRINT0("putting Pds into Grib Hdr struct\n"); |
---|
| 116 | |
---|
| 117 | gh= *ppgrib_hdr; |
---|
| 118 | newsize= gh->msg_length + sizeof(PDS_GRIB); |
---|
| 119 | |
---|
| 120 | /* |
---|
| 121 | * |
---|
| 122 | * A.5 IF gribhdr's buffer is too small AND |
---|
| 123 | * FUCTION Expand_gribhdr failed |
---|
| 124 | * THEN |
---|
| 125 | * SET stat = 1 |
---|
| 126 | * RETURN with error !errmsg filled |
---|
| 127 | * ENDIF |
---|
| 128 | */ |
---|
| 129 | if (newsize > gh->abs_size |
---|
| 130 | && Expand_gribhdr (gh, newsize, errmsg) !=0) |
---|
| 131 | { |
---|
| 132 | stat = 1; |
---|
| 133 | upd_child_errmsg (func, errmsg); |
---|
| 134 | goto BYE; |
---|
| 135 | } |
---|
| 136 | |
---|
| 137 | /* |
---|
| 138 | * |
---|
| 139 | * A.6 COPY Pds and its info into Grib Header |
---|
| 140 | * !copy PDS_GRIB struct to the end of Entire_msg array; |
---|
| 141 | * !store pds pointer and length |
---|
| 142 | * !update msg length |
---|
| 143 | */ |
---|
| 144 | gh->pds_ptr= gh->entire_msg + gh->msg_length; |
---|
| 145 | memcpy ((void *) gh->pds_ptr, (void *) pPDS_Grib, sizeof (PDS_GRIB)); |
---|
| 146 | gh->pds_len = sizeof(PDS_GRIB); |
---|
| 147 | gh->msg_length += gh->pds_len; |
---|
| 148 | |
---|
| 149 | DPRINT1 ("copied PDS_GRIB(%ld) bytes from pPDS_Grib to PDS_PTR\n", |
---|
| 150 | sizeof(PDS_GRIB)); |
---|
| 151 | |
---|
| 152 | /* |
---|
| 153 | * |
---|
| 154 | * A.7 FREE up local struct PDS_GRIB |
---|
| 155 | * |
---|
| 156 | * A.8 RETURN to caller with stat |
---|
| 157 | */ |
---|
| 158 | BYE: |
---|
| 159 | if (pPDS_Grib!=NULL) free (pPDS_Grib); |
---|
| 160 | DPRINT2 ("Leaving %s(), stat=%d\n", func,stat); |
---|
| 161 | return stat; |
---|
| 162 | /* |
---|
| 163 | * |
---|
| 164 | * END OF FUNCTION |
---|
| 165 | * |
---|
| 166 | * |
---|
| 167 | */ |
---|
| 168 | } |
---|
| 169 | |
---|
| 170 | /* |
---|
| 171 | * |
---|
| 172 | ********************************************************************* |
---|
| 173 | * B. FUNCTION: create_inpPDS |
---|
| 174 | * Fill the internal Product Defn Section structure with info |
---|
| 175 | * retrieved from the 2 input structures DATA_INPUT and USER_INPUT. |
---|
| 176 | * |
---|
| 177 | * INTERFACE: |
---|
| 178 | * void create_inpPDS (Data_Input, User_Input, pPDS_Input) |
---|
| 179 | * |
---|
| 180 | * ARGUMENTS (I=input, O=output, I&O=input and output): |
---|
| 181 | * (I) DATA_INPUT Data_Input; holds ids to be used in Sections |
---|
| 182 | * (I) USER_INPUT User_Input; holds encoder configuration info |
---|
| 183 | * (O) PDS_INPUT *pPDS_Input; pre-allocated structure to be filled; |
---|
| 184 | * |
---|
| 185 | * RETURN CODE: none; |
---|
| 186 | ********************************************************************** |
---|
| 187 | */ |
---|
| 188 | #if PROTOTYPE_NEEDED |
---|
| 189 | void create_inpPDS ( DATA_INPUT Data_Input, USER_INPUT User_Input, |
---|
| 190 | PDS_INPUT *pPDS_Input) |
---|
| 191 | #else |
---|
| 192 | void create_inpPDS ( Data_Input, User_Input, pPDS_Input) |
---|
| 193 | DATA_INPUT Data_Input; |
---|
| 194 | USER_INPUT User_Input; |
---|
| 195 | PDS_INPUT *pPDS_Input; |
---|
| 196 | #endif |
---|
| 197 | { |
---|
| 198 | int i; |
---|
| 199 | |
---|
| 200 | DPRINT0 ( "Entering create_inpPDS ()\n" ); |
---|
| 201 | /* |
---|
| 202 | * |
---|
| 203 | * B.1 LOAD info from struct USER_INPUT into struct PDS_INPUT |
---|
| 204 | */ |
---|
| 205 | |
---|
| 206 | /* assigns the values from USER_INPUT to PDS_Input */ |
---|
| 207 | pPDS_Input->usEd_num = (unsigned short) 1; /* GRIB Edition num */ |
---|
| 208 | pPDS_Input->usParm_tbl = User_Input.usParm_tbl; /* GRIB TblVersion num */ |
---|
| 209 | pPDS_Input->usSub_tbl = User_Input.usSub_tbl; /* Local TblVersion num */ |
---|
| 210 | pPDS_Input->usCenter_id = User_Input.usCenter_id; /* Originating Ctr-Tbl0*/ |
---|
| 211 | pPDS_Input->usProc_id = Data_Input.usProc_id; /* Model id */ |
---|
| 212 | pPDS_Input->usGrid_id = Data_Input.usGrid_id; /* Grid id num */ |
---|
| 213 | pPDS_Input->usGds_bms_id = User_Input.usGds_bms_id; /* GDS/BMS flag-Tbl1 */ |
---|
| 214 | pPDS_Input->usParm_id = Data_Input.usParm_id; /* Parameter& Units id -Tbl2 */ |
---|
| 215 | pPDS_Input->usParm_sub = Data_Input.usParm_sub_id;/* Sub-Tblentry for Tbl2 */ |
---|
| 216 | pPDS_Input->usLevel_id = Data_Input.usLevel_id; /* Type of level/layer-Tbl3*/ /* Height, pressure of level 1 and 2 */ |
---|
| 217 | pPDS_Input->usHeight1 =(unsigned short)Data_Input.nLvl_1 ; |
---|
| 218 | pPDS_Input->usHeight2 =(unsigned short)Data_Input.nLvl_2 ; |
---|
| 219 | pPDS_Input->usYear =(unsigned short)( Data_Input.nYear % 100 ); /* Year */ |
---|
| 220 | pPDS_Input->usMonth =(unsigned short)Data_Input.nMonth; /* Month */ |
---|
| 221 | pPDS_Input->usDay =(unsigned short)Data_Input.nDay;/* Day of month */ |
---|
| 222 | pPDS_Input->usHour =(unsigned short)Data_Input.nHour; /* Hour of day */ |
---|
| 223 | pPDS_Input->usMinute =(unsigned short)Data_Input.nMinute; /* Minute of hour*/ |
---|
| 224 | pPDS_Input->usSecond =(unsigned short)Data_Input.nSecond; /* Secs of Min */ |
---|
| 225 | pPDS_Input->usFcst_unit_id = Data_Input.usFcst_id; /*ForecastTime unit-Tbl4*/ |
---|
| 226 | /* Period of time (tau)- 0 for analysis */ |
---|
| 227 | pPDS_Input->usP1 = Data_Input.usFcst_per1; |
---|
| 228 | /* Period of time between analyses */ |
---|
| 229 | pPDS_Input->usP2 = Data_Input.usFcst_per2; |
---|
| 230 | /* Time range indicator-Tbl5 */ |
---|
| 231 | pPDS_Input->usTime_range = Data_Input.usTime_range_id; |
---|
| 232 | /* Num in average */ |
---|
| 233 | pPDS_Input->usTime_range_avg = Data_Input.usTime_range_avg; |
---|
| 234 | /* Num missing from average */ |
---|
| 235 | pPDS_Input->usTime_range_mis = Data_Input.usTime_range_mis; |
---|
| 236 | |
---|
| 237 | /* Century of reference time */ |
---|
| 238 | if (Data_Input.nYear % 100 == 0) { |
---|
| 239 | pPDS_Input->usCentury = (unsigned short)( Data_Input.nYear / 100 ); |
---|
| 240 | pPDS_Input->usYear += 100; |
---|
| 241 | } else { |
---|
| 242 | pPDS_Input->usCentury =(unsigned short)( Data_Input.nYear / 100 + 1); |
---|
| 243 | } |
---|
| 244 | |
---|
| 245 | /* Decimal scale factor */ |
---|
| 246 | pPDS_Input->sDec_sc_fctr = (short) Data_Input.nDec_sc_fctr; |
---|
| 247 | /* reserved bytes */ |
---|
| 248 | for ( i=0 ; i< 12 ; i++)pPDS_Input->ausZero[i] = 0; /* Reserved- Set to 0 */ |
---|
| 249 | /* Oct-26 was reserved, now holds Sub-Center Id */ |
---|
| 250 | pPDS_Input->usCenter_sub = User_Input.usCenter_sub; |
---|
| 251 | /* Oct-41: show that Grib Extensions are used */ |
---|
| 252 | pPDS_Input->usExt_flag = (unsigned short)EXTENSION_FLAG; |
---|
| 253 | /* Tracking ID for data set */ |
---|
| 254 | pPDS_Input->usTrack_num = User_Input.usTrack_num; |
---|
| 255 | |
---|
| 256 | /* WSI Extended PDS section: Used for extended and higher resolution time periods */ |
---|
| 257 | pPDS_Input->PDS_41 = Data_Input.PDS_41; |
---|
| 258 | pPDS_Input->PDS_42 = Data_Input.PDS_42; |
---|
| 259 | pPDS_Input->PDS_46 = Data_Input.PDS_46; |
---|
| 260 | pPDS_Input->PDS_47 = Data_Input.PDS_47; |
---|
| 261 | pPDS_Input->PDS_51 = Data_Input.PDS_51; |
---|
| 262 | pPDS_Input->PDS_52 = Data_Input.PDS_52; |
---|
| 263 | |
---|
| 264 | /* |
---|
| 265 | * |
---|
| 266 | * B.2 ASSIGN size of PDS_GRIB into uslength of struct PDS_INPUT |
---|
| 267 | ** If encoding MEL GRIB messages, Pds Length should be 46 and |
---|
| 268 | Octet 41 should equal the Extension Flag. |
---|
| 269 | */ |
---|
| 270 | pPDS_Input->uslength = sizeof(PDS_GRIB); |
---|
| 271 | |
---|
| 272 | /* |
---|
| 273 | * |
---|
| 274 | * B.3 DEBUG Print |
---|
| 275 | */ |
---|
| 276 | DPRINT1("\t create_inpPDS: uslength = %u (Size of PDS_GRIB)\n", |
---|
| 277 | pPDS_Input->uslength ); |
---|
| 278 | DPRINT1("\t create_inpPDS: usEd_num = %u\n", pPDS_Input->usEd_num ); |
---|
| 279 | DPRINT1("\t create_inpPDS: usParm_tbl = %u\n", pPDS_Input->usParm_tbl ); |
---|
| 280 | DPRINT1("\t create_inpPDS: usSub_tbl = %u\n", pPDS_Input->usSub_tbl); |
---|
| 281 | DPRINT1("\t create_inpPDS: usCenter_id = %u\n", pPDS_Input->usCenter_id ); |
---|
| 282 | DPRINT2("\t create_inpPDS: usCenter_sub Oct26=%u, usExt_flag Oct41=%u\n", |
---|
| 283 | pPDS_Input->usCenter_sub, pPDS_Input->usExt_flag); |
---|
| 284 | DPRINT1("\t create_inpPDS: usProc_id = %u\n", pPDS_Input->usProc_id ); |
---|
| 285 | DPRINT1("\t create_inpPDS: usGrid_id = %u\n", pPDS_Input->usGrid_id ); |
---|
| 286 | DPRINT1("\t create_inpPDS: usGds_bms_id = %u\n", pPDS_Input->usGds_bms_id); |
---|
| 287 | DPRINT1("\t create_inpPDS: usParm_id = %u\n", pPDS_Input->usParm_id ); |
---|
| 288 | DPRINT1("\t create_inpPDS: usParm_sub = %u\n", pPDS_Input->usParm_sub); |
---|
| 289 | DPRINT1("\t create_inpPDS: usLevel_id = %u\n", pPDS_Input->usLevel_id ); |
---|
| 290 | DPRINT1("\t create_inpPDS: usHeight1 = %u\n", pPDS_Input->usHeight1 ); |
---|
| 291 | DPRINT1("\t create_inpPDS: usHeight2 = %u\n", pPDS_Input->usHeight2 ); |
---|
| 292 | DPRINT1("\t create_inpPDS: usCentury = %u\n", pPDS_Input->usCentury ); |
---|
| 293 | DPRINT1("\t create_inpPDS: usYear = %u\n", pPDS_Input->usYear ); |
---|
| 294 | DPRINT1("\t create_inpPDS: usDay = %u\n", pPDS_Input->usDay ); |
---|
| 295 | DPRINT1("\t create_inpPDS: usHour = %u\n", pPDS_Input->usHour ); |
---|
| 296 | DPRINT1("\t create_inpPDS: usMinute = %u\n", pPDS_Input->usMinute ); |
---|
| 297 | DPRINT1("\t create_inpPDS: usSecond = %u\n", pPDS_Input->usSecond ); |
---|
| 298 | DPRINT1("\t create_inpPDS: usP1 = %u\n", pPDS_Input->usP1); |
---|
| 299 | DPRINT1("\t create_inpPDS: sDec_sc_fctr = %d\n", pPDS_Input->sDec_sc_fctr); |
---|
| 300 | DPRINT1("\t create_inpPDS: usTrack_num = %u\n", pPDS_Input->usTrack_num); |
---|
| 301 | DPRINT0("\t create_inpPDS: WSI Extended PDS Section: \n"); |
---|
| 302 | DPRINT1("\t create_inpPDS: PDS_41 (Forecast time 1 unit id): %u\n",pPDS_Input->PDS_41); |
---|
| 303 | DPRINT1("\t create_inpPDS: PDS_42 (Forecast time 1): %u\n",pPDS_Input->PDS_42); |
---|
| 304 | DPRINT1("\t create_inpPDS: PDS_46 (Forecast time 2 unit id): %u\n",pPDS_Input->PDS_46); |
---|
| 305 | DPRINT1("\t create_inpPDS: PDS_47 (Forecast time 2 unit id): %u\n",pPDS_Input->PDS_47); |
---|
| 306 | DPRINT1("\t create_inpPDS: PDS_51 (Time range indicator): %u\n",pPDS_Input->PDS_51); |
---|
| 307 | DPRINT1("\t create_inpPDS: PDS_52 (Top of atm): %u\n",pPDS_Input->PDS_52); |
---|
| 308 | |
---|
| 309 | |
---|
| 310 | /* |
---|
| 311 | * |
---|
| 312 | * B.4 RETURN w/nothing |
---|
| 313 | */ |
---|
| 314 | DPRINT0 ("Exiting create_inpPDS with no errors;\n"); |
---|
| 315 | |
---|
| 316 | /* |
---|
| 317 | * |
---|
| 318 | * END OF FUNCTION |
---|
| 319 | * |
---|
| 320 | * |
---|
| 321 | */ |
---|
| 322 | } |
---|
| 323 | |
---|
| 324 | /* |
---|
| 325 | * |
---|
| 326 | **************************************************************************** |
---|
| 327 | * C. FUNCTION: inp2grib_PDS |
---|
| 328 | * Use the data from the internal structure to fill the Product |
---|
| 329 | * Definition Section structure. |
---|
| 330 | * |
---|
| 331 | * INTERFACE: |
---|
| 332 | * int inp2grib_PDS ( pPDS_Input, ppPDS_Grib, errmsg) |
---|
| 333 | * |
---|
| 334 | * ARGUMENTS (I=input, O=output, I&O=input and output): |
---|
| 335 | * (I) PDS_INPUT *pPDS_Input; |
---|
| 336 | * internal PDS structure, used for input |
---|
| 337 | * (O) PDS_GRIB **ppPDS_GRIB ; |
---|
| 338 | * pre-allocated structure to be filled; |
---|
| 339 | * (O) char *errmsg; |
---|
| 340 | * empty array, returned filled if error occured; |
---|
| 341 | * |
---|
| 342 | * RETURN CODE: |
---|
| 343 | * 0> no errors; PDS_GRIB filled; |
---|
| 344 | * 99> unexpected null pointers, Errmsg filled; |
---|
| 345 | ****************************************************************************/ |
---|
| 346 | |
---|
| 347 | #if PROTOTYPE_NEEDED |
---|
| 348 | int inp2grib_PDS ( PDS_INPUT *pPDS_Input, |
---|
| 349 | PDS_GRIB **ppPDS_Grib, |
---|
| 350 | char *errmsg) |
---|
| 351 | #else |
---|
| 352 | int inp2grib_PDS ( pPDS_Input, ppPDS_Grib, errmsg) |
---|
| 353 | PDS_INPUT *pPDS_Input; |
---|
| 354 | PDS_GRIB **ppPDS_Grib; |
---|
| 355 | char *errmsg; |
---|
| 356 | #endif |
---|
| 357 | { |
---|
| 358 | char *func= "inp2grib_PDS"; |
---|
| 359 | unsigned char ach3bytes[3]; |
---|
| 360 | unsigned long ulPDS_length = 0; |
---|
| 361 | short sDec_sc_fctr = 0; |
---|
| 362 | int nStatus = 0; |
---|
| 363 | int i; /* loop counter */ |
---|
| 364 | long lTemp; /* working var */ |
---|
| 365 | PDS_GRIB *tpds; /* true grib pds, working var */ |
---|
| 366 | short tmp_byte2; /* working var */ |
---|
| 367 | long tmp_byte4; /* working var */ |
---|
| 368 | |
---|
| 369 | DPRINT0 ( "Entering inp2grib_PDS......\n" ); |
---|
| 370 | |
---|
| 371 | /* |
---|
| 372 | * |
---|
| 373 | * C.1 IF (either Internal PDS_INPUT or True Grib PDS_GRIB is null) THEN |
---|
| 374 | * SET status = 99; |
---|
| 375 | * RETURN |
---|
| 376 | * ENDIF |
---|
| 377 | */ |
---|
| 378 | if ( !ppPDS_Grib || !pPDS_Input) { |
---|
| 379 | sprintf(errmsg, |
---|
| 380 | "%s: either PDS_GRIB /PDS_INPUT/or both are Null\n",func); |
---|
| 381 | nStatus= 99; |
---|
| 382 | goto BYE; |
---|
| 383 | } |
---|
| 384 | |
---|
| 385 | /* |
---|
| 386 | * |
---|
| 387 | * C.2 ASSIGN local ptr to point to PDS_GRIB struct; |
---|
| 388 | */ |
---|
| 389 | tpds = *ppPDS_Grib; |
---|
| 390 | |
---|
| 391 | /* |
---|
| 392 | * |
---|
| 393 | * C.3 CREATE true Grib struct PDS_GRIB from internal PDS_INPUT |
---|
| 394 | */ |
---|
| 395 | tpds->chParm_tbl = ( unsigned char ) pPDS_Input->usParm_tbl; |
---|
| 396 | |
---|
| 397 | /* Commented out by Todd Hutchinson, WSI, when Extended PDS was replaced */ |
---|
| 398 | /* tpds->chSub_tbl = ( unsigned char ) pPDS_Input->usSub_tbl; */ |
---|
| 399 | |
---|
| 400 | tpds->chCenter_id = ( unsigned char ) pPDS_Input->usCenter_id; |
---|
| 401 | tpds->chProc_id = ( unsigned char ) pPDS_Input->usProc_id; |
---|
| 402 | tpds->chGrid_id = ( unsigned char ) pPDS_Input->usGrid_id; |
---|
| 403 | tpds->chGds_bms_id = ( unsigned char ) pPDS_Input->usGds_bms_id; |
---|
| 404 | tpds->chParm_id = ( unsigned char ) pPDS_Input->usParm_id; |
---|
| 405 | |
---|
| 406 | /* Commented out by Todd Hutchinson, WSI, when Extended PDS was replaced */ |
---|
| 407 | /* tpds->chParm_sub= (unsigned char ) pPDS_Input->usParm_sub; */ |
---|
| 408 | |
---|
| 409 | tpds->chLevel_id = ( unsigned char ) pPDS_Input->usLevel_id; |
---|
| 410 | |
---|
| 411 | switch(pPDS_Input->usLevel_id){ |
---|
| 412 | case 1: /* surface(of the Earth, includes sea surface) level */ |
---|
| 413 | case 2: /* cloud base level */ |
---|
| 414 | case 3: /* cloud top level */ |
---|
| 415 | case 4: /* 0 deg C isotherm level */ |
---|
| 416 | case 5: /* adiabatic condensation level */ |
---|
| 417 | case 6: /* maximum wind speed level */ |
---|
| 418 | case 7: /* tropopause level */ |
---|
| 419 | case 8: /* nominal top of atmosphere level */ |
---|
| 420 | case 9: /* sea bottom level */ |
---|
| 421 | case 100: /* isobaric level */ |
---|
| 422 | case 103: /* fixed height level */ |
---|
| 423 | case 105: /* fixed height above ground */ |
---|
| 424 | case 107: /* sigma level */ |
---|
| 425 | case 111: /* depth below land surface */ |
---|
| 426 | case 113: /* isentropic (theta) level */ |
---|
| 427 | case 115: /* sigma-z level */ |
---|
| 428 | case 119: /* Eta Level */ |
---|
| 429 | case 125: /* height level above ground (high precision) */ |
---|
| 430 | case 160: /* depth below sea level */ |
---|
| 431 | case 200: /* entire atmosphere considered as a single layer */ |
---|
| 432 | case 201: /* entire ocean considered as a single layer */ |
---|
| 433 | case 212: /* low cloud bottom level */ |
---|
| 434 | case 213: /* low cloud top level */ |
---|
| 435 | case 222: /* middle cloud bottom level */ |
---|
| 436 | case 223: /* middle cloud top level */ |
---|
| 437 | case 232: /* high cloud bottom level */ |
---|
| 438 | case 233: /* high cloud top level */ |
---|
| 439 | set_bytes(pPDS_Input->usHeight1, 2, tpds->achHeight); |
---|
| 440 | break; |
---|
| 441 | default: |
---|
| 442 | set_bytes(pPDS_Input->usHeight2, 1, (tpds->achHeight)); |
---|
| 443 | set_bytes(pPDS_Input->usHeight1, 1, (tpds->achHeight)+1); |
---|
| 444 | break; |
---|
| 445 | } |
---|
| 446 | |
---|
| 447 | tpds->chYear = ( unsigned char ) pPDS_Input->usYear; |
---|
| 448 | tpds->chMonth = ( unsigned char ) pPDS_Input->usMonth; |
---|
| 449 | tpds->chDay = ( unsigned char ) pPDS_Input->usDay; |
---|
| 450 | tpds->chHour = ( unsigned char ) pPDS_Input->usHour; |
---|
| 451 | tpds->chMinute = ( unsigned char ) pPDS_Input->usMinute; |
---|
| 452 | tpds->chFcst_unit_id = ( unsigned char ) pPDS_Input->usFcst_unit_id; |
---|
| 453 | tpds->chP1 = ( unsigned char ) pPDS_Input->usP1; |
---|
| 454 | tpds->chP2 = ( unsigned char ) pPDS_Input->usP2; |
---|
| 455 | tpds->chTime_range = ( unsigned char ) pPDS_Input->usTime_range; |
---|
| 456 | |
---|
| 457 | set_bytes(pPDS_Input->usTime_range_avg,2,tpds->achTime_range_avg); |
---|
| 458 | |
---|
| 459 | tpds->chTime_range_mis = ( unsigned char ) pPDS_Input->usTime_range_mis; |
---|
| 460 | tpds->chCentury = ( unsigned char ) pPDS_Input->usCentury; |
---|
| 461 | tpds->chCenter_sub = ( unsigned char ) pPDS_Input->usCenter_sub; |
---|
| 462 | DPRINT1("Octet-26: tpds->usCenter_sub= %d\n", (int)tpds->chCenter_sub); |
---|
| 463 | |
---|
| 464 | set_bytes(pPDS_Input->sDec_sc_fctr,2,tpds->achDec_sc_fctr); |
---|
| 465 | |
---|
| 466 | for(i=0;i<12;++i) |
---|
| 467 | tpds->achZero[i]= ( unsigned char ) pPDS_Input->ausZero[i]; |
---|
| 468 | |
---|
| 469 | /* Commented out by Todd Hutchinson, WSI, when Extended PDS was replaced */ |
---|
| 470 | /* |
---|
| 471 | tpds->chExt_flag = (unsigned char) pPDS_Input->usExt_flag; |
---|
| 472 | DPRINT1("Octet41: tpds->chExt_flag= %d\n", (int)tpds->chExt_flag); |
---|
| 473 | |
---|
| 474 | tpds->chSecond = ( unsigned char ) pPDS_Input->usSecond; |
---|
| 475 | memcpy((void *)tpds->chTrack_num, |
---|
| 476 | (void *)&(pPDS_Input->usTrack_num), 2); |
---|
| 477 | */ |
---|
| 478 | |
---|
| 479 | /* Added by Todd Hutchinson, WSI. Extended WSI PDS section */ |
---|
| 480 | |
---|
| 481 | tpds->PDS_41 = (unsigned char)pPDS_Input->PDS_41; |
---|
| 482 | |
---|
| 483 | set_bytes(pPDS_Input->PDS_42,4,tpds->PDS_42); |
---|
| 484 | |
---|
| 485 | tpds->PDS_46 = (unsigned char)pPDS_Input->PDS_46; |
---|
| 486 | |
---|
| 487 | set_bytes(pPDS_Input->PDS_47,4,tpds->PDS_47); |
---|
| 488 | |
---|
| 489 | tpds->PDS_51 = (unsigned char)pPDS_Input->PDS_51; |
---|
| 490 | |
---|
| 491 | set_bytes(pPDS_Input->PDS_52,2,tpds->PDS_52); |
---|
| 492 | |
---|
| 493 | ulPDS_length= sizeof (PDS_GRIB); |
---|
| 494 | DPRINT1 ( "\t length of PDS_GRIB is %d\n", ulPDS_length ); |
---|
| 495 | |
---|
| 496 | set_bytes(ulPDS_length, 3, tpds->achPDS_length); |
---|
| 497 | |
---|
| 498 | HDR_PRINT("encoded PDS", (unsigned char*)tpds, (int)ulPDS_length); |
---|
| 499 | /* |
---|
| 500 | * |
---|
| 501 | * C.4 RETURN with Status |
---|
| 502 | */ |
---|
| 503 | BYE: |
---|
| 504 | DPRINT1 ( "Exiting inp2grib_PDS(), stat=%d\n", nStatus); |
---|
| 505 | return ( nStatus ); |
---|
| 506 | /* |
---|
| 507 | * |
---|
| 508 | * END OF FUNCTION |
---|
| 509 | * |
---|
| 510 | */ |
---|
| 511 | } |
---|