1 /*****************************************************************************
2 * weather.c
3 *
4 * DESCRIPTION
5 * This file contains all the utility functions needed to handle weather
6 * "ugly" strings. Originally I didn't need to parse them, but for people
7 * to use them in ArcView, I had to.
8 *
9 * HISTORY
10 * 5/2003 Arthur Taylor (MDL / RSIS): Created.
11 *
12 * NOTES
13 *****************************************************************************
14 */
15 /*
16 * Uncomment the following to have error messages stored in the UglyStringType
17 * This uses myerror.*
18 */
19 #define STORE_ERRORS
20
21 /*
22 * Uncomment the following to have error messages sent to stdout.
23 */
24 /* #define VERBOSE */
25 #undef VERBOSE
26
27 /*
28 * Uncomment the following to test Weather names.
29 */
30 /* #define DEBUG_WEATHER */
31
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include "weather.h"
37
38 #ifdef STORE_ERRORS
39 #include "myerror.h"
40 #endif
41
42 typedef struct {
43 const char *abrev, *name;
44 uChar number;
45 } WxTable;
46
47 /* Unknown <NoCov>:EW:<NoInten>:<NoVis>:10to20g30 */
48 /* Original enumeration.
49 enum {
50 WX_NOWX, WX_K, WX_BD, WX_BS, WX_H, WX_F, WX_L, WX_R, WX_RW,
51 WX_A, WX_FR, WX_ZL, WX_ZR, WX_IP, WX_S, WX_SW, WX_T
52 };
53 */
54 enum {
55 WX_NOWX, WX_K, WX_BD, WX_BS, WX_H, WX_F, WX_L, WX_R, WX_RW,
56 WX_A, WX_FR, WX_ZL, WX_ZR, WX_IP, WX_S, WX_SW, WX_T, WX_BN,
57 WX_ZF, WX_IC, WX_IF, WX_VA, WX_ZY, WX_WP, WX_UNKNOWN
58 };
59
60 /* SA -> Snowfall aob freezing */
61 /* LC -> Caution Advised on area Lakes */
62 /* {"WG", "Frequent Gusts", WX_WG},*/
63 static const WxTable WxCode[] = {
64 /* 0 */ {"<NoWx>", "No Weather", WX_NOWX},
65 /* Dry Obstruction to visibility. */
66 /* 14 */ {"K", "Smoke", WX_K},
67 /* 15 */ {"BD", "Blowing Dust", WX_BD},
68 /* 13 */ {"BS", "Blowing Snow", WX_BS},
69 /* Moist Obstruction to visibility. */
70 /* 12 */ {"H", "Haze", WX_H},
71 /* 11 */ {"F", "Fog", WX_F},
72 /* 5 */ {"L", "Drizzle", WX_L},
73 /* Warm moisture. */
74 /* 3 */ {"R", "Rain", WX_R},
75 /* 4 */ {"RW", "Rain Showers", WX_RW},
76 /* 'A' has have been dropped as of 8/12/2004 */
77 /* 2 */ {"A", "Hail", WX_A},
78 /* 'A' has have been dropped as of 8/12/2004 */
79 /* Freezing / Mix moisture. */
80 /* 16 */ {"FR", "Frost", WX_FR},
81 /* 7 */ {"ZL", "Freezing Drizzle", WX_ZL},
82 /* 6 */ {"ZR", "Freezing Rain", WX_ZR},
83 /* Frozen moisture. */
84 /* 10 */ {"IP", "Ice Pellets (sleet)", WX_IP},
85 /* 8 */ {"S", "Snow", WX_S},
86 /* 9 */ {"SW", "Snow Showers", WX_SW},
87 /* Extra. */
88 /* 1 */ {"T", "Thunderstorms", WX_T},
89 {"BN", "Blowing Sand", WX_BN},
90 {"ZF", "Freezing Fog", WX_ZF},
91 {"IC", "Ice Crystals", WX_IC},
92 {"IF", "Ice Fog", WX_IF},
93 {"VA", "Volcanic Ash", WX_VA},
94 {"ZY", "Freezing Spray", WX_ZY},
95 {"WP", "Water Spouts", WX_WP},
96 {"<unknown>", "Unknown Weather", WX_UNKNOWN}
97 };
98
99 /* GChc found in output streams... not allowed to add yet. */
100 /* Original enumeration.
101 enum {
102 COV_NOCOV, COV_ISO, COV_SCT, COV_NUM, COV_WIDE, COV_OCNL, COV_SCHC,
103 COV_CHC, COV_LKLY, COV_DEF, COV_PATCHY, COV_AREAS
104 };
105 */
106 enum {
107 COV_NOCOV, COV_ISO, COV_SCT, COV_NUM, COV_WIDE, COV_OCNL, COV_SCHC,
108 COV_CHC, COV_LKLY, COV_DEF, COV_PATCHY, COV_AREAS, COV_PDS, COV_FRQ,
109 COV_INTER, COV_BRIEF, COV_UNKNOWN
110 };
111
112 static const WxTable WxCover[] = {
113 /* 0 */ {"<NoCov>", "No Coverage/Probability", COV_NOCOV},
114 /* 1 */ {"Iso", "Isolated", COV_ISO},
115 /* 2 */ {"Sct", "Scattered", COV_SCT},
116 /* 3 */ {"Num", "Numerous", COV_NUM},
117 /* 4 */ {"Wide", "Widespread", COV_WIDE},
118 /* 5 */ {"Ocnl", "Occasional", COV_OCNL},
119 /* 6 */ {"SChc", "Slight Chance of", COV_SCHC},
120 /* 7 */ {"Chc", "Chance of", COV_CHC},
121 /* 8 */ {"Lkly", "Likely", COV_LKLY},
122 /* 9 */ {"Def", "Definite", COV_DEF},
123 /* 10 */ {"Patchy", "Patchy", COV_PATCHY},
124 /* 11 */ {"Areas", "Areas of", COV_AREAS},
125 /* Added 8/13/2004 */
126 /* 12 */ {"Pds", "Periods of", COV_PDS},
127 /* 13 */ {"Frq", "Frequent", COV_FRQ},
128 /* 14 */ {"Inter", "Intermittent", COV_INTER},
129 /* 15 */ {"Brf", "Brief", COV_BRIEF},
130 /* Finished Added 8/13/2004 */
131 {"<unknown>", "Unknown Coverage", COV_UNKNOWN}
132 };
133
134 enum { INT_NOINT, INT_DD, INT_D, INT_M, INT_P, INT_UNKNOWN };
135
136 static const WxTable WxIntens[] = {
137 /* 0 */ {"<NoInten>", "No Intensity", INT_NOINT},
138 /* 1 */ {"--", "Very Light", INT_DD},
139 /* 2 */ {"-", "Light", INT_D},
140 /* 3 */ {"m", "Moderate", INT_M},
141 /* 4 */ {"+", "Heavy", INT_P},
142 {"<unknown>", "Unknown Intensity", INT_UNKNOWN}
143 };
144
145 enum {
146 VIS_NOVIS, VIS_0, VIS_8, VIS_16, VIS_24, VIS_32, VIS_48, VIS_64, VIS_80,
147 VIS_96, VIS_128, VIS_160, VIS_192, VIS_224, VIS_UNKNOWN = 255
148 };
149
150 static const WxTable WxVisib[] = {
151 /* 0 */ {"<NoVis>", "255", VIS_NOVIS},
152 /* 1 */ {"0SM", "0", VIS_0},
153 /* 2 */ {"1/4SM", "8", VIS_8},
154 /* 3 */ {"1/2SM", "16", VIS_16},
155 /* 4 */ {"3/4SM", "24", VIS_24},
156 /* 5 */ {"1SM", "32", VIS_32},
157 /* 6 */ {"11/2SM", "48", VIS_48},
158 /* 7 */ {"2SM", "64", VIS_64},
159 /* 8 */ {"21/2SM", "80", VIS_80},
160 /* 9 */ {"3SM", "96", VIS_96},
161 /* 10 */ {"4SM", "128", VIS_128},
162 /* 11 */ {"5SM", "160", VIS_160},
163 /* 12 */ {"6SM", "192", VIS_192},
164 /* Past 6 SM (encode as 7 SM). */
165 /* 13 */ {"P6SM", "224", VIS_224},
166 {"<unknown>", "Unknown Visibility", VIS_UNKNOWN}
167 };
168
169 enum {
170 HAZ_NOHAZ, HAZ_FL, HAZ_GW, HAZ_HVYRN, HAZ_DMGW, HAZ_A, HAZ_LGA, HAZ_OLA,
171 HAZ_OBO, HAZ_OGA, HAZ_DRY, HAZ_TOR, HAZ_UNKNOWN, HAZ_PRI1 = 253,
172 HAZ_PRI2 = 254, HAZ_OR = 255
173 };
174
175 /* Note: HazCode currently can handle up to (21 + 4) different WxAttrib
176 * numbers because it is stored in a "sInt4" (2^31 = 21,47,48,36,48) */
177 static const WxTable WxAttrib[] = {
178 /* 0 */ {"", "None", HAZ_NOHAZ},
179 /* 1 */ {"FL", "Frequent Lightning", HAZ_FL},
180 /* 2 */ {"GW", "Gusty Winds", HAZ_GW},
181 /* 3 */ {"HvyRn", "Heavy Rain", HAZ_HVYRN},
182 /* 4 */ {"DmgW", "Damaging Wind", HAZ_DMGW},
183 /* 5 */ {"SmA", "Small Hail", HAZ_A},
184 /* 6 */ {"LgA", "Large Hail", HAZ_LGA},
185 /* 7 */ {"OLA", "Outlying Areas", HAZ_OLA},
186 /* 8 */ {"OBO", "on Bridges and Overpasses", HAZ_OBO},
187 /* Added 8/13/2004 */
188 /* 9 */ {"OGA", "On Grassy Areas", HAZ_OGA},
189 /* 10 */ {"Dry", "dry", HAZ_DRY},
190 /* 11 */ {"TOR", "Tornado", HAZ_TOR},
191 /* 12 */ {"Primary", "Highest Ranking", HAZ_PRI2},
192 /* 13 */ {"Mention", "Include Unconditionally", HAZ_PRI1},
193 /* Finished Added 8/13/2004 */
194 /* 14 */ {"OR", "or", HAZ_OR},
195 /* 15 */ {"MX", "mixture", HAZ_OR},
196 {"<unknown>", "Unknown Hazard", HAZ_UNKNOWN}
197 };
198
199 /*****************************************************************************
200 * NDFD_WxTable1() --
201 *
202 * Original: makeWxImageCodes() Marc Saccucci (MDL)
203 * Adapted to NDFD_WxTable() Arthur Taylor / MDL
204 *
205 * PURPOSE
206 * To use the same weather table scheme used by Marc Saccucci in
207 * makeWxImageCodes() in the NDFD source tree. The purpose of both
208 * procedures is to simplify the weather string (aka ugly string) to a single
209 * integral code number, which contains the most relevant weather. The
210 * intent is to create a simpler field which can more readily be viewed as
211 * an image.
212 *
213 * ARGUMENTS
214 * ugly = The ugly weather string to encode. (Input)
215 *
216 * FILES/DATABASES: None
217 *
218 * RETURNS: int (the encoded number.)
219 *
220 * HISTORY
221 * 11/2002 Marc Saccucci (MDL): Created matching algorithm in
222 * makeWxImageCodes().
223 * 6/2003 MS: Altered matching combinations in makeWxImageCodes().
224 * 7/2003 Arthur Taylor (MDL/RSIS): Created NDFD_WxTable()
225 *
226 * NOTES
227 * 1) The table used:
228 * new_code primary weather/probability Description (sample value)
229 * ======== =========================== ==========================
230 * 0 <NoWx> No weather
231 * 1 L/Sct,SChc,Patchy,Iso,Chc Rain (LoProb L)
232 * 2 R-/Sct,SChc,Patchy,Iso,Chc Rain (LoProb R-)
233 * 3 R/Sct,SChc,Patchy,Iso,Chc Rain (LoProb R)
234 * 4 R+/Sct,SChc,Patchy,Iso,Chc Rain (LoProb R+)
235 * 5 R/T;Sct,SChc,Patchy,Iso,Chc Rain (LoProb R/T)
236 * 6 RW/Sct,SChc,Patchy,Iso,Chc Rain (LoProb Rw)
237 * 7 RW/T;Sct,SChc,Patchy,Iso,Chc Rain (LoProb RW/T)
238 * 8 T/Sct,SChc,Patchy,Iso,Chc Rain (LoProb T)
239 * 9 L/Wide,Lkly,Num,Ocnl,Def,Areas Rain (HiProb L)
240 * 10 R-/Wide,Lkly,Num,Ocnl,Def,Areas Rain (HiProb R-)
241 * 11 R/Wide,Lkly,Num,Ocnl,Def,Areas Rain (HiProb R)
242 * 12 R+/Wide,Lkly,Num,Ocnl,Def,Areas Rain (HiProb R+)
243 * 13 R/T;Wide,Lkly,Num,Ocnl,Def,Areas Rain (HiProb R/T)
244 * 14 RW/Wide,Lkly,Num,Ocnl,Def,Areas Rain (HiProb RW)
245 * 15 RW/T;Wide,Lkly,Num,Ocnl,Def,Areas Rain (HiProb RW/T)
246 * 16 T/Wide,Lkly,Num,Ocnl,Def,Areas Rain (HiProb T)
247 * 17 T+ Severe Tstorms
248 * 18 R/S;Sct,SChc,Patchy,Iso,Chc Wintry Mix (LoProb R/S)
249 * 19 RW/SW;Sct,SChc,Patchy,Iso,Chc Wintry Mix (LoProb RW/SW)
250 * 20 R/IP;Sct,SChc,Patchy,Iso,Chc Wintry Mix (LoProb R/IP)
251 * 21 S/IP;Sct,SChc,Patchy,Iso,Chc Wintry Mix (LoProb S/IP)
252 * 22 R/S;Wide,Lkly,Num,Ocnl,Def,Areas Wintry Mix (HiProb R/S)
253 * 23 RW/SW;Wide,Lkly,Num,Ocnl,Def,AreasWintry Mix (HiProb RW/SW)
254 * 24 R/IP;Wide,Lkly,Num,Ocnl,Def,Areas Wintry Mix (HiProb R/IP)
255 * 25 S/IP;Wide,Lkly,Num,Ocnl,Def,Areas Wintry Mix (HiProb S/IP)
256 * 26 IP-/Sct,SChc,Patchy,Iso,Chc Ice (LoProb IP-)
257 * 27 IP/Sct,SChc,Patchy,Iso,Chc Ice (LoProb IP)
258 * 28 IP+/Sct,SChc,Patchy,Iso,Chc Ice (LoProb IP+)
259 * 29 ZL/Sct,SChc,Patchy,Iso,Chc Ice (LoProb ZL)
260 * 30 ZL/R;Sct,SChc,Patchy,Iso,Chc Ice (LoProb R/ZL)
261 * 31 ZR-/Sct,SChc,Patchy,Iso,Chc Ice (LoProb ZR-)
262 * 32 ZR/Sct,SChc,Patchy,Iso,Chc Ice (LoProb ZR)
263 * 33 ZR+/Sct,SChc,Patchy,Iso,Chc Ice (LoProb ZR+)
264 * 34 ZR/R;Sct,SChc,Patchy,Iso,Chc Ice (LoProb R/ZR)
265 * 35 ZR/IP;Sct,SChc,Patchy,Iso,Chc Ice (LoProb ZR/IP)
266 * 36 IP-/Wide,Lkly,Num,Ocnl,Def,Areas Ice (HiProb IP-)
267 * 37 IP/Wide,Lkly,Num,Ocnl,Def,Areas Ice (HiProb IP)
268 * 38 IP+/Wide,Lkly,Num,Ocnl,Def,Areas Ice (HiProb IP+)
269 * 39 ZL/Wide,Lkly,Num,Ocnl,Def,Areas Ice (HiProb ZL)
270 * 40 ZL/R;Wide,Lkly,Num,Ocnl,Def,Areas Ice (HiProb R/ZL)
271 * 41 ZR-/Wide,Lkly,Num,Ocnl,Def,Areas Ice (HiProb ZR-)
272 * 42 ZR/Wide,Lkly,Num,Ocnl,Def,Areas Ice (HiProb ZR)
273 * 43 ZR+/Wide,Lkly,Num,Ocnl,Def,Areas Ice (HiProb ZR+)
274 * 44 ZR/R;Wide,Lkly,Num,Ocnl,Def,Areas Ice (HiProb R/ZR)
275 * 45 ZR/IP;Wide,Lkly,Num,Ocnl,Def,AreasIce (HiProb ZR/IP)
276 * 46 SW/Sct,SChc,Patchy,Iso,Chc Snow (LoProb SW)
277 * 47 S-/Sct,SChc,Patchy,Iso,Chc Snow (LoProb S-)
278 * 48 S/Sct,SChc,Patchy,Iso,Chc Snow (LoProb S)
279 * 49 S+/Sct,SChc,Patchy,Iso,Chc Snow (LoProb S+)
280 * 50 SW/Wide,Lkly,Num,Ocnl,Def,Areas Snow (HiProb SW)
281 * 51 S-/Wide,Lkly,Num,Ocnl,Def,Areas Snow (HiProb S-)
282 * 52 S/Wide,Lkly,Num,Ocnl,Def,Areas Snow (HiProb S)
283 * 53 S+/Wide,Lkly,Num,Ocnl,Def,Areas Snow (HiProb S+)
284 * 54 F Fog
285 * 55 H Haze
286 * 56 K Smoke
287 * 57 BS Blowing Snow
288 * 58 BD Blowing Dust
289 *****************************************************************************
290 */
NDFD_WxTable1(UglyStringType * ugly)291 static int NDFD_WxTable1 (UglyStringType * ugly)
292 {
293 switch (ugly->wx[0]) {
294 case WX_NOWX:
295 return 0;
296 case WX_R:
297 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
298 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
299 (ugly->cover[0] == COV_CHC)) {
300 switch (ugly->wx[1]) {
301 case WX_S:
302 case WX_SW:
303 return 18; /* Rain/Snow Showers */
304 case WX_ZR:
305 return 34; /* Rain/Freezing Rain */
306 case WX_IP:
307 return 20; /* Rain/Sleet */
308 case WX_ZL:
309 return 30; /* Rain/Freezing Drizzle */
310 case WX_T:
311 return 5; /* Rain/Thunderstorms */
312 default:
313 switch (ugly->intens[0]) {
314 case INT_D:
315 case INT_DD:
316 return 2; /* Light Rain */
317 case INT_P:
318 return 4; /* Heavy Rain */
319 default:
320 return 3; /* Normal Rain */
321 }
322 }
323 } else {
324 switch (ugly->wx[1]) {
325 case WX_S:
326 case WX_SW:
327 return 22; /* Rain/Snow Showers */
328 case WX_ZR:
329 return 44; /* Rain/Freezing Rain */
330 case WX_IP:
331 return 24; /* Rain/Sleet */
332 case WX_ZL:
333 return 40; /* Rain/Freezing Drizzle */
334 case WX_T:
335 return 13; /* Rain/Thunderstorms */
336 default:
337 switch (ugly->intens[0]) {
338 case INT_D:
339 case INT_DD:
340 return 10; /* Light Rain */
341 case INT_P:
342 return 12; /* Heavy Rain */
343 default:
344 return 11; /* Normal Rain */
345 }
346 }
347 }
348 case WX_RW:
349 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
350 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
351 (ugly->cover[0] == COV_CHC)) {
352 switch (ugly->wx[1]) {
353 case WX_T:
354 return 7; /* Rain Showers/Thunderstorms */
355 case WX_SW:
356 return 19; /* Rain Showers/Snow Showers */
357 default:
358 return 6; /* Rain Showers */
359 }
360 } else {
361 switch (ugly->wx[1]) {
362 case WX_T:
363 return 15; /* Rain Showers/Thunderstorms */
364 case WX_SW:
365 return 23; /* Rain Showers/Snow Showers */
366 default:
367 return 14; /* Rain Showers */
368 }
369 }
370 case WX_L:
371 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
372 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
373 (ugly->cover[0] == COV_CHC)) {
374 switch (ugly->wx[1]) {
375 case WX_ZL:
376 return 29; /* Drizzle/Freezing Drizzle */
377 case WX_F:
378 default:
379 return 1; /* Drizzle */
380 }
381 } else {
382 switch (ugly->wx[1]) {
383 case WX_ZL:
384 return 40; /* Drizzle/Freezing Drizzle */
385 case WX_F:
386 default:
387 return 9; /* Drizzle */
388 }
389 }
390 case WX_ZL:
391 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
392 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
393 (ugly->cover[0] == COV_CHC)) {
394 switch (ugly->wx[1]) {
395 case WX_R:
396 return 30; /* Freezing Drizzle/Rain */
397 case WX_L:
398 default:
399 return 29; /* Freezing Drizzle */
400 }
401 } else {
402 switch (ugly->wx[1]) {
403 case WX_R:
404 return 40; /* Freezing Drizzle/Rain */
405 case WX_L:
406 default:
407 return 39; /* Freezing Drizzle */
408 }
409 }
410 case WX_ZR:
411 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
412 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
413 (ugly->cover[0] == COV_CHC)) {
414 switch (ugly->wx[1]) {
415 case WX_R:
416 return 34; /* Freezing Rain/Rain */
417 case WX_IP:
418 return 35; /* Freezing Rain/Sleet */
419 default:
420 switch (ugly->intens[0]) {
421 case INT_D:
422 case INT_DD:
423 return 31; /* Light Freezing Rain */
424 case INT_P:
425 return 33; /* Heavy Freezing Rain */
426 default:
427 return 32; /* Normal Freezing Rain */
428 }
429 }
430 } else {
431 switch (ugly->wx[1]) {
432 case WX_R:
433 return 44; /* Freezing Rain/Rain */
434 case WX_IP:
435 return 45; /* Freezing Rain/Sleet */
436 default:
437 switch (ugly->intens[0]) {
438 case INT_D:
439 case INT_DD:
440 return 41; /* Light Freezing Rain */
441 case INT_P:
442 return 43; /* Heavy Freezing Rain */
443 default:
444 return 42; /* Normal Freezing Rain */
445 }
446 }
447 }
448 case WX_IP:
449 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
450 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
451 (ugly->cover[0] == COV_CHC)) {
452 switch (ugly->wx[1]) {
453 case WX_R:
454 return 20; /* Sleet/Rain */
455 case WX_S:
456 return 21; /* Sleet/Snow */
457 case WX_ZR:
458 return 35; /* Sleet/Freezing Rain */
459 default:
460 switch (ugly->intens[0]) {
461 case INT_D:
462 case INT_DD:
463 return 26; /* Light Sleet */
464 case INT_P:
465 return 28; /* Heavy Sleet */
466 default:
467 return 27; /* Normal Sleet */
468 }
469 }
470 } else {
471 switch (ugly->wx[1]) {
472 case WX_R:
473 return 24; /* Sleet/Rain */
474 case WX_S:
475 return 25; /* Sleet/Snow */
476 case WX_ZR:
477 return 45; /* Sleet/Freezing Rain */
478 default:
479 switch (ugly->intens[0]) {
480 case INT_D:
481 case INT_DD:
482 return 36; /* Light Sleet */
483 case INT_P:
484 return 38; /* Heavy Sleet */
485 default:
486 return 37; /* Normal Sleet */
487 }
488 }
489 }
490 case WX_SW:
491 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
492 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
493 (ugly->cover[0] == COV_CHC)) {
494 switch (ugly->wx[1]) {
495 case WX_R:
496 return 18; /* Snow Showers/Rain */
497 case WX_RW:
498 return 19; /* Snow Showers/Rain Showers */
499 default:
500 return 46; /* Snow Showers */
501 }
502 } else {
503 switch (ugly->wx[1]) {
504 case WX_R:
505 return 22; /* Snow Showers/Rain */
506 case WX_RW:
507 return 23; /* Snow Showers/Rain Showers */
508 default:
509 return 50; /* Snow Showers */
510 }
511 }
512 case WX_S:
513 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
514 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
515 (ugly->cover[0] == COV_CHC)) {
516 switch (ugly->wx[1]) {
517 case WX_R:
518 case WX_RW:
519 return 18; /* Snow/Rain */
520 case WX_IP:
521 return 21; /* Snow/Sleet */
522 default:
523 switch (ugly->intens[0]) {
524 case INT_D:
525 case INT_DD:
526 return 47; /* Light Snow */
527 case INT_P:
528 return 49; /* Heavy Snow */
529 default:
530 return 48; /* Normal Snow */
531 }
532 }
533 } else {
534 switch (ugly->wx[1]) {
535 case WX_R:
536 case WX_RW:
537 return 22; /* Snow/Rain */
538 case WX_IP:
539 return 25; /* Snow/Sleet */
540 default:
541 switch (ugly->intens[0]) {
542 case INT_D:
543 case INT_DD:
544 return 51; /* Light Snow */
545 case INT_P:
546 return 53; /* Heavy Snow */
547 default:
548 return 52; /* Normal Snow */
549 }
550 }
551 }
552 case WX_T:
553 /*
554 * Check Severe storms. If so, this is most important weather
555 * type.
556 */
557 if (ugly->intens[0] == INT_P) {
558 return 17; /* Severe Thunderstorms */
559 }
560 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
561 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
562 (ugly->cover[0] == COV_CHC)) {
563 switch (ugly->wx[1]) {
564 case WX_R:
565 return 5; /* Thunderstorms/Rain */
566 case WX_RW:
567 return 7; /* Thunderstorms/Rain Showers */
568 default:
569 return 8; /* Thunderstorms. */
570 }
571 } else {
572 switch (ugly->wx[1]) {
573 case WX_R:
574 return 13; /* Thunderstorms/Rain */
575 case WX_RW:
576 return 15; /* Thunderstorms/Rain Showers */
577 default:
578 return 16; /* Thunderstorms. */
579 }
580 }
581 case WX_F:
582 return 54; /* Fog */
583 case WX_H:
584 return 55; /* Haze */
585 case WX_K:
586 return 56; /* Smoke */
587 case WX_BS:
588 return 57; /* Blowing Snow */
589 case WX_BD:
590 return 58; /* Blowing Dust */
591 case WX_FR: /* Ignore Frost */
592 case WX_A: /* Ignore Hail */
593 default:
594 return 0;
595 }
596 }
597
598 /*****************************************************************************
599 * NDFD_WxTable2_StdInten() --
600 *
601 * Arthur Taylor / MDL
602 *
603 * PURPOSE
604 * A helper routine to NDFD_WxTable2() to assist with adjusting the
605 * intensity. For the most part if intens is INT_D or INT_DD, we want to
606 * subtract 1 from the base value. If it is INT_P, we want to add 1,
607 * otherwise just return base.
608 *
609 * ARGUMENTS
610 * base = The base encoded number to adjust. (Input)
611 * intens = The intensity of the first weather key. (Input)
612 *
613 * FILES/DATABASES: None
614 *
615 * RETURNS: int (the resulting encoded number.)
616 *
617 * HISTORY
618 * 1/2004 Arthur Taylor (MDL/RSIS): Created.
619 *
620 * NOTES
621 *****************************************************************************
622 */
NDFD_WxTable2_StdInten(int base,int intens)623 static int NDFD_WxTable2_StdInten (int base, int intens)
624 {
625 switch (intens) {
626 case INT_D:
627 case INT_DD:
628 return base - 1;
629 case INT_P:
630 return base + 1;
631 default:
632 return base;
633 }
634 }
635
636 /*****************************************************************************
637 * NDFD_WxTable2() --
638 *
639 * Original: makeWxImageCodes() Marc Saccucci Jan 2004 (MDL)
640 * Adapted to NDFD_WxTable() Arthur Taylor / MDL
641 *
642 * PURPOSE
643 * To use the same weather table scheme used by Marc Saccucci in
644 * makeWxImageCodes() in the NDFD source tree. The purpose of both
645 * procedures is to simplify the weather string (aka ugly string) to a single
646 * integral code number, which contains the most relevant weather. The
647 * intent is to create a simpler field which can more readily be viewed as
648 * an image.
649 *
650 * ARGUMENTS
651 * ugly = The ugly weather string to encode. (Input)
652 *
653 * FILES/DATABASES: None
654 *
655 * RETURNS: int (the encoded number.)
656 *
657 * HISTORY
658 * 11/2002 Marc Saccucci (MDL): Created matching algorithm in
659 * makeWxImageCodes().
660 * 6/2003 MS: Altered matching combinations in makeWxImageCodes().
661 * 1/2004 MS: Updated to include intensity considerations for all Precip
662 types.
663 * 1/2004 Arthur Taylor (MDL/RSIS): Created NDFD_WxTable2()
664 *
665 * NOTES
666 * 1) The table used:
667 * new_code Sample Value Legend Value Description
668 * -------- ------------ -------------- ------------
669 * 0 - - No Predominant Weather
670 * 1 L- Rain (LoProb L-)
671 * 2 L Rain (LoProb L)
672 * 3 L+ Rain (LoProb L+)
673 * 4 R- Rain (LoProb R-)
674 * 5 R Rain (LoProb R)
675 * 6 R+ Rain (LoProb R+)
676 * 7 R/T+ Severe (LoProb R/T+)
677 * 8 T/R+ Rain (LoProb T/R+)
678 * 9 T/R- Rain (LoProb T/R-)
679 * 10 R/T Rain (LoProb R/T)
680 * 11 RW- Rain (LoProb RW-)
681 * 12 RW Rain (LoProb RW)
682 * 13 RW+ Rain (LoProb RW+)
683 * 14 RW/T+ Severe (LoProb RW/T+)
684 * 15 RW/T Rain (LoProb RW/T)
685 * 16 T/RW+ Rain (LoProb T/RW+)
686 * 17 T/RW- Rain (LoProb T/RW-)
687 * 18 T Rain (LoProb T)
688 * 19 T+ Severe (LoProb T+)
689 * 20 L- Rain (HiProb L-)
690 * 21 L Rain (HiProb L)
691 * 22 L+ Rain (HiProb L+)
692 * 23 R- Rain (HiProb R-)
693 * 24 R Rain (HiProb R)
694 * 25 R+ Rain (HiProb R+)
695 * 26 R/T+ Severe (HiProb R/T+)
696 * 27 R/T Rain (HiProb R/T)
697 * 28 T/R+ Rain (HiProb T/R+)
698 * 29 T/R- Rain (HiProb T/R-)
699 * 30 RW- Rain (HiProb RW-)
700 * 31 RW Rain (HiProb RW)
701 * 32 RW+ Rain (HiProb RW+)
702 * 33 RW/T Rain (HiProb RW/T)
703 * 34 RW/T+ Severe (HiProb RW/T+)
704 * 35 T/RW+ Rain (HiProb T/RW+)
705 * 36 T/RW- Rain (HiProb T/RW-)
706 * 37 T Rain (HiProb T)
707 * 38 T+ Severe (HiProb T+)
708 * 39 R/S- Mix (LoProb R/S-)
709 * 40 R/S Mix (LoProb R/S)
710 * 41 R/S+ Mix (LoProb R/S+)
711 * 42 RW/SW- Mix (LoProb RW/SW-)
712 * 43 RW/SW Mix (LoProb RW/SW)
713 * 44 RW/SW+ Mix (LoProb RW/SW+)
714 * 45 R/IP- Mix (LoProb R/IP-)
715 * 46 R/IP Mix (LoProb R/IP)
716 * 47 R/IP+ Mix (LoProb R/IP+)
717 * 48 S/IP- Mix (LoProb S/IP-)
718 * 49 S/IP Mix (LoProb S/IP)
719 * 50 S/IP+ Mix (LoProb S/IP+)
720 * 51 R/S- Mix (HiProb R/S-)
721 * 52 R/S Mix (HiProb R/S)
722 * 53 R/S+ Mix (HiProb R/S+)
723 * 54 RW/SW- Mix (HiProb RW/SW-)
724 * 55 RW/SW Mix (HiProb RW/SW)
725 * 56 RW/SW+ Mix (HiProb RW/SW+)
726 * 57 R/IP- Mix (HiProb R/IP-)
727 * 58 R/IP Mix (HiProb R/IP)
728 * 59 R/IP+ Mix (HiProb R/IP+)
729 * 60 S/IP- Mix (HiProb S/IP-)
730 * 61 S/IP Mix (HiProb S/IP)
731 * 62 S/IP+ Mix (HiProb S/IP+)
732 * 63 IP- Ice (LoProb IP-)
733 * 64 IP Ice (LoProb IP)
734 * 65 IP+ Ice (LoProb IP+)
735 * 66 ZL- Ice (LoProb ZL-)
736 * 67 ZL Ice (LoProb ZL)
737 * 68 ZL+ Ice (LoProb ZL+)
738 * 69 R/ZL- Ice (LoProb R/ZL-)
739 * 70 R/ZL Ice (LoProb R/ZL)
740 * 71 R/ZL+ Ice (LoProb R/ZL+)
741 * 72 ZR- Ice (LoProb ZR-)
742 * 73 ZR Ice (LoProb ZR)
743 * 74 ZR+ Ice (LoProb ZR+)
744 * 75 R/ZR- Ice (LoProb R/ZR-)
745 * 76 R/ZR Ice (LoProb R/ZR)
746 * 77 R/ZR+ Ice (LoProb R/ZR+)
747 * 78 IP/ZR- Ice (LoProb IP/ZR-)
748 * 79 IP/ZR Ice (LoProb IP/ZR)
749 * 80 IP/ZR+ Ice (LoProb IP/ZR+)
750 * 81 IP- Ice (HiProb IP-)
751 * 82 IP Ice (HiProb IP)
752 * 83 IP+ Ice (HiProb IP+)
753 * 84 ZL- Ice (HiProb ZL-)
754 * 85 ZL Ice (HiProb ZL)
755 * 86 ZL+ Ice (HiProb ZL+)
756 * 87 R/ZL- Ice (HiProb R/ZL-)
757 * 88 R/ZL Ice (HiProb R/ZL)
758 * 89 R/ZL+ Ice (HiProb R/ZL+)
759 * 90 ZR- Ice (HiProb ZR-)
760 * 91 ZR Ice (HiProb ZR)
761 * 92 ZR+ Ice (HiProb ZR+)
762 * 93 R/ZR- Ice (HiProb R/ZR-)
763 * 94 R/ZR Ice (HiProb R/ZR)
764 * 95 R/ZR+ Ice (HiProb R/ZR+)
765 * 96 IP/ZR- Ice (HiProb IP/ZR-)
766 * 97 IP/ZR Ice (HiProb IP/ZR)
767 * 98 IP/ZR+ Ice (HiProb IP/ZR+)
768 * 99 L/ZL- Ice (LoProb L/ZL-)
769 * 100 L/ZL Ice (LoProb L/ZL)
770 * 101 L/ZL+ Ice (LoProb L/ZL+)
771 * 102 L/ZL- Ice (HiProb L/ZL-)
772 * 103 L/ZL Ice (HiProb L/ZL)
773 * 104 L/ZL+ Ice (HiProb L/ZL+)
774 * 105 SW- Snow (LoProb SW-)
775 * 106 SW Snow (LoProb SW)
776 * 107 SW+ Snow (LoProb SW+)
777 * 108 S- Snow (LoProb S-)
778 * 109 S Snow (LoProb S)
779 * 110 S+ Snow (LoProb S+)
780 * 111 SW- Snow (HiProb SW-)
781 * 112 SW Snow (HiProb SW)
782 * 113 SW+ Snow (HiProb SW+)
783 * 114 S- Snow (HiProb S-)
784 * 115 S Snow (HiProb S)
785 * 116 S+ Snow (HiProb S+)
786 * 117 F Fog (Fog)
787 * 118 F+ Fog (Dense Fog)
788 * 119 H Haze
789 * 120 K Smoke
790 * 121 BS Blowing (Blowing Snow)
791 * 122 BD Blowing (Blowing Dust)
792 *****************************************************************************
793 */
NDFD_WxTable2(UglyStringType * ugly)794 static int NDFD_WxTable2 (UglyStringType * ugly)
795 {
796 switch (ugly->wx[0]) {
797 case WX_NOWX:
798 return 0;
799 case WX_R:
800 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
801 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
802 (ugly->cover[0] == COV_CHC)) {
803 switch (ugly->wx[1]) {
804 case WX_S:
805 return (NDFD_WxTable2_StdInten (40, ugly->intens[0]));
806 case WX_ZR: /* Rain/Freezing Rain */
807 return (NDFD_WxTable2_StdInten (76, ugly->intens[0]));
808 case WX_IP: /* Rain/Sleet */
809 return (NDFD_WxTable2_StdInten (46, ugly->intens[0]));
810 case WX_ZL: /* Rain/Freezing Drizzle */
811 return (NDFD_WxTable2_StdInten (70, ugly->intens[0]));
812 case WX_SW: /* Rain/Snow Showers */
813 return (NDFD_WxTable2_StdInten (40, ugly->intens[0]));
814 case WX_T: /* Rain/Thunderstorms */
815 switch (ugly->intens[0]) {
816 case INT_D:
817 case INT_DD:
818 return 9;
819 case INT_P:
820 return 8;
821 default:
822 return 27;
823 }
824 default:
825 return (NDFD_WxTable2_StdInten (5, ugly->intens[0]));
826 }
827 } else {
828 switch (ugly->wx[1]) {
829 case WX_S: /* Rain/Snow */
830 return (NDFD_WxTable2_StdInten (52, ugly->intens[0]));
831 case WX_ZR: /* Rain/Freezing Rain */
832 return (NDFD_WxTable2_StdInten (94, ugly->intens[0]));
833 case WX_IP: /* Rain/Sleet */
834 return (NDFD_WxTable2_StdInten (58, ugly->intens[0]));
835 case WX_ZL: /* Rain/Freezing Drizzle */
836 return (NDFD_WxTable2_StdInten (88, ugly->intens[0]));
837 case WX_SW: /* Rain/Snow Showers */
838 return (NDFD_WxTable2_StdInten (52, ugly->intens[0]));
839 case WX_T: /* Rain/Thunderstorms */
840 switch (ugly->intens[0]) {
841 case INT_D:
842 case INT_DD:
843 return 29;
844 case INT_P:
845 return 28;
846 default:
847 return 27;
848 }
849 default:
850 return (NDFD_WxTable2_StdInten (24, ugly->intens[0]));
851 }
852 }
853 case WX_RW:
854 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
855 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
856 (ugly->cover[0] == COV_CHC)) {
857 switch (ugly->wx[1]) {
858 case WX_T: /* Rain Showers/Thunderstorms */
859 switch (ugly->intens[0]) {
860 case INT_D:
861 case INT_DD:
862 return 17;
863 case INT_P:
864 return 16;
865 default:
866 return 15;
867 }
868 case WX_SW: /* Rain Showers/Snow Showers */
869 case WX_S: /* Rain Showers/Snow */
870 return (NDFD_WxTable2_StdInten (43, ugly->intens[0]));
871 default:
872 return (NDFD_WxTable2_StdInten (12, ugly->intens[0]));
873 }
874 } else {
875 switch (ugly->wx[1]) {
876 case WX_T: /* Rain Showers/Thunderstorms */
877 switch (ugly->intens[0]) {
878 case INT_D:
879 case INT_DD:
880 return 36;
881 case INT_P:
882 return 35;
883 default:
884 return 33;
885 }
886 case WX_SW: /* Rain Showers/Snow Showers */
887 case WX_S: /* Rain Showers/Snow */
888 return (NDFD_WxTable2_StdInten (55, ugly->intens[0]));
889 default:
890 return (NDFD_WxTable2_StdInten (31, ugly->intens[0]));
891 }
892 }
893 case WX_L:
894 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
895 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
896 (ugly->cover[0] == COV_CHC)) {
897 switch (ugly->wx[1]) {
898 case WX_ZL: /* Drizzle/Freezing Drizzle */
899 return (NDFD_WxTable2_StdInten (100, ugly->intens[0]));
900 case WX_F:
901 default: /* Drizzle */
902 return (NDFD_WxTable2_StdInten (2, ugly->intens[0]));
903 }
904 } else {
905 switch (ugly->wx[1]) {
906 case WX_ZL: /* Drizzle/Freezing Drizzle */
907 return (NDFD_WxTable2_StdInten (103, ugly->intens[0]));
908 case WX_F:
909 default: /* Drizzle */
910 return (NDFD_WxTable2_StdInten (21, ugly->intens[0]));
911 }
912 }
913 case WX_ZL:
914 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
915 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
916 (ugly->cover[0] == COV_CHC)) {
917 switch (ugly->wx[1]) {
918 case WX_R: /* Freezing Drizzle/Rain */
919 return (NDFD_WxTable2_StdInten (70, ugly->intens[0]));
920 case WX_L: /* Freezing Drizzle/Drizzle */
921 return (NDFD_WxTable2_StdInten (100, ugly->intens[0]));
922 default:
923 return (NDFD_WxTable2_StdInten (67, ugly->intens[0]));
924 }
925 } else {
926 switch (ugly->wx[1]) {
927 case WX_R: /* Freezing Drizzle/Rain */
928 return (NDFD_WxTable2_StdInten (88, ugly->intens[0]));
929 case WX_L: /* Freezing Drizzle/Drizzle */
930 return (NDFD_WxTable2_StdInten (103, ugly->intens[0]));
931 default: /* Freezing Drizzle */
932 return (NDFD_WxTable2_StdInten (85, ugly->intens[0]));
933 }
934 }
935 case WX_ZR:
936 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
937 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
938 (ugly->cover[0] == COV_CHC)) {
939 switch (ugly->wx[1]) {
940 case WX_R: /* Freezing Rain/Rain */
941 return (NDFD_WxTable2_StdInten (76, ugly->intens[0]));
942 case WX_IP: /* Freezing Rain/Sleet */
943 return (NDFD_WxTable2_StdInten (79, ugly->intens[0]));
944 default:
945 return (NDFD_WxTable2_StdInten (73, ugly->intens[0]));
946 }
947 } else {
948 switch (ugly->wx[1]) {
949 case WX_R: /* Freezing Rain/Rain */
950 return (NDFD_WxTable2_StdInten (94, ugly->intens[0]));
951 case WX_IP: /* Freezing Rain/Sleet */
952 return (NDFD_WxTable2_StdInten (97, ugly->intens[0]));
953 default:
954 return (NDFD_WxTable2_StdInten (91, ugly->intens[0]));
955 }
956 }
957 case WX_IP:
958 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
959 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
960 (ugly->cover[0] == COV_CHC)) {
961 switch (ugly->wx[1]) {
962 case WX_R: /* Sleet/Rain */
963 return (NDFD_WxTable2_StdInten (46, ugly->intens[0]));
964 case WX_S: /* Sleet/Snow */
965 return (NDFD_WxTable2_StdInten (49, ugly->intens[0]));
966 case WX_ZR: /* Sleet/Freezing Rain */
967 return (NDFD_WxTable2_StdInten (79, ugly->intens[0]));
968 default:
969 return (NDFD_WxTable2_StdInten (64, ugly->intens[0]));
970 }
971 } else {
972 switch (ugly->wx[1]) {
973 case WX_R: /* Sleet/Rain */
974 return (NDFD_WxTable2_StdInten (58, ugly->intens[0]));
975 case WX_S: /* Sleet/Snow */
976 return (NDFD_WxTable2_StdInten (61, ugly->intens[0]));
977 case WX_ZR: /* Sleet/Freezing Rain */
978 return (NDFD_WxTable2_StdInten (97, ugly->intens[0]));
979 default:
980 return (NDFD_WxTable2_StdInten (82, ugly->intens[0]));
981 }
982 }
983 case WX_SW:
984 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
985 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
986 (ugly->cover[0] == COV_CHC)) {
987 switch (ugly->wx[1]) {
988 case WX_R: /* Snow Showers/Rain */
989 case WX_RW: /* Snow Showers/Rain Showers */
990 return (NDFD_WxTable2_StdInten (43, ugly->intens[0]));
991 default: /* Snow Showers */
992 return (NDFD_WxTable2_StdInten (106, ugly->intens[0]));
993 }
994 } else {
995 switch (ugly->wx[1]) {
996 case WX_R: /* Snow Showers/Rain */
997 case WX_RW: /* Snow Showers/Rain Showers */
998 return (NDFD_WxTable2_StdInten (55, ugly->intens[0]));
999 default: /* Snow Showers */
1000 return (NDFD_WxTable2_StdInten (112, ugly->intens[0]));
1001 }
1002 }
1003 case WX_S:
1004 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
1005 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
1006 (ugly->cover[0] == COV_CHC)) {
1007 switch (ugly->wx[1]) {
1008 case WX_R: /* Snow/Rain */
1009 case WX_RW: /* Snow/Rain Showers */
1010 return (NDFD_WxTable2_StdInten (40, ugly->intens[0]));
1011 case WX_IP: /* Snow/Sleet */
1012 return (NDFD_WxTable2_StdInten (49, ugly->intens[0]));
1013 default:
1014 return (NDFD_WxTable2_StdInten (109, ugly->intens[0]));
1015 }
1016 } else {
1017 switch (ugly->wx[1]) {
1018 case WX_R: /* Snow/Rain */
1019 case WX_RW:
1020 return (NDFD_WxTable2_StdInten (52, ugly->intens[0]));
1021 case WX_IP: /* Snow/Sleet */
1022 return (NDFD_WxTable2_StdInten (61, ugly->intens[0]));
1023 default:
1024 return (NDFD_WxTable2_StdInten (115, ugly->intens[0]));
1025 }
1026 }
1027 case WX_T:
1028 /*
1029 * Check Severe storms. If so, this is most important weather
1030 * type.
1031 */
1032 /*
1033 if (ugly->intens[0] == INT_P) {
1034 return 17; * Severe Thunderstorms *
1035 }
1036 */
1037 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
1038 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
1039 (ugly->cover[0] == COV_CHC)) {
1040 switch (ugly->wx[1]) {
1041 case WX_RW: /* Thunderstorms/Rain Showers */
1042 switch (ugly->intens[0]) {
1043 case INT_D:
1044 case INT_DD:
1045 return 17;
1046 case INT_P:
1047 return 14;
1048 default:
1049 return 15;
1050 }
1051 case WX_R: /* Thunderstorms/Rain */
1052 switch (ugly->intens[0]) {
1053 case INT_D:
1054 case INT_DD:
1055 return 9;
1056 case INT_P:
1057 return 7;
1058 default:
1059 return 10;
1060 }
1061 default: /* Thunderstorms. */
1062 switch (ugly->intens[0]) {
1063 case INT_D:
1064 case INT_DD:
1065 return 18;
1066 case INT_P:
1067 return 19;
1068 default:
1069 return 18;
1070 }
1071 }
1072 } else {
1073 switch (ugly->wx[1]) {
1074 case WX_RW: /* Thunderstorms/Rain Showers */
1075 switch (ugly->intens[0]) {
1076 case INT_D:
1077 case INT_DD:
1078 return 36;
1079 case INT_P:
1080 return 34;
1081 default:
1082 return 33; /* corrected from 37 */
1083 }
1084 case WX_R: /* Thunderstorms/Rain */
1085 switch (ugly->intens[0]) {
1086 case INT_D:
1087 case INT_DD:
1088 return 29;
1089 case INT_P:
1090 return 26;
1091 default:
1092 return 27;
1093 }
1094 default: /* Thunderstorms. */
1095 switch (ugly->intens[0]) {
1096 case INT_D:
1097 case INT_DD:
1098 return 37;
1099 case INT_P:
1100 return 38;
1101 default:
1102 return 37;
1103 }
1104 }
1105 }
1106 case WX_A: /* Ignore Hail */
1107 return 0;
1108 case WX_F: /* Fog */
1109 switch (ugly->intens[0]) {
1110 case INT_P:
1111 return 118;
1112 default:
1113 return 117;
1114 }
1115 case WX_H: /* Haze */
1116 return 119;
1117 case WX_K: /* Smoke */
1118 return 120;
1119 case WX_FR: /* Ignore Frost */
1120 return 0;
1121 case WX_BS: /* Blowing Snow */
1122 return 121;
1123 case WX_BD: /* Blowing Dust */
1124 return 122;
1125 default:
1126 return 0;
1127 }
1128 }
1129
1130 /*****************************************************************************
1131 * NDFD_WxTable3() --
1132 *
1133 * Original: makeWxImageCodes() Marc Saccucci Feb 2004 (MDL)
1134 * Adapted to NDFD_WxTable3() Arthur Taylor / MDL
1135 *
1136 * PURPOSE
1137 * To use the same weather table scheme used by Marc Saccucci in
1138 * makeWxImageCodes() in the NDFD source tree. The purpose of both
1139 * procedures is to simplify the weather string (aka ugly string) to a single
1140 * integral code number, which contains the most relevant weather. The
1141 * intent is to create a simpler field which can more readily be viewed as
1142 * an image.
1143 *
1144 * ARGUMENTS
1145 * ugly = The ugly weather string to encode. (Input)
1146 *
1147 * FILES/DATABASES: None
1148 *
1149 * RETURNS: int (the encoded number.)
1150 *
1151 * HISTORY
1152 * 11/2002 Marc Saccucci (MDL): Created matching algorithm in
1153 * makeWxImageCodes().
1154 * 6/2003 MS: Altered matching combinations in makeWxImageCodes().
1155 * 1/2004 MS: Updated to include intensity considerations for all Precip
1156 * types.
1157 * 2/2004 MS: Updated to include: 123..129 ZF, IF, IC, BN, ZY, VA, WP
1158 * 2/2004 Arthur Taylor (MDL/RSIS): Created NDFD_WxTable3()
1159 *
1160 * NOTES
1161 * 1) The table used:
1162 * new_code Sample Value Legend Value Description
1163 * -------- ------------ -------------- ------------
1164 * 0 - - No Predominant Weather
1165 * 1 L- Rain (LoProb L-)
1166 * 2 L Rain (LoProb L)
1167 * 3 L+ Rain (LoProb L+)
1168 * 4 R- Rain (LoProb R-)
1169 * 5 R Rain (LoProb R)
1170 * 6 R+ Rain (LoProb R+)
1171 * 7 R/T+ Severe (LoProb R/T+)
1172 * 8 T/R+ Rain (LoProb T/R+)
1173 * 9 T/R- Rain (LoProb T/R-)
1174 * 10 R/T Rain (LoProb R/T)
1175 * 11 RW- Rain (LoProb RW-)
1176 * 12 RW Rain (LoProb RW)
1177 * 13 RW+ Rain (LoProb RW+)
1178 * 14 RW/T+ Severe (LoProb RW/T+)
1179 * 15 RW/T Rain (LoProb RW/T)
1180 * 16 T/RW+ Rain (LoProb T/RW+)
1181 * 17 T/RW- Rain (LoProb T/RW-)
1182 * 18 T Rain (LoProb T)
1183 * 19 T+ Severe (LoProb T+)
1184 * 20 L- Rain (HiProb L-)
1185 * 21 L Rain (HiProb L)
1186 * 22 L+ Rain (HiProb L+)
1187 * 23 R- Rain (HiProb R-)
1188 * 24 R Rain (HiProb R)
1189 * 25 R+ Rain (HiProb R+)
1190 * 26 R/T+ Severe (HiProb R/T+)
1191 * 27 R/T Rain (HiProb R/T)
1192 * 28 T/R+ Rain (HiProb T/R+)
1193 * 29 T/R- Rain (HiProb T/R-)
1194 * 30 RW- Rain (HiProb RW-)
1195 * 31 RW Rain (HiProb RW)
1196 * 32 RW+ Rain (HiProb RW+)
1197 * 33 RW/T Rain (HiProb RW/T)
1198 * 34 RW/T+ Severe (HiProb RW/T+)
1199 * 35 T/RW+ Rain (HiProb T/RW+)
1200 * 36 T/RW- Rain (HiProb T/RW-)
1201 * 37 T Rain (HiProb T)
1202 * 38 T+ Severe (HiProb T+)
1203 * 39 R/S- Mix (LoProb R/S-)
1204 * 40 R/S Mix (LoProb R/S)
1205 * 41 R/S+ Mix (LoProb R/S+)
1206 * 42 RW/SW- Mix (LoProb RW/SW-)
1207 * 43 RW/SW Mix (LoProb RW/SW)
1208 * 44 RW/SW+ Mix (LoProb RW/SW+)
1209 * 45 R/IP- Mix (LoProb R/IP-)
1210 * 46 R/IP Mix (LoProb R/IP)
1211 * 47 R/IP+ Mix (LoProb R/IP+)
1212 * 48 S/IP- Mix (LoProb S/IP-)
1213 * 49 S/IP Mix (LoProb S/IP)
1214 * 50 S/IP+ Mix (LoProb S/IP+)
1215 * 51 R/S- Mix (HiProb R/S-)
1216 * 52 R/S Mix (HiProb R/S)
1217 * 53 R/S+ Mix (HiProb R/S+)
1218 * 54 RW/SW- Mix (HiProb RW/SW-)
1219 * 55 RW/SW Mix (HiProb RW/SW)
1220 * 56 RW/SW+ Mix (HiProb RW/SW+)
1221 * 57 R/IP- Mix (HiProb R/IP-)
1222 * 58 R/IP Mix (HiProb R/IP)
1223 * 59 R/IP+ Mix (HiProb R/IP+)
1224 * 60 S/IP- Mix (HiProb S/IP-)
1225 * 61 S/IP Mix (HiProb S/IP)
1226 * 62 S/IP+ Mix (HiProb S/IP+)
1227 * 63 IP- Ice (LoProb IP-)
1228 * 64 IP Ice (LoProb IP)
1229 * 65 IP+ Ice (LoProb IP+)
1230 * 66 ZL- Ice (LoProb ZL-)
1231 * 67 ZL Ice (LoProb ZL)
1232 * 68 ZL+ Ice (LoProb ZL+)
1233 * 69 R/ZL- Ice (LoProb R/ZL-)
1234 * 70 R/ZL Ice (LoProb R/ZL)
1235 * 71 R/ZL+ Ice (LoProb R/ZL+)
1236 * 72 ZR- Ice (LoProb ZR-)
1237 * 73 ZR Ice (LoProb ZR)
1238 * 74 ZR+ Ice (LoProb ZR+)
1239 * 75 R/ZR- Ice (LoProb R/ZR-)
1240 * 76 R/ZR Ice (LoProb R/ZR)
1241 * 77 R/ZR+ Ice (LoProb R/ZR+)
1242 * 78 IP/ZR- Ice (LoProb IP/ZR-)
1243 * 79 IP/ZR Ice (LoProb IP/ZR)
1244 * 80 IP/ZR+ Ice (LoProb IP/ZR+)
1245 * 81 IP- Ice (HiProb IP-)
1246 * 82 IP Ice (HiProb IP)
1247 * 83 IP+ Ice (HiProb IP+)
1248 * 84 ZL- Ice (HiProb ZL-)
1249 * 85 ZL Ice (HiProb ZL)
1250 * 86 ZL+ Ice (HiProb ZL+)
1251 * 87 R/ZL- Ice (HiProb R/ZL-)
1252 * 88 R/ZL Ice (HiProb R/ZL)
1253 * 89 R/ZL+ Ice (HiProb R/ZL+)
1254 * 90 ZR- Ice (HiProb ZR-)
1255 * 91 ZR Ice (HiProb ZR)
1256 * 92 ZR+ Ice (HiProb ZR+)
1257 * 93 R/ZR- Ice (HiProb R/ZR-)
1258 * 94 R/ZR Ice (HiProb R/ZR)
1259 * 95 R/ZR+ Ice (HiProb R/ZR+)
1260 * 96 IP/ZR- Ice (HiProb IP/ZR-)
1261 * 97 IP/ZR Ice (HiProb IP/ZR)
1262 * 98 IP/ZR+ Ice (HiProb IP/ZR+)
1263 * 99 L/ZL- Ice (LoProb L/ZL-)
1264 * 100 L/ZL Ice (LoProb L/ZL)
1265 * 101 L/ZL+ Ice (LoProb L/ZL+)
1266 * 102 L/ZL- Ice (HiProb L/ZL-)
1267 * 103 L/ZL Ice (HiProb L/ZL)
1268 * 104 L/ZL+ Ice (HiProb L/ZL+)
1269 * 105 SW- Snow (LoProb SW-)
1270 * 106 SW Snow (LoProb SW)
1271 * 107 SW+ Snow (LoProb SW+)
1272 * 108 S- Snow (LoProb S-)
1273 * 109 S Snow (LoProb S)
1274 * 110 S+ Snow (LoProb S+)
1275 * 111 SW- Snow (HiProb SW-)
1276 * 112 SW Snow (HiProb SW)
1277 * 113 SW+ Snow (HiProb SW+)
1278 * 114 S- Snow (HiProb S-)
1279 * 115 S Snow (HiProb S)
1280 * 116 S+ Snow (HiProb S+)
1281 * 117 F Fog (Fog)
1282 * 118 F+ Fog (Dense Fog)
1283 * 119 H Haze
1284 * 120 K Smoke
1285 * 121 BS Blowing (Blowing Snow)
1286 * 122 BD Blowing (Blowing Dust)
1287 * 123 ZF Fog (Freezing Fog)
1288 * 124 IF Fog (Ice Fog)
1289 * 125 IC Ice (Ice Crystals)
1290 * 126 BN Blowing (Blowing Sand)
1291 * 127 ZY Blowing (Freezing Spray)
1292 * 128 VA Smoke (Volcanic Ash)
1293 * 129 WP Severe (Water Spouts)
1294 *****************************************************************************
1295 */
NDFD_WxTable3(UglyStringType * ugly)1296 static int NDFD_WxTable3 (UglyStringType * ugly)
1297 {
1298 switch (ugly->wx[0]) {
1299 case WX_NOWX:
1300 return 0;
1301 case WX_R:
1302 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
1303 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
1304 (ugly->cover[0] == COV_CHC)) {
1305 switch (ugly->wx[1]) {
1306 case WX_S:
1307 return (NDFD_WxTable2_StdInten (40, ugly->intens[0]));
1308 case WX_ZR: /* Rain/Freezing Rain */
1309 return (NDFD_WxTable2_StdInten (76, ugly->intens[0]));
1310 case WX_IP: /* Rain/Sleet */
1311 return (NDFD_WxTable2_StdInten (46, ugly->intens[0]));
1312 case WX_ZL: /* Rain/Freezing Drizzle */
1313 return (NDFD_WxTable2_StdInten (70, ugly->intens[0]));
1314 case WX_SW: /* Rain/Snow Showers */
1315 return (NDFD_WxTable2_StdInten (40, ugly->intens[0]));
1316 case WX_T: /* Rain/Thunderstorms */
1317 switch (ugly->intens[0]) {
1318 case INT_D:
1319 case INT_DD:
1320 return 9;
1321 case INT_P:
1322 return 8;
1323 default:
1324 return 27;
1325 }
1326 default:
1327 return (NDFD_WxTable2_StdInten (5, ugly->intens[0]));
1328 }
1329 } else {
1330 switch (ugly->wx[1]) {
1331 case WX_S: /* Rain/Snow */
1332 return (NDFD_WxTable2_StdInten (52, ugly->intens[0]));
1333 case WX_ZR: /* Rain/Freezing Rain */
1334 return (NDFD_WxTable2_StdInten (94, ugly->intens[0]));
1335 case WX_IP: /* Rain/Sleet */
1336 return (NDFD_WxTable2_StdInten (58, ugly->intens[0]));
1337 case WX_ZL: /* Rain/Freezing Drizzle */
1338 return (NDFD_WxTable2_StdInten (88, ugly->intens[0]));
1339 case WX_SW: /* Rain/Snow Showers */
1340 return (NDFD_WxTable2_StdInten (52, ugly->intens[0]));
1341 case WX_T: /* Rain/Thunderstorms */
1342 switch (ugly->intens[0]) {
1343 case INT_D:
1344 case INT_DD:
1345 return 29;
1346 case INT_P:
1347 return 28;
1348 default:
1349 return 27;
1350 }
1351 default:
1352 return (NDFD_WxTable2_StdInten (24, ugly->intens[0]));
1353 }
1354 }
1355 case WX_RW:
1356 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
1357 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
1358 (ugly->cover[0] == COV_CHC)) {
1359 switch (ugly->wx[1]) {
1360 case WX_T: /* Rain Showers/Thunderstorms */
1361 switch (ugly->intens[0]) {
1362 case INT_D:
1363 case INT_DD:
1364 return 17;
1365 case INT_P:
1366 return 16;
1367 default:
1368 return 15;
1369 }
1370 case WX_SW: /* Rain Showers/Snow Showers */
1371 case WX_S: /* Rain Showers/Snow */
1372 return (NDFD_WxTable2_StdInten (43, ugly->intens[0]));
1373 default:
1374 return (NDFD_WxTable2_StdInten (12, ugly->intens[0]));
1375 }
1376 } else {
1377 switch (ugly->wx[1]) {
1378 case WX_T: /* Rain Showers/Thunderstorms */
1379 switch (ugly->intens[0]) {
1380 case INT_D:
1381 case INT_DD:
1382 return 36;
1383 case INT_P:
1384 return 35;
1385 default:
1386 return 33;
1387 }
1388 case WX_SW: /* Rain Showers/Snow Showers */
1389 case WX_S: /* Rain Showers/Snow */
1390 return (NDFD_WxTable2_StdInten (55, ugly->intens[0]));
1391 default:
1392 return (NDFD_WxTable2_StdInten (31, ugly->intens[0]));
1393 }
1394 }
1395 case WX_L:
1396 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
1397 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
1398 (ugly->cover[0] == COV_CHC)) {
1399 switch (ugly->wx[1]) {
1400 case WX_ZL: /* Drizzle/Freezing Drizzle */
1401 return (NDFD_WxTable2_StdInten (100, ugly->intens[0]));
1402 case WX_F:
1403 default: /* Drizzle */
1404 return (NDFD_WxTable2_StdInten (2, ugly->intens[0]));
1405 }
1406 } else {
1407 switch (ugly->wx[1]) {
1408 case WX_ZL: /* Drizzle/Freezing Drizzle */
1409 return (NDFD_WxTable2_StdInten (103, ugly->intens[0]));
1410 case WX_F:
1411 default: /* Drizzle */
1412 return (NDFD_WxTable2_StdInten (21, ugly->intens[0]));
1413 }
1414 }
1415 case WX_ZL:
1416 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
1417 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
1418 (ugly->cover[0] == COV_CHC)) {
1419 switch (ugly->wx[1]) {
1420 case WX_R: /* Freezing Drizzle/Rain */
1421 return (NDFD_WxTable2_StdInten (70, ugly->intens[0]));
1422 case WX_L: /* Freezing Drizzle/Drizzle */
1423 return (NDFD_WxTable2_StdInten (100, ugly->intens[0]));
1424 default:
1425 return (NDFD_WxTable2_StdInten (67, ugly->intens[0]));
1426 }
1427 } else {
1428 switch (ugly->wx[1]) {
1429 case WX_R: /* Freezing Drizzle/Rain */
1430 return (NDFD_WxTable2_StdInten (88, ugly->intens[0]));
1431 case WX_L: /* Freezing Drizzle/Drizzle */
1432 return (NDFD_WxTable2_StdInten (103, ugly->intens[0]));
1433 default: /* Freezing Drizzle */
1434 return (NDFD_WxTable2_StdInten (85, ugly->intens[0]));
1435 }
1436 }
1437 case WX_ZR:
1438 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
1439 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
1440 (ugly->cover[0] == COV_CHC)) {
1441 switch (ugly->wx[1]) {
1442 case WX_R: /* Freezing Rain/Rain */
1443 return (NDFD_WxTable2_StdInten (76, ugly->intens[0]));
1444 case WX_IP: /* Freezing Rain/Sleet */
1445 return (NDFD_WxTable2_StdInten (79, ugly->intens[0]));
1446 default:
1447 return (NDFD_WxTable2_StdInten (73, ugly->intens[0]));
1448 }
1449 } else {
1450 switch (ugly->wx[1]) {
1451 case WX_R: /* Freezing Rain/Rain */
1452 return (NDFD_WxTable2_StdInten (94, ugly->intens[0]));
1453 case WX_IP: /* Freezing Rain/Sleet */
1454 return (NDFD_WxTable2_StdInten (97, ugly->intens[0]));
1455 default:
1456 return (NDFD_WxTable2_StdInten (91, ugly->intens[0]));
1457 }
1458 }
1459 case WX_IP:
1460 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
1461 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
1462 (ugly->cover[0] == COV_CHC)) {
1463 switch (ugly->wx[1]) {
1464 case WX_R: /* Sleet/Rain */
1465 return (NDFD_WxTable2_StdInten (46, ugly->intens[0]));
1466 case WX_S: /* Sleet/Snow */
1467 return (NDFD_WxTable2_StdInten (49, ugly->intens[0]));
1468 case WX_ZR: /* Sleet/Freezing Rain */
1469 return (NDFD_WxTable2_StdInten (79, ugly->intens[0]));
1470 default:
1471 return (NDFD_WxTable2_StdInten (64, ugly->intens[0]));
1472 }
1473 } else {
1474 switch (ugly->wx[1]) {
1475 case WX_R: /* Sleet/Rain */
1476 return (NDFD_WxTable2_StdInten (58, ugly->intens[0]));
1477 case WX_S: /* Sleet/Snow */
1478 return (NDFD_WxTable2_StdInten (61, ugly->intens[0]));
1479 case WX_ZR: /* Sleet/Freezing Rain */
1480 return (NDFD_WxTable2_StdInten (97, ugly->intens[0]));
1481 default:
1482 return (NDFD_WxTable2_StdInten (82, ugly->intens[0]));
1483 }
1484 }
1485 case WX_SW:
1486 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
1487 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
1488 (ugly->cover[0] == COV_CHC)) {
1489 switch (ugly->wx[1]) {
1490 case WX_R: /* Snow Showers/Rain */
1491 case WX_RW: /* Snow Showers/Rain Showers */
1492 return (NDFD_WxTable2_StdInten (43, ugly->intens[0]));
1493 default: /* Snow Showers */
1494 return (NDFD_WxTable2_StdInten (106, ugly->intens[0]));
1495 }
1496 } else {
1497 switch (ugly->wx[1]) {
1498 case WX_R: /* Snow Showers/Rain */
1499 case WX_RW: /* Snow Showers/Rain Showers */
1500 return (NDFD_WxTable2_StdInten (55, ugly->intens[0]));
1501 default: /* Snow Showers */
1502 return (NDFD_WxTable2_StdInten (112, ugly->intens[0]));
1503 }
1504 }
1505 case WX_S:
1506 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
1507 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
1508 (ugly->cover[0] == COV_CHC)) {
1509 switch (ugly->wx[1]) {
1510 case WX_R: /* Snow/Rain */
1511 case WX_RW: /* Snow/Rain Showers */
1512 return (NDFD_WxTable2_StdInten (40, ugly->intens[0]));
1513 case WX_IP: /* Snow/Sleet */
1514 return (NDFD_WxTable2_StdInten (49, ugly->intens[0]));
1515 default:
1516 return (NDFD_WxTable2_StdInten (109, ugly->intens[0]));
1517 }
1518 } else {
1519 switch (ugly->wx[1]) {
1520 case WX_R: /* Snow/Rain */
1521 case WX_RW:
1522 return (NDFD_WxTable2_StdInten (52, ugly->intens[0]));
1523 case WX_IP: /* Snow/Sleet */
1524 return (NDFD_WxTable2_StdInten (61, ugly->intens[0]));
1525 default:
1526 return (NDFD_WxTable2_StdInten (115, ugly->intens[0]));
1527 }
1528 }
1529 case WX_T:
1530 if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
1531 (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
1532 (ugly->cover[0] == COV_CHC)) {
1533 switch (ugly->wx[1]) {
1534 case WX_RW: /* Thunderstorms/Rain Showers */
1535 switch (ugly->intens[0]) {
1536 case INT_D:
1537 case INT_DD:
1538 return 17;
1539 case INT_P:
1540 return 14;
1541 default:
1542 return 15;
1543 }
1544 case WX_R: /* Thunderstorms/Rain */
1545 switch (ugly->intens[0]) {
1546 case INT_D:
1547 case INT_DD:
1548 return 9;
1549 case INT_P:
1550 return 7;
1551 default:
1552 return 10;
1553 }
1554 default: /* Thunderstorms. */
1555 switch (ugly->intens[0]) {
1556 case INT_D:
1557 case INT_DD:
1558 return 18;
1559 case INT_P:
1560 return 19;
1561 default:
1562 return 18;
1563 }
1564 }
1565 } else {
1566 switch (ugly->wx[1]) {
1567 case WX_RW: /* Thunderstorms/Rain Showers */
1568 switch (ugly->intens[0]) {
1569 case INT_D:
1570 case INT_DD:
1571 return 36;
1572 case INT_P:
1573 return 34;
1574 default:
1575 return 33;
1576 }
1577 case WX_R: /* Thunderstorms/Rain */
1578 switch (ugly->intens[0]) {
1579 case INT_D:
1580 case INT_DD:
1581 return 29;
1582 case INT_P:
1583 return 26;
1584 default:
1585 return 27;
1586 }
1587 default: /* Thunderstorms. */
1588 switch (ugly->intens[0]) {
1589 case INT_D:
1590 case INT_DD:
1591 return 37;
1592 case INT_P:
1593 return 38;
1594 default:
1595 return 37;
1596 }
1597 }
1598 }
1599 case WX_A: /* Ignore Hail */
1600 return 0;
1601 case WX_F: /* Fog */
1602 switch (ugly->intens[0]) {
1603 case INT_P:
1604 return 118;
1605 default:
1606 return 117;
1607 }
1608 case WX_H: /* Haze */
1609 return 119;
1610 case WX_K: /* Smoke */
1611 return 120;
1612 case WX_FR: /* Ignore Frost */
1613 return 0;
1614 case WX_BS: /* Blowing Snow */
1615 return 121;
1616 case WX_BD: /* Blowing Dust */
1617 return 122;
1618 case WX_ZF: /* Freezing Fog */
1619 return 123;
1620 case WX_IF: /* Ice Fog */
1621 return 124;
1622 case WX_IC: /* Ice Crystals */
1623 return 125;
1624 case WX_BN: /* Blowing Sand */
1625 return 126;
1626 case WX_ZY: /* Freezing Spray */
1627 return 127;
1628 case WX_VA: /* Volcanic Ash */
1629 return 128;
1630 case WX_WP: /* Water Spouts */
1631 return 129;
1632 default:
1633 return 0;
1634 }
1635 }
1636
1637 /*****************************************************************************
1638 * NDFD_Wx2Code4() --
1639 *
1640 * Original: wx2code() Mark Armstrong Nov 2004 (MDL)
1641 * Adapted to NDFD_Wx2Code() Arthur Taylor (MDL)
1642 *
1643 * PURPOSE
1644 * Converts from a Weather Type to the code value used in makeWxImageCodes.
1645 *
1646 * ARGUMENTS
1647 * wxtype = The weather type to encode. (Input)
1648 *
1649 * FILES/DATABASES: None
1650 *
1651 * RETURNS: int (the encoded number.)
1652 *
1653 * HISTORY
1654 * 11/2004 Mark Armstrong (MDL): Created matching algorithm "wx2code"
1655 * 11/2004 Arthur Taylor (MDL): Modified to assist with NDFD_WxTable4()
1656 *
1657 * NOTES
1658 *****************************************************************************
1659 */
NDFD_Wx2Code4(int wxtype)1660 static int NDFD_Wx2Code4 (int wxtype)
1661 {
1662 switch (wxtype) {
1663 case WX_R:
1664 return 0;
1665 case WX_RW:
1666 return 10;
1667 case WX_L:
1668 return 20;
1669 case WX_ZL:
1670 return 30;
1671 case WX_ZR:
1672 return 40;
1673 case WX_IP:
1674 return 50;
1675 case WX_SW:
1676 return 60;
1677 case WX_S:
1678 return 70;
1679 case WX_T:
1680 return 80;
1681 case WX_F:
1682 return 90;
1683 default:
1684 return 0;
1685 }
1686 }
1687
1688 /*****************************************************************************
1689 * NDFD_CodeIntens4() --
1690 *
1691 * Original: code_intensity() Mark Armstrong Nov 2004 (MDL)
1692 * Adapted to NDFD_CodeIntens4() Arthur Taylor (MDL)
1693 *
1694 * PURPOSE
1695 * Converts from two types of weather intensities to the code value used in
1696 * makeWxImageCodes when dealing with intensities.
1697 *
1698 * ARGUMENTS
1699 * inten1 = The first intensity to encode. (Input)
1700 * inten2 = The second intensity to encode. (Input)
1701 *
1702 * FILES/DATABASES: None
1703 *
1704 * RETURNS: int (the encoded number.)
1705 *
1706 * HISTORY
1707 * 11/2004 Mark Armstrong (MDL): Created matching algorithm "code_intensity"
1708 * 11/2004 Arthur Taylor (MDL): Modified to assist with NDFD_WxTable4()
1709 *
1710 * NOTES
1711 *****************************************************************************
1712 */
NDFD_CodeIntens4(int inten1,int inten2)1713 static int NDFD_CodeIntens4 (int inten1, int inten2)
1714 {
1715 switch (inten2) {
1716 case INT_NOINT:
1717 case INT_UNKNOWN:
1718 case INT_M:
1719 if ((inten1 == INT_NOINT) || (inten1 == INT_UNKNOWN) ||
1720 (inten1 == INT_M)) {
1721 return 0;
1722 } else if ((inten1 == INT_D) || (inten1 == INT_DD)) {
1723 return 1;
1724 }
1725 /* Default case */
1726 /* else if (inten1 == INT_P) */
1727 return 2;
1728 case INT_D:
1729 case INT_DD:
1730 if ((inten1 == INT_NOINT) || (inten1 == INT_UNKNOWN) ||
1731 (inten1 == INT_M)) {
1732 return 3;
1733 } else if ((inten1 == INT_D) || (inten1 == INT_DD)) {
1734 return 4;
1735 }
1736 /* Default case */
1737 /* else if (inten1 == INT_P) */
1738 return 5;
1739 case INT_P:
1740 default:
1741 if ((inten1 == INT_NOINT) || (inten1 == INT_UNKNOWN) ||
1742 (inten1 == INT_M)) {
1743 return 6;
1744 } else if ((inten1 == INT_D) || (inten1 == INT_DD)) {
1745 return 7;
1746 }
1747 /* Default case */
1748 /* else if (inten1 == INT_P) */
1749 return 8;
1750 }
1751 }
1752
1753 /*****************************************************************************
1754 * NDFD_WxTable4() --
1755 *
1756 * Original: makeWxImageCodes() Mark Armstrong Nov 2004 (MDL)
1757 * Adapted to NDFD_WxTable4() Arthur Taylor (MDL)
1758 *
1759 * PURPOSE
1760 * To use the same weather table scheme used by Mark Armstrong in
1761 * makeWxImageCodes(). The purpose of both procedures is to simplify the
1762 * weather string (aka ugly string) to a single integral code number, which
1763 * contains the most relevant weather. The intent is to create a simpler
1764 * field which can more readily be viewed as an image.
1765 *
1766 * ARGUMENTS
1767 * ugly = The ugly weather string to encode. (Input)
1768 *
1769 * FILES/DATABASES: None
1770 *
1771 * RETURNS: int (the encoded number.)
1772 *
1773 * HISTORY
1774 * 11/2004 Mark Armstrong (MDL): Created "makeWxImageCodes"
1775 * 11/2004 Arthur Taylor (MDL): Created NDFD_WxTable4
1776 *
1777 * NOTES
1778 * 1) The table used... In the past I have included the table as part of the
1779 * documentation here, but since the table is now > 1000 lines long, I think
1780 * it best to look in "/degrib/data/imageGen/colortable/Wx_200411.colortable"
1781 *****************************************************************************
1782 */
NDFD_WxTable4(UglyStringType * ugly)1783 static int NDFD_WxTable4 (UglyStringType * ugly)
1784 {
1785 int code = 0;
1786 int numValid = ugly->numValid;
1787 int cover1 = ugly->cover[1];
1788 int intens1 = ugly->intens[1];
1789
1790 if (numValid > 1) {
1791 if ((ugly->wx[1] != WX_R) && (ugly->wx[1] != WX_S) &&
1792 (ugly->wx[1] != WX_RW) && (ugly->wx[1] != WX_SW) &&
1793 (ugly->wx[1] != WX_T) && (ugly->wx[1] != WX_ZR) &&
1794 (ugly->wx[1] != WX_IP) && (ugly->wx[1] != WX_ZL) &&
1795 (ugly->wx[1] != WX_L) && (ugly->wx[1] != WX_F)) {
1796 numValid = 1;
1797 cover1 = COV_UNKNOWN;
1798 intens1 = INT_UNKNOWN;
1799 }
1800 }
1801
1802 switch (ugly->wx[0]) {
1803 case WX_NOWX: /* NoWx */
1804 case WX_A: /* Hail */
1805 case WX_FR: /* Frost */
1806 code = 0;
1807 break;
1808 case WX_R: /* Rain */
1809 code = 1;
1810 if (numValid > 1) {
1811 code = 100 + NDFD_Wx2Code4 (ugly->wx[1]);
1812 }
1813 break;
1814 case WX_RW: /* Rain Showers */
1815 code = 4;
1816 if (numValid > 1) {
1817 code = 200 + NDFD_Wx2Code4 (ugly->wx[1]);
1818 }
1819 break;
1820 case WX_L: /* Drizzle */
1821 code = 7;
1822 if (numValid > 1) {
1823 code = 300 + NDFD_Wx2Code4 (ugly->wx[1]);
1824 }
1825 break;
1826 case WX_ZL: /* Freezing Drizzle */
1827 code = 10;
1828 if (numValid > 1) {
1829 code = 400 + NDFD_Wx2Code4 (ugly->wx[1]);
1830 }
1831 break;
1832 case WX_ZR: /* Freezing Rain */
1833 code = 13;
1834 if (numValid > 1) {
1835 code = 500 + NDFD_Wx2Code4 (ugly->wx[1]);
1836 }
1837 break;
1838 case WX_IP: /* Sleet */
1839 code = 16;
1840 if (numValid > 1) {
1841 code = 600 + NDFD_Wx2Code4 (ugly->wx[1]);
1842 }
1843 break;
1844 case WX_SW: /* Snow Showers */
1845 code = 19;
1846 if (numValid > 1) {
1847 code = 700 + NDFD_Wx2Code4 (ugly->wx[1]);
1848 }
1849 break;
1850 case WX_S: /* Snow */
1851 code = 22;
1852 if (numValid > 1) {
1853 code = 800 + NDFD_Wx2Code4 (ugly->wx[1]);
1854 }
1855 break;
1856 case WX_T: /* Thunderstorms */
1857 code = 25;
1858 if (numValid > 1) {
1859 code = 900 + NDFD_Wx2Code4 (ugly->wx[1]);
1860 }
1861 break;
1862 case WX_F: /* Fog */
1863 code = 28;
1864 if (numValid > 1) {
1865 code = 1000 + NDFD_Wx2Code4 (ugly->wx[1]);
1866 }
1867 break;
1868 case WX_K: /* Smoke */
1869 code = 31;
1870 break;
1871 case WX_BS: /* Blowing Snow */
1872 code = 32;
1873 break;
1874 case WX_BD: /* Blowing Dust */
1875 code = 33;
1876 break;
1877 case WX_ZF: /* Freezing Fog */
1878 code = 34;
1879 break;
1880 case WX_IF: /* Ice Fog */
1881 code = 35;
1882 break;
1883 case WX_IC: /* Ice Crystals */
1884 code = 36;
1885 break;
1886 case WX_BN: /* Blowing Sand */
1887 code = 37;
1888 break;
1889 case WX_ZY: /* Freezing Spray */
1890 code = 38;
1891 break;
1892 case WX_VA: /* Volcanic Ash */
1893 code = 39;
1894 break;
1895 case WX_WP: /* Water Spouts */
1896 code = 40;
1897 break;
1898 case WX_H: /* Haze */
1899 code = 41;
1900 break;
1901 default:
1902 code = 0;
1903 } /* End of Switch statement. */
1904
1905 if ((ugly->wx[0] == WX_R) || (ugly->wx[0] == WX_S) ||
1906 (ugly->wx[0] == WX_RW) || (ugly->wx[0] == WX_SW) ||
1907 (ugly->wx[0] == WX_T) || (ugly->wx[0] == WX_ZR) ||
1908 (ugly->wx[0] == WX_IP) || (ugly->wx[0] == WX_ZL) ||
1909 (ugly->wx[0] == WX_L) || (ugly->wx[0] == WX_F)) {
1910 code += NDFD_CodeIntens4 (ugly->intens[0], intens1);
1911 }
1912
1913 if ((ugly->cover[0] == COV_WIDE) || (ugly->cover[0] == COV_LKLY) ||
1914 (ugly->cover[0] == COV_NUM) || (ugly->cover[0] == COV_OCNL) ||
1915 (ugly->cover[0] == COV_DEF) || (ugly->cover[0] == COV_AREAS) ||
1916 (ugly->cover[0] == COV_PDS) || (ugly->cover[0] == COV_FRQ) ||
1917 (ugly->cover[0] == COV_INTER) || (ugly->cover[0] == COV_BRIEF) ||
1918 (cover1 == COV_WIDE) || (cover1 == COV_LKLY) || (cover1 == COV_NUM) ||
1919 (cover1 == COV_OCNL) || (cover1 == COV_DEF) ||
1920 (cover1 == COV_AREAS) || (cover1 == COV_PDS) || (cover1 == COV_FRQ) ||
1921 (cover1 == COV_INTER) || (cover1 == COV_BRIEF)) {
1922 code += 1100;
1923 }
1924
1925 return code;
1926 }
1927
1928 /*****************************************************************************
1929 * FreeUglyString() --
1930 *
1931 * Arthur Taylor / MDL
1932 *
1933 * PURPOSE
1934 * To free the data structure used to hold the parsed ugly string.
1935 *
1936 * ARGUMENTS
1937 * ugly = The ugly string structure to free. (Output)
1938 *
1939 * FILES/DATABASES: None
1940 *
1941 * RETURNS: void
1942 *
1943 * HISTORY
1944 * 9/2003 Arthur Taylor (MDL/RSIS): Created.
1945 *
1946 * NOTES
1947 *****************************************************************************
1948 */
FreeUglyString(UglyStringType * ugly)1949 void FreeUglyString (UglyStringType * ugly)
1950 {
1951 int j; /* Used to free all the English words. */
1952
1953 for (j = 0; j < NUM_UGLY_WORD; j++) {
1954 free (ugly->english[j]);
1955 }
1956 free (ugly->errors);
1957 }
1958
1959 /*****************************************************************************
1960 * InitUglyString() --
1961 *
1962 * Arthur Taylor / MDL
1963 *
1964 * PURPOSE
1965 * To initialize the structure used to hold the parsed ugly string.
1966 *
1967 * ARGUMENTS
1968 * ugly = The ugly string structure to modify. (Output)
1969 *
1970 * FILES/DATABASES: None
1971 *
1972 * RETURNS: void
1973 *
1974 * HISTORY
1975 * 5/2003 Arthur Taylor (MDL/RSIS): Created.
1976 * 7/2003 AAT: Made it initialize whole UglyString structure instead of
1977 * just some of the word in the structure.
1978 *
1979 * NOTES
1980 *****************************************************************************
1981 */
InitUglyString(UglyStringType * ugly)1982 static void InitUglyString (UglyStringType * ugly)
1983 {
1984 int i; /* Used to traverse all the words. */
1985 int j; /* Used to traverse all the attributes. */
1986
1987 ugly->numValid = 0;
1988 ugly->minVis = 0;
1989 ugly->validIndex = 0;
1990 ugly->SimpleCode = 0;
1991 ugly->errors = NULL;
1992 for (i = 0; i < NUM_UGLY_WORD; i++) {
1993 ugly->wx[i] = 0;
1994 ugly->cover[i] = 0;
1995 ugly->intens[i] = 0;
1996 ugly->vis[i] = VIS_UNKNOWN;
1997 for (j = 0; j < NUM_UGLY_ATTRIB; j++) {
1998 ugly->attrib[i][j] = 0;
1999 }
2000 ugly->f_or[i] = 0;
2001 ugly->f_priority[i] = 0;
2002 ugly->english[i] = NULL;
2003 ugly->wx_inten[i] = 0;
2004 ugly->HazCode[i] = 0;
2005 }
2006 }
2007
2008 /*****************************************************************************
2009 * FindInTable() --
2010 *
2011 * Arthur Taylor / MDL
2012 *
2013 * PURPOSE
2014 * Look through a given table for a particular "phrase".
2015 *
2016 * ARGUMENTS
2017 * table = The table to look in. (Input)
2018 * tableLen = The length of the table (Input)
2019 * data = The string (or phrase) to look for. (Input)
2020 * ans = The index where the string was found. (Output)
2021 *
2022 * FILES/DATABASES: None
2023 *
2024 * RETURNS: int
2025 * 1 = Found it but string is "invalid" or "missing".
2026 * 0 = Found it.
2027 * -1 = Did not find it.
2028 *
2029 * HISTORY
2030 * 5/2003 Arthur Taylor (MDL/RSIS): Created.
2031 *
2032 * NOTES
2033 *****************************************************************************
2034 */
FindInTable(const WxTable * table,int tableLen,char * data,uChar * ans)2035 static int FindInTable (const WxTable * table, int tableLen, char *data, uChar *ans)
2036 {
2037 int i; /* Index used to walk through the table. */
2038
2039 for (i = 0; i < tableLen; i++) {
2040 if (strcmp (data, table[i].abrev) == 0) {
2041 *ans = i;
2042 return 0;
2043 }
2044 }
2045 if (strcmp (data, "<Invalid>") == 0) {
2046 return 1;
2047 } else {
2048 return -1;
2049 }
2050 }
2051
2052 /*****************************************************************************
2053 * UglyLookUp() --
2054 *
2055 * Arthur Taylor / MDL
2056 *
2057 * PURPOSE
2058 * Determine which table to look in based on how many ':' we have seen in
2059 * the current word. After looking up the data in the appropriate table,
2060 * Places the result in the appropriate places in the UglyStringType data
2061 * structure.
2062 *
2063 * ARGUMENTS
2064 * ugly = The ugly string structure to modify. (Output)
2065 * data = The string (or phrase) to look for. (Input)
2066 * word = Which word we are currently working on. (Input)
2067 * place = What part of the word (i.e. # of :'s) (Input)
2068 * attNum = What part of attribute piece (i.e. # of ,'s) (Input)
2069 *
2070 * FILES/DATABASES: None
2071 *
2072 * RETURNS: int
2073 * 0 = No problems
2074 * -1 = 'place' was invalid (larger than 4)
2075 * -2 = Couldn't find the phrase 'data' in the look-up tables.
2076 *
2077 * HISTORY
2078 * 5/2003 Arthur Taylor (MDL/RSIS): Created.
2079 *
2080 * NOTES
2081 *****************************************************************************
2082 */
UglyLookUp(UglyStringType * ugly,char * data,uChar word,uChar place,uChar attNum)2083 static int UglyLookUp (UglyStringType * ugly, char *data, uChar word,
2084 uChar place, uChar attNum)
2085 {
2086 int ans;
2087
2088 switch (place) {
2089 case 0: /* Cover */
2090 ans = FindInTable (WxCover, (sizeof (WxCover) / sizeof (WxTable)),
2091 data, &(ugly->cover[word]));
2092 /* Don't see why <Invalid> should be treated specially. */
2093 /*
2094 if (ans == 1) {
2095 ugly->f_valid = 0;
2096 return 0;
2097 } else
2098 */
2099 if (ans != 0) {
2100 if (strlen (data) == 0) {
2101 ugly->cover[word] = COV_NOCOV;
2102 } else {
2103 ugly->cover[word] = COV_UNKNOWN;
2104 #ifdef VERBOSE
2105 printf ("No '%s' in WxCover\n", data);
2106 #endif
2107 #ifdef STORE_ERRORS
2108 reallocSprintf (&(ugly->errors), "No '%s' in WxCover ", data);
2109 #endif
2110 /*
2111 return -2;
2112 */
2113 }
2114 }
2115 break;
2116 case 1: /* Weather */
2117 ans = FindInTable (WxCode, (sizeof (WxCode) / sizeof (WxTable)),
2118 data, &(ugly->wx[word]));
2119 /* Don't see why <Invalid> should be treated specially. */
2120 /*
2121 if (ans == 1) {
2122 ugly->f_valid = 0;
2123 return 0;
2124 } else
2125 */
2126 if (ans != 0) {
2127 if (strlen (data) == 0) {
2128 ugly->wx[word] = WX_NOWX;
2129 } else {
2130 #ifdef VERBOSE
2131 printf ("No '%s' in WxCode\n", data);
2132 #endif
2133 #ifdef STORE_ERRORS
2134 reallocSprintf (&(ugly->errors), "No '%s' in WxCode ", data);
2135 #endif
2136 return -2;
2137 }
2138 }
2139 break;
2140 case 2: /* Intensity */
2141 ans = FindInTable (WxIntens, (sizeof (WxIntens) / sizeof (WxTable)),
2142 data, &(ugly->intens[word]));
2143 /* Don't see why <Invalid> should be treated specially. */
2144 /*
2145 if (ans == 1) {
2146 ugly->f_valid = 0;
2147 return 0;
2148 } else
2149 */
2150 if (ans != 0) {
2151 if (strlen (data) == 0) {
2152 ugly->intens[word] = INT_NOINT;
2153 } else {
2154 #ifdef VERBOSE
2155 printf ("No '%s' in WxIntens\n", data);
2156 #endif
2157 #ifdef STORE_ERRORS
2158 reallocSprintf (&(ugly->errors), "No '%s' in WxIntens ", data);
2159 #endif
2160 return -2;
2161 }
2162 }
2163 break;
2164 case 3: /* Vis */
2165 ans = FindInTable (WxVisib, (sizeof (WxVisib) / sizeof (WxTable)),
2166 data, &(ugly->vis[word]));
2167 /* Don't see why <Invalid> should be treated specially. */
2168 /*
2169 if (ans == 1) {
2170 ugly->f_valid = 0;
2171 return 0;
2172 } else
2173 */
2174 if (ans != 0) {
2175 if (strlen (data) == 0) {
2176 ugly->vis[word] = 0;
2177 } else {
2178 #ifdef VERBOSE
2179 printf ("No '%s' in WxVisib\n", data);
2180 #endif
2181 #ifdef STORE_ERRORS
2182 reallocSprintf (&(ugly->errors), "No '%s' in WxVisib ", data);
2183 #endif
2184 return -2;
2185 }
2186 }
2187 ugly->vis[word] = atoi (WxVisib[ugly->vis[word]].name);
2188 if (word == 0) {
2189 ugly->minVis = ugly->vis[word];
2190 } else if (ugly->minVis > ugly->vis[word]) {
2191 ugly->minVis = ugly->vis[word];
2192 }
2193 break;
2194 case 4: /* Attrib */
2195 ans = FindInTable (WxAttrib, (sizeof (WxAttrib) / sizeof (WxTable)),
2196 data, &(ugly->attrib[word][attNum]));
2197 /* Don't see why <Invalid> should be treated specially. */
2198 /*
2199 if (ans == 1) {
2200 ugly->f_valid = 0;
2201 return 0;
2202 } else
2203 */
2204 if (ans != 0) {
2205 #ifdef VERBOSE
2206 printf ("No '%s' in WxAttrib\n", data);
2207 #endif
2208 #ifdef STORE_ERRORS
2209 reallocSprintf (&(ugly->errors), "No '%s' in WxAttrib ", data);
2210 #endif
2211 return -2;
2212 } else {
2213 /* Check if it is the "OR" or "MX" case. */
2214 if (ugly->attrib[word][attNum] == HAZ_OR) {
2215 ugly->attrib[word][attNum] = 0;
2216 ugly->f_or[word] = 1;
2217 } else if (ugly->attrib[word][attNum] == HAZ_PRI2) {
2218 ugly->attrib[word][attNum] = 0;
2219 ugly->f_priority[word] = 2;
2220 } else if (ugly->attrib[word][attNum] == HAZ_PRI1) {
2221 ugly->attrib[word][attNum] = 0;
2222 ugly->f_priority[word] = 1;
2223 }
2224 }
2225 break;
2226 default:
2227 return -1;
2228 }
2229 return 0;
2230 }
2231
2232 /*****************************************************************************
2233 * Ugly2English() --
2234 *
2235 * Arthur Taylor / MDL
2236 *
2237 * PURPOSE
2238 * Converts an Ugly string to an English Phrase.
2239 * Example: "Iso:T:<NoInten>:<NoVis>:" -> "Isolated Thunderstorms"
2240 * English phrase does not include visibility.
2241 *
2242 * ARGUMENTS
2243 * ugly = The ugly string structure to modify. (Input/Output)
2244 *
2245 * FILES/DATABASES: None
2246 *
2247 * RETURNS: void
2248 *
2249 * HISTORY
2250 * 5/2003 Arthur Taylor (MDL/RSIS): Created.
2251 *
2252 * NOTES
2253 * 1) buffer size is chosen so each of the 8 parts has 50 bytes for the
2254 * table entry and the ' ' and ', ' and ' with '. If NUM_UGLY_ATTRIB
2255 * increases (from 5), we may need more.
2256 * 2) Instead of static buffer, we could use myerror.c :: AllocSprintf.
2257 *****************************************************************************
2258 */
2259
safe_strcat(char * target,size_t target_size,const char * string_to_append)2260 static void safe_strcat(char* target, size_t target_size,
2261 const char* string_to_append)
2262 {
2263 size_t target_length = strlen(target);
2264 if( target_length + strlen(string_to_append) < target_size )
2265 strcat(target + target_length, string_to_append);
2266 }
2267
Ugly2English(UglyStringType * ugly)2268 static void Ugly2English (UglyStringType * ugly)
2269 {
2270 int i; /* Loop counter over number of words. */
2271 int j; /* Loop counter over number of attributes. */
2272 char buffer[400]; /* Temporary storage as we build up the phrase. */
2273 uChar f_first; /* Flag for first attribute. */
2274 int HazCode[NUM_UGLY_ATTRIB]; /* Sorted list of hazard numbers used to *
2275 * create hazard code. */
2276 int k; /* A counter used to help sort hazard. */
2277 int temp; /* A temp variable used to help sort hazard. */
2278
2279 for (i = 0; i < ugly->numValid; i++) {
2280 buffer[0] = '\0';
2281 /* Handle Coverage. */
2282 if (ugly->cover[i] != 0) {
2283 safe_strcat (buffer, sizeof(buffer), WxCover[ugly->cover[i]].name);
2284 safe_strcat (buffer, sizeof(buffer), " ");
2285 }
2286 /* Handle Intensity. */
2287 if (ugly->intens[i] != 0) {
2288 safe_strcat (buffer, sizeof(buffer), WxIntens[ugly->intens[i]].name);
2289 safe_strcat (buffer, sizeof(buffer), " ");
2290 }
2291 safe_strcat (buffer, sizeof(buffer), WxCode[ugly->wx[i]].name);
2292 /* Handle Attributes. */
2293 f_first = 1;
2294 for (j = 0; j < NUM_UGLY_ATTRIB; j++) {
2295 if (ugly->attrib[i][j] != 0) {
2296 /* Fixed by GDAL */
2297 if (ugly->f_priority[i] == 0) {
2298 if (f_first) {
2299 safe_strcat (buffer, sizeof(buffer), " with ");
2300 f_first = 0;
2301 } else {
2302 safe_strcat (buffer, sizeof(buffer), ", ");
2303 }
2304 safe_strcat (buffer, sizeof(buffer), WxAttrib[ugly->attrib[i][j]].name);
2305 }
2306 }
2307 }
2308 ugly->english[i] = (char *) malloc ((strlen (buffer) + 1) *
2309 sizeof (char));
2310 strcpy (ugly->english[i], buffer);
2311 /* Compute a code number for wx&inten, as well as attrib. */
2312 if (WxCode[ugly->wx[i]].number != 0) {
2313 ugly->wx_inten[i] = 1 + (WxCode[ugly->wx[i]].number - 1) *
2314 (sizeof (WxIntens) / sizeof (WxTable)) +
2315 WxIntens[ugly->intens[i]].number;
2316 } else {
2317 ugly->wx_inten[i] = 0;
2318 }
2319 /* Compute a code number for hazards. */
2320 for (j = 0; j < NUM_UGLY_ATTRIB; j++) {
2321 HazCode[j] = WxAttrib[ugly->attrib[i][j]].number;
2322 if (HazCode[j] > 250) {
2323 HazCode[j] = 0;
2324 }
2325 }
2326 for (j = 0; j < NUM_UGLY_ATTRIB - 1; j++) {
2327 for (k = j + 1; k < NUM_UGLY_ATTRIB; k++) {
2328 if (HazCode[j] > HazCode[k]) {
2329 temp = HazCode[j];
2330 HazCode[j] = HazCode[k];
2331 HazCode[k] = temp;
2332 }
2333 }
2334 }
2335 /* Hazard is now smallest number first... we now convert from "00 00 00
2336 * 04 05" to 405 */
2337 ugly->HazCode[i] = 0;
2338 for (j = 0; j < NUM_UGLY_ATTRIB; j++) {
2339 ugly->HazCode[i] = (ugly->HazCode[i] * 100) + HazCode[j];
2340 }
2341 }
2342 }
2343
2344 /*****************************************************************************
2345 * ParseUglyString() --
2346 *
2347 * Arthur Taylor / MDL
2348 *
2349 * PURPOSE
2350 * Parse an ASCII ugly string describing weather into a data structure
2351 * which is more easily manipulated.
2352 *
2353 * ARGUMENTS
2354 * ugly = The ugly string structure to modify. (Output)
2355 * wxData = The ugly string to parse. (Input)
2356 * simpleVer = The version of the simple Wx table to use.
2357 * (1 is 6/2003 version), (2 is 1/2004 version). (Input)
2358 *
2359 * FILES/DATABASES: None
2360 *
2361 * RETURNS: int
2362 * 0 = No problems
2363 * -1 = Had difficulties parsing the ugly string.
2364 *
2365 * HISTORY
2366 * 5/2003 Arthur Taylor (MDL/RSIS): Created.
2367 *
2368 * NOTES
2369 * 1) Assumes it is ok to modify the wxData ascii string. This means that
2370 * You can NOT pass in constant strings.
2371 *****************************************************************************
2372 */
ParseUglyString(UglyStringType * ugly,char * wxData,int simpleVer)2373 int ParseUglyString (UglyStringType * ugly, char *wxData, int simpleVer)
2374 {
2375 char *cur; /* Used to help walk though the ascii string. */
2376 char *start; /* Where current phrase starts. */
2377 uChar attNum = 0; /* piece of attribute phrase (# of , seen) */
2378 uChar place = 0; /* location in a word (# of : seen) */
2379 uChar word = 0; /* Which word in sentence (# of ^ seen) */
2380
2381 /* Init first message */
2382 ugly->SimpleCode = 0;
2383 InitUglyString (ugly);
2384 start = wxData;
2385 for (cur = wxData; *cur != '\0'; cur++) {
2386 switch (*cur) {
2387 case '^':
2388 *cur = '\0';
2389 if (UglyLookUp (ugly, start, word, place, attNum) != 0) {
2390 *cur = '^';
2391 #ifdef VERBOSE
2392 printf ("(A) %s\n", wxData);
2393 #endif
2394 #ifdef STORE_ERRORS
2395 reallocSprintf (&(ugly->errors), "(A) '%s'\n", wxData);
2396 #endif
2397 /* Convert what we have to "English phrase" */
2398 ugly->numValid = word + 1;
2399 Ugly2English (ugly);
2400 if (simpleVer == 1) {
2401 ugly->SimpleCode = NDFD_WxTable1 (ugly);
2402 } else if (simpleVer == 2) {
2403 ugly->SimpleCode = NDFD_WxTable2 (ugly);
2404 } else if (simpleVer == 3) {
2405 ugly->SimpleCode = NDFD_WxTable3 (ugly);
2406 } else {
2407 ugly->SimpleCode = NDFD_WxTable4 (ugly);
2408 }
2409 return -1;
2410 }
2411 *cur = '^';
2412 word++;
2413 /* Make sure we don't start writing out of bounds. */
2414 if (word >= NUM_UGLY_WORD) {
2415 #ifdef VERBOSE
2416 printf ("(B) %s\n", wxData);
2417 #endif
2418 #ifdef STORE_ERRORS
2419 reallocSprintf (&(ugly->errors), "(B) '%s'\n", wxData);
2420 #endif
2421 /* Convert what we have to "English phrase" */
2422 /*
2423 ugly->numValid = word + 1;
2424 */
2425 Ugly2English (ugly);
2426 if (simpleVer == 1) {
2427 ugly->SimpleCode = NDFD_WxTable1 (ugly);
2428 } else if (simpleVer == 2) {
2429 ugly->SimpleCode = NDFD_WxTable2 (ugly);
2430 } else if (simpleVer == 3) {
2431 ugly->SimpleCode = NDFD_WxTable3 (ugly);
2432 } else {
2433 ugly->SimpleCode = NDFD_WxTable4 (ugly);
2434 }
2435 return -1;
2436 }
2437 place = 0;
2438 attNum = 0;
2439 start = cur + 1;
2440 break;
2441 case ':':
2442 *cur = '\0';
2443 if (UglyLookUp (ugly, start, word, place, attNum) != 0) {
2444 *cur = ':';
2445 #ifdef VERBOSE
2446 printf ("(C) %s\n", wxData);
2447 #endif
2448 #ifdef STORE_ERRORS
2449 reallocSprintf (&(ugly->errors), "(C) '%s'\n", wxData);
2450 #endif
2451 /* Convert what we have to "English phrase" */
2452 ugly->numValid = word + 1;
2453 Ugly2English (ugly);
2454 if (simpleVer == 1) {
2455 ugly->SimpleCode = NDFD_WxTable1 (ugly);
2456 } else if (simpleVer == 2) {
2457 ugly->SimpleCode = NDFD_WxTable2 (ugly);
2458 } else if (simpleVer == 3) {
2459 ugly->SimpleCode = NDFD_WxTable3 (ugly);
2460 } else {
2461 ugly->SimpleCode = NDFD_WxTable4 (ugly);
2462 }
2463 return -1;
2464 }
2465 *cur = ':';
2466 place++;
2467 attNum = 0;
2468 start = cur + 1;
2469 break;
2470 case ',':
2471 if (place == 4) {
2472 *cur = '\0';
2473 if (UglyLookUp (ugly, start, word, place, attNum) != 0) {
2474 *cur = ',';
2475 #ifdef VERBOSE
2476 printf ("(D) %s\n", wxData);
2477 #endif
2478 #ifdef STORE_ERRORS
2479 reallocSprintf (&(ugly->errors), "(D) '%s'\n", wxData);
2480 #endif
2481 /* Convert what we have to "English phrase" */
2482 ugly->numValid = word + 1;
2483 Ugly2English (ugly);
2484 if (simpleVer == 1) {
2485 ugly->SimpleCode = NDFD_WxTable1 (ugly);
2486 } else if (simpleVer == 2) {
2487 ugly->SimpleCode = NDFD_WxTable2 (ugly);
2488 } else if (simpleVer == 3) {
2489 ugly->SimpleCode = NDFD_WxTable3 (ugly);
2490 } else {
2491 ugly->SimpleCode = NDFD_WxTable4 (ugly);
2492 }
2493 return -1;
2494 }
2495 *cur = ',';
2496 attNum++;
2497 start = cur + 1;
2498 }
2499 break;
2500 default:
2501 break;
2502 }
2503 /*
2504 if (word == 2) {
2505 return;
2506 }
2507 */
2508 }
2509 if (start != NULL) {
2510 if (UglyLookUp (ugly, start, word, place, attNum) != 0) {
2511 #ifdef VERBOSE
2512 printf ("(E) '%s'\n", wxData);
2513 #endif
2514 #ifdef STORE_ERRORS
2515 reallocSprintf (&(ugly->errors), "(E) '%s'\n", wxData);
2516 #endif
2517 /* Convert what we have to "English phrase" */
2518 ugly->numValid = word + 1;
2519 Ugly2English (ugly);
2520 if (simpleVer == 1) {
2521 ugly->SimpleCode = NDFD_WxTable1 (ugly);
2522 } else if (simpleVer == 2) {
2523 ugly->SimpleCode = NDFD_WxTable2 (ugly);
2524 } else if (simpleVer == 3) {
2525 ugly->SimpleCode = NDFD_WxTable3 (ugly);
2526 } else {
2527 ugly->SimpleCode = NDFD_WxTable4 (ugly);
2528 }
2529 return -1;
2530 }
2531 }
2532
2533 ugly->numValid = word + 1;
2534 /* Convert what we have to "English phrase" */
2535 Ugly2English (ugly);
2536 if (simpleVer == 1) {
2537 ugly->SimpleCode = NDFD_WxTable1 (ugly);
2538 } else if (simpleVer == 2) {
2539 ugly->SimpleCode = NDFD_WxTable2 (ugly);
2540 } else if (simpleVer == 3) {
2541 ugly->SimpleCode = NDFD_WxTable3 (ugly);
2542 } else {
2543 ugly->SimpleCode = NDFD_WxTable4 (ugly);
2544 }
2545 #ifdef VERBOSE
2546 if (place != 4) {
2547 printf ("Too few ugly words? '%s'\n", wxData);
2548 }
2549 #endif
2550 #ifdef STORE_ERRORS
2551 /*
2552 if (place != 4) {
2553 reallocSprintf (&(ugly->errors), "Too few ugly words? '%s'\n", wxData);
2554 }
2555 */
2556 #endif
2557 return 0;
2558 }
2559
2560 /*****************************************************************************
2561 * PrintUglyString() --
2562 *
2563 * Arthur Taylor / MDL
2564 *
2565 * PURPOSE
2566 * Prints all the relevant data in an ugly string. Mainly for debugging
2567 * purposes.
2568 *
2569 * ARGUMENTS
2570 * ugly = The ugly string structure to print. (Input)
2571 *
2572 * FILES/DATABASES: None
2573 *
2574 * RETURNS: void
2575 *
2576 * HISTORY
2577 * 5/2003 Arthur Taylor (MDL/RSIS): Created.
2578 *
2579 * NOTES
2580 *****************************************************************************
2581 */
PrintUglyString(UglyStringType * ugly)2582 void PrintUglyString (UglyStringType * ugly)
2583 {
2584 int i; /* Used to traverse the ugly string structure. */
2585 double vis; /* Used to determine if we have "missing" vis. */
2586
2587 printf ("numValid %d\n", ugly->numValid);
2588 for (i = 0; i < ugly->numValid; i++) {
2589 if (ugly->vis[i] == VIS_UNKNOWN) {
2590 vis = 9999;
2591 } else {
2592 vis = ugly->vis[i] / 32.;
2593 }
2594 printf ("Wx=%d, Cov=%d, inten=%d, vis=%d, attrib=%d,%d,%d,%d,%d\n",
2595 ugly->wx[i], ugly->cover[i], ugly->intens[i],
2596 ugly->vis[i], ugly->attrib[i][0], ugly->attrib[i][1],
2597 ugly->attrib[i][2], ugly->attrib[i][3], ugly->attrib[i][4]);
2598 printf ("Wx=%s, Cov=%s, intens=%s, vis=%f, attrib=%s,%s,%s,%s,%s\n",
2599 WxCode[ugly->wx[i]].name, WxCover[ugly->cover[i]].name,
2600 WxIntens[ugly->intens[i]].name, vis,
2601 WxAttrib[ugly->attrib[i][0]].name,
2602 WxAttrib[ugly->attrib[i][1]].name,
2603 WxAttrib[ugly->attrib[i][2]].name,
2604 WxAttrib[ugly->attrib[i][3]].name,
2605 WxAttrib[ugly->attrib[i][4]].name);
2606 }
2607 printf ("\n");
2608 }
2609
2610 #ifdef DEBUG_WEATHER
2611 /*****************************************************************************
2612 * main() --
2613 *
2614 * Arthur Taylor / MDL
2615 *
2616 * PURPOSE
2617 * To test the ParseUglyString() procedure.
2618 *
2619 * ARGUMENTS
2620 * argc = The number of arguments on the command line. (Input)
2621 * argv = The arguments on the command line. (Input)
2622 *
2623 * FILES/DATABASES: None
2624 *
2625 * RETURNS: int
2626 *
2627 * HISTORY
2628 * 5/2003 Arthur Taylor (MDL/RSIS): Created.
2629 *
2630 * NOTES
2631 *****************************************************************************
2632 */
main(int argc,char ** argv)2633 int main (int argc, char **argv)
2634 {
2635 UglyStringType ugly;
2636 char buffer[100];
2637
2638 strcpy (buffer, "Pds:R:+:<NoVis>:Mention^Ocnl:R:m:<NoVis>:^Sct:"
2639 "T:<NoInten>:<NoVis>:");
2640 ParseUglyString (&ugly, buffer, 3);
2641 PrintUglyString (&ugly);
2642 if (ugly.errors != NULL) {
2643 printf ("Errors: %s\n", ugly.errors);
2644 }
2645 FreeUglyString (&ugly);
2646 return 0;
2647
2648 strcpy (buffer, "Sct:SW:-:<NoVis>:");
2649 ParseUglyString (&ugly, buffer, 3);
2650 PrintUglyString (&ugly);
2651 strcpy (buffer, "Ocnl:R:-:<NoVis>:^Ocnl:S:-:<NoVis>:^SChc:ZR:-:<NoVis>:");
2652 ParseUglyString (&ugly, buffer, 3);
2653 PrintUglyString (&ugly);
2654 strcpy (buffer, "Wide:FR:-:<NoVis>:OLA");
2655 ParseUglyString (&ugly, buffer, 3);
2656 PrintUglyString (&ugly);
2657 strcpy (buffer, "<NoCov>:<NoWx>:<NoInten>:<NoVis>:");
2658 ParseUglyString (&ugly, buffer, 3);
2659 PrintUglyString (&ugly);
2660 strcpy (buffer, "Sct:RW:-:<NoVis>:^Iso:T:m:<NoVis>:");
2661 ParseUglyString (&ugly, buffer, 3);
2662 PrintUglyString (&ugly);
2663 strcpy (buffer, "Sct:T:+:<NoVis>:DmgW,LgA");
2664 ParseUglyString (&ugly, buffer, 3);
2665 PrintUglyString (&ugly);
2666 return 0;
2667 }
2668 #endif
2669