LCOV - code coverage report
Current view: top level - frmts/grib/degrib/degrib - weather.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 0 1203 0.0 %
Date: 2024-04-27 17:22:41 Functions: 0 15 0.0 %

          Line data    Source code
       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             :  */
     291           0 : static int NDFD_WxTable1 (UglyStringType * ugly)
     292             : {
     293           0 :    switch (ugly->wx[0]) {
     294           0 :       case WX_NOWX:
     295           0 :          return 0;
     296           0 :       case WX_R:
     297           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     298           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     299           0 :              (ugly->cover[0] == COV_CHC)) {
     300           0 :             switch (ugly->wx[1]) {
     301           0 :                case WX_S:
     302             :                case WX_SW:
     303           0 :                   return 18; /* Rain/Snow Showers */
     304           0 :                case WX_ZR:
     305           0 :                   return 34; /* Rain/Freezing Rain */
     306           0 :                case WX_IP:
     307           0 :                   return 20; /* Rain/Sleet */
     308           0 :                case WX_ZL:
     309           0 :                   return 30; /* Rain/Freezing Drizzle */
     310           0 :                case WX_T:
     311           0 :                   return 5; /* Rain/Thunderstorms */
     312           0 :                default:
     313           0 :                   switch (ugly->intens[0]) {
     314           0 :                      case INT_D:
     315             :                      case INT_DD:
     316           0 :                         return 2; /* Light Rain */
     317           0 :                      case INT_P:
     318           0 :                         return 4; /* Heavy Rain */
     319           0 :                      default:
     320           0 :                         return 3; /* Normal Rain */
     321             :                   }
     322             :             }
     323             :          } else {
     324           0 :             switch (ugly->wx[1]) {
     325           0 :                case WX_S:
     326             :                case WX_SW:
     327           0 :                   return 22; /* Rain/Snow Showers */
     328           0 :                case WX_ZR:
     329           0 :                   return 44; /* Rain/Freezing Rain */
     330           0 :                case WX_IP:
     331           0 :                   return 24; /* Rain/Sleet */
     332           0 :                case WX_ZL:
     333           0 :                   return 40; /* Rain/Freezing Drizzle */
     334           0 :                case WX_T:
     335           0 :                   return 13; /* Rain/Thunderstorms */
     336           0 :                default:
     337           0 :                   switch (ugly->intens[0]) {
     338           0 :                      case INT_D:
     339             :                      case INT_DD:
     340           0 :                         return 10; /* Light Rain */
     341           0 :                      case INT_P:
     342           0 :                         return 12; /* Heavy Rain */
     343           0 :                      default:
     344           0 :                         return 11; /* Normal Rain */
     345             :                   }
     346             :             }
     347             :          }
     348           0 :       case WX_RW:
     349           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     350           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     351           0 :              (ugly->cover[0] == COV_CHC)) {
     352           0 :             switch (ugly->wx[1]) {
     353           0 :                case WX_T:
     354           0 :                   return 7; /* Rain Showers/Thunderstorms */
     355           0 :                case WX_SW:
     356           0 :                   return 19; /* Rain Showers/Snow Showers */
     357           0 :                default:
     358           0 :                   return 6; /* Rain Showers */
     359             :             }
     360             :          } else {
     361           0 :             switch (ugly->wx[1]) {
     362           0 :                case WX_T:
     363           0 :                   return 15; /* Rain Showers/Thunderstorms */
     364           0 :                case WX_SW:
     365           0 :                   return 23; /* Rain Showers/Snow Showers */
     366           0 :                default:
     367           0 :                   return 14; /* Rain Showers */
     368             :             }
     369             :          }
     370           0 :       case WX_L:
     371           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     372           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     373           0 :              (ugly->cover[0] == COV_CHC)) {
     374           0 :             switch (ugly->wx[1]) {
     375           0 :                case WX_ZL:
     376           0 :                   return 29; /* Drizzle/Freezing Drizzle */
     377           0 :                case WX_F:
     378             :                default:
     379           0 :                   return 1; /* Drizzle */
     380             :             }
     381             :          } else {
     382           0 :             switch (ugly->wx[1]) {
     383           0 :                case WX_ZL:
     384           0 :                   return 40; /* Drizzle/Freezing Drizzle */
     385           0 :                case WX_F:
     386             :                default:
     387           0 :                   return 9; /* Drizzle */
     388             :             }
     389             :          }
     390           0 :       case WX_ZL:
     391           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     392           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     393           0 :              (ugly->cover[0] == COV_CHC)) {
     394           0 :             switch (ugly->wx[1]) {
     395           0 :                case WX_R:
     396           0 :                   return 30; /* Freezing Drizzle/Rain */
     397           0 :                case WX_L:
     398             :                default:
     399           0 :                   return 29; /* Freezing Drizzle */
     400             :             }
     401             :          } else {
     402           0 :             switch (ugly->wx[1]) {
     403           0 :                case WX_R:
     404           0 :                   return 40; /* Freezing Drizzle/Rain */
     405           0 :                case WX_L:
     406             :                default:
     407           0 :                   return 39; /* Freezing Drizzle */
     408             :             }
     409             :          }
     410           0 :       case WX_ZR:
     411           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     412           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     413           0 :              (ugly->cover[0] == COV_CHC)) {
     414           0 :             switch (ugly->wx[1]) {
     415           0 :                case WX_R:
     416           0 :                   return 34; /* Freezing Rain/Rain */
     417           0 :                case WX_IP:
     418           0 :                   return 35; /* Freezing Rain/Sleet */
     419           0 :                default:
     420           0 :                   switch (ugly->intens[0]) {
     421           0 :                      case INT_D:
     422             :                      case INT_DD:
     423           0 :                         return 31; /* Light Freezing Rain */
     424           0 :                      case INT_P:
     425           0 :                         return 33; /* Heavy Freezing Rain */
     426           0 :                      default:
     427           0 :                         return 32; /* Normal Freezing Rain */
     428             :                   }
     429             :             }
     430             :          } else {
     431           0 :             switch (ugly->wx[1]) {
     432           0 :                case WX_R:
     433           0 :                   return 44; /* Freezing Rain/Rain */
     434           0 :                case WX_IP:
     435           0 :                   return 45; /* Freezing Rain/Sleet */
     436           0 :                default:
     437           0 :                   switch (ugly->intens[0]) {
     438           0 :                      case INT_D:
     439             :                      case INT_DD:
     440           0 :                         return 41; /* Light Freezing Rain */
     441           0 :                      case INT_P:
     442           0 :                         return 43; /* Heavy Freezing Rain */
     443           0 :                      default:
     444           0 :                         return 42; /* Normal Freezing Rain */
     445             :                   }
     446             :             }
     447             :          }
     448           0 :       case WX_IP:
     449           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     450           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     451           0 :              (ugly->cover[0] == COV_CHC)) {
     452           0 :             switch (ugly->wx[1]) {
     453           0 :                case WX_R:
     454           0 :                   return 20; /* Sleet/Rain */
     455           0 :                case WX_S:
     456           0 :                   return 21; /* Sleet/Snow */
     457           0 :                case WX_ZR:
     458           0 :                   return 35; /* Sleet/Freezing Rain */
     459           0 :                default:
     460           0 :                   switch (ugly->intens[0]) {
     461           0 :                      case INT_D:
     462             :                      case INT_DD:
     463           0 :                         return 26; /* Light Sleet */
     464           0 :                      case INT_P:
     465           0 :                         return 28; /* Heavy Sleet */
     466           0 :                      default:
     467           0 :                         return 27; /* Normal Sleet */
     468             :                   }
     469             :             }
     470             :          } else {
     471           0 :             switch (ugly->wx[1]) {
     472           0 :                case WX_R:
     473           0 :                   return 24; /* Sleet/Rain */
     474           0 :                case WX_S:
     475           0 :                   return 25; /* Sleet/Snow */
     476           0 :                case WX_ZR:
     477           0 :                   return 45; /* Sleet/Freezing Rain */
     478           0 :                default:
     479           0 :                   switch (ugly->intens[0]) {
     480           0 :                      case INT_D:
     481             :                      case INT_DD:
     482           0 :                         return 36; /* Light Sleet */
     483           0 :                      case INT_P:
     484           0 :                         return 38; /* Heavy Sleet */
     485           0 :                      default:
     486           0 :                         return 37; /* Normal Sleet */
     487             :                   }
     488             :             }
     489             :          }
     490           0 :       case WX_SW:
     491           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     492           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     493           0 :              (ugly->cover[0] == COV_CHC)) {
     494           0 :             switch (ugly->wx[1]) {
     495           0 :                case WX_R:
     496           0 :                   return 18; /* Snow Showers/Rain */
     497           0 :                case WX_RW:
     498           0 :                   return 19; /* Snow Showers/Rain Showers */
     499           0 :                default:
     500           0 :                   return 46; /* Snow Showers */
     501             :             }
     502             :          } else {
     503           0 :             switch (ugly->wx[1]) {
     504           0 :                case WX_R:
     505           0 :                   return 22; /* Snow Showers/Rain */
     506           0 :                case WX_RW:
     507           0 :                   return 23; /* Snow Showers/Rain Showers */
     508           0 :                default:
     509           0 :                   return 50; /* Snow Showers */
     510             :             }
     511             :          }
     512           0 :       case WX_S:
     513           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     514           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     515           0 :              (ugly->cover[0] == COV_CHC)) {
     516           0 :             switch (ugly->wx[1]) {
     517           0 :                case WX_R:
     518             :                case WX_RW:
     519           0 :                   return 18; /* Snow/Rain */
     520           0 :                case WX_IP:
     521           0 :                   return 21; /* Snow/Sleet */
     522           0 :                default:
     523           0 :                   switch (ugly->intens[0]) {
     524           0 :                      case INT_D:
     525             :                      case INT_DD:
     526           0 :                         return 47; /* Light Snow */
     527           0 :                      case INT_P:
     528           0 :                         return 49; /* Heavy Snow */
     529           0 :                      default:
     530           0 :                         return 48; /* Normal Snow */
     531             :                   }
     532             :             }
     533             :          } else {
     534           0 :             switch (ugly->wx[1]) {
     535           0 :                case WX_R:
     536             :                case WX_RW:
     537           0 :                   return 22; /* Snow/Rain */
     538           0 :                case WX_IP:
     539           0 :                   return 25; /* Snow/Sleet */
     540           0 :                default:
     541           0 :                   switch (ugly->intens[0]) {
     542           0 :                      case INT_D:
     543             :                      case INT_DD:
     544           0 :                         return 51; /* Light Snow */
     545           0 :                      case INT_P:
     546           0 :                         return 53; /* Heavy Snow */
     547           0 :                      default:
     548           0 :                         return 52; /* Normal Snow */
     549             :                   }
     550             :             }
     551             :          }
     552           0 :       case WX_T:
     553             :          /*
     554             :           * Check Severe storms.  If so, this is most important weather
     555             :           * type.
     556             :           */
     557           0 :          if (ugly->intens[0] == INT_P) {
     558           0 :             return 17;  /* Severe Thunderstorms */
     559             :          }
     560           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     561           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     562           0 :              (ugly->cover[0] == COV_CHC)) {
     563           0 :             switch (ugly->wx[1]) {
     564           0 :                case WX_R:
     565           0 :                   return 5; /* Thunderstorms/Rain */
     566           0 :                case WX_RW:
     567           0 :                   return 7; /* Thunderstorms/Rain Showers */
     568           0 :                default:
     569           0 :                   return 8; /* Thunderstorms. */
     570             :             }
     571             :          } else {
     572           0 :             switch (ugly->wx[1]) {
     573           0 :                case WX_R:
     574           0 :                   return 13; /* Thunderstorms/Rain */
     575           0 :                case WX_RW:
     576           0 :                   return 15; /* Thunderstorms/Rain Showers */
     577           0 :                default:
     578           0 :                   return 16; /* Thunderstorms. */
     579             :             }
     580             :          }
     581           0 :       case WX_F:
     582           0 :          return 54;     /* Fog */
     583           0 :       case WX_H:
     584           0 :          return 55;     /* Haze */
     585           0 :       case WX_K:
     586           0 :          return 56;     /* Smoke */
     587           0 :       case WX_BS:
     588           0 :          return 57;     /* Blowing Snow */
     589           0 :       case WX_BD:
     590           0 :          return 58;     /* Blowing Dust */
     591           0 :       case WX_FR:      /* Ignore Frost */
     592             :       case WX_A:       /* Ignore Hail */
     593             :       default:
     594           0 :          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             :  */
     623           0 : static int NDFD_WxTable2_StdInten (int base, int intens)
     624             : {
     625           0 :    switch (intens) {
     626           0 :       case INT_D:
     627             :       case INT_DD:
     628           0 :          return base - 1;
     629           0 :       case INT_P:
     630           0 :          return base + 1;
     631           0 :       default:
     632           0 :          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             :  */
     794           0 : static int NDFD_WxTable2 (UglyStringType * ugly)
     795             : {
     796           0 :    switch (ugly->wx[0]) {
     797           0 :       case WX_NOWX:
     798           0 :          return 0;
     799           0 :       case WX_R:
     800           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     801           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     802           0 :              (ugly->cover[0] == COV_CHC)) {
     803           0 :             switch (ugly->wx[1]) {
     804           0 :                case WX_S:
     805           0 :                   return (NDFD_WxTable2_StdInten (40, ugly->intens[0]));
     806           0 :                case WX_ZR: /* Rain/Freezing Rain */
     807           0 :                   return (NDFD_WxTable2_StdInten (76, ugly->intens[0]));
     808           0 :                case WX_IP: /* Rain/Sleet */
     809           0 :                   return (NDFD_WxTable2_StdInten (46, ugly->intens[0]));
     810           0 :                case WX_ZL: /* Rain/Freezing Drizzle */
     811           0 :                   return (NDFD_WxTable2_StdInten (70, ugly->intens[0]));
     812           0 :                case WX_SW: /* Rain/Snow Showers */
     813           0 :                   return (NDFD_WxTable2_StdInten (40, ugly->intens[0]));
     814           0 :                case WX_T: /* Rain/Thunderstorms */
     815           0 :                   switch (ugly->intens[0]) {
     816           0 :                      case INT_D:
     817             :                      case INT_DD:
     818           0 :                         return 9;
     819           0 :                      case INT_P:
     820           0 :                         return 8;
     821           0 :                      default:
     822           0 :                         return 27;
     823             :                   }
     824           0 :                default:
     825           0 :                   return (NDFD_WxTable2_StdInten (5, ugly->intens[0]));
     826             :             }
     827             :          } else {
     828           0 :             switch (ugly->wx[1]) {
     829           0 :                case WX_S: /* Rain/Snow */
     830           0 :                   return (NDFD_WxTable2_StdInten (52, ugly->intens[0]));
     831           0 :                case WX_ZR: /* Rain/Freezing Rain */
     832           0 :                   return (NDFD_WxTable2_StdInten (94, ugly->intens[0]));
     833           0 :                case WX_IP: /* Rain/Sleet */
     834           0 :                   return (NDFD_WxTable2_StdInten (58, ugly->intens[0]));
     835           0 :                case WX_ZL: /* Rain/Freezing Drizzle */
     836           0 :                   return (NDFD_WxTable2_StdInten (88, ugly->intens[0]));
     837           0 :                case WX_SW: /* Rain/Snow Showers */
     838           0 :                   return (NDFD_WxTable2_StdInten (52, ugly->intens[0]));
     839           0 :                case WX_T: /* Rain/Thunderstorms */
     840           0 :                   switch (ugly->intens[0]) {
     841           0 :                      case INT_D:
     842             :                      case INT_DD:
     843           0 :                         return 29;
     844           0 :                      case INT_P:
     845           0 :                         return 28;
     846           0 :                      default:
     847           0 :                         return 27;
     848             :                   }
     849           0 :                default:
     850           0 :                   return (NDFD_WxTable2_StdInten (24, ugly->intens[0]));
     851             :             }
     852             :          }
     853           0 :       case WX_RW:
     854           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     855           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     856           0 :              (ugly->cover[0] == COV_CHC)) {
     857           0 :             switch (ugly->wx[1]) {
     858           0 :                case WX_T: /* Rain Showers/Thunderstorms */
     859           0 :                   switch (ugly->intens[0]) {
     860           0 :                      case INT_D:
     861             :                      case INT_DD:
     862           0 :                         return 17;
     863           0 :                      case INT_P:
     864           0 :                         return 16;
     865           0 :                      default:
     866           0 :                         return 15;
     867             :                   }
     868           0 :                case WX_SW: /* Rain Showers/Snow Showers */
     869             :                case WX_S: /* Rain Showers/Snow */
     870           0 :                   return (NDFD_WxTable2_StdInten (43, ugly->intens[0]));
     871           0 :                default:
     872           0 :                   return (NDFD_WxTable2_StdInten (12, ugly->intens[0]));
     873             :             }
     874             :          } else {
     875           0 :             switch (ugly->wx[1]) {
     876           0 :                case WX_T: /* Rain Showers/Thunderstorms */
     877           0 :                   switch (ugly->intens[0]) {
     878           0 :                      case INT_D:
     879             :                      case INT_DD:
     880           0 :                         return 36;
     881           0 :                      case INT_P:
     882           0 :                         return 35;
     883           0 :                      default:
     884           0 :                         return 33;
     885             :                   }
     886           0 :                case WX_SW: /* Rain Showers/Snow Showers */
     887             :                case WX_S: /* Rain Showers/Snow */
     888           0 :                   return (NDFD_WxTable2_StdInten (55, ugly->intens[0]));
     889           0 :                default:
     890           0 :                   return (NDFD_WxTable2_StdInten (31, ugly->intens[0]));
     891             :             }
     892             :          }
     893           0 :       case WX_L:
     894           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     895           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     896           0 :              (ugly->cover[0] == COV_CHC)) {
     897           0 :             switch (ugly->wx[1]) {
     898           0 :                case WX_ZL: /* Drizzle/Freezing Drizzle */
     899           0 :                   return (NDFD_WxTable2_StdInten (100, ugly->intens[0]));
     900           0 :                case WX_F:
     901             :                default: /* Drizzle */
     902           0 :                   return (NDFD_WxTable2_StdInten (2, ugly->intens[0]));
     903             :             }
     904             :          } else {
     905           0 :             switch (ugly->wx[1]) {
     906           0 :                case WX_ZL: /* Drizzle/Freezing Drizzle */
     907           0 :                   return (NDFD_WxTable2_StdInten (103, ugly->intens[0]));
     908           0 :                case WX_F:
     909             :                default: /* Drizzle */
     910           0 :                   return (NDFD_WxTable2_StdInten (21, ugly->intens[0]));
     911             :             }
     912             :          }
     913           0 :       case WX_ZL:
     914           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     915           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     916           0 :              (ugly->cover[0] == COV_CHC)) {
     917           0 :             switch (ugly->wx[1]) {
     918           0 :                case WX_R: /* Freezing Drizzle/Rain */
     919           0 :                   return (NDFD_WxTable2_StdInten (70, ugly->intens[0]));
     920           0 :                case WX_L: /* Freezing Drizzle/Drizzle */
     921           0 :                   return (NDFD_WxTable2_StdInten (100, ugly->intens[0]));
     922           0 :                default:
     923           0 :                   return (NDFD_WxTable2_StdInten (67, ugly->intens[0]));
     924             :             }
     925             :          } else {
     926           0 :             switch (ugly->wx[1]) {
     927           0 :                case WX_R: /* Freezing Drizzle/Rain */
     928           0 :                   return (NDFD_WxTable2_StdInten (88, ugly->intens[0]));
     929           0 :                case WX_L: /* Freezing Drizzle/Drizzle */
     930           0 :                   return (NDFD_WxTable2_StdInten (103, ugly->intens[0]));
     931           0 :                default: /* Freezing Drizzle */
     932           0 :                   return (NDFD_WxTable2_StdInten (85, ugly->intens[0]));
     933             :             }
     934             :          }
     935           0 :       case WX_ZR:
     936           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     937           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     938           0 :              (ugly->cover[0] == COV_CHC)) {
     939           0 :             switch (ugly->wx[1]) {
     940           0 :                case WX_R: /* Freezing Rain/Rain */
     941           0 :                   return (NDFD_WxTable2_StdInten (76, ugly->intens[0]));
     942           0 :                case WX_IP: /* Freezing Rain/Sleet */
     943           0 :                   return (NDFD_WxTable2_StdInten (79, ugly->intens[0]));
     944           0 :                default:
     945           0 :                   return (NDFD_WxTable2_StdInten (73, ugly->intens[0]));
     946             :             }
     947             :          } else {
     948           0 :             switch (ugly->wx[1]) {
     949           0 :                case WX_R: /* Freezing Rain/Rain */
     950           0 :                   return (NDFD_WxTable2_StdInten (94, ugly->intens[0]));
     951           0 :                case WX_IP: /* Freezing Rain/Sleet */
     952           0 :                   return (NDFD_WxTable2_StdInten (97, ugly->intens[0]));
     953           0 :                default:
     954           0 :                   return (NDFD_WxTable2_StdInten (91, ugly->intens[0]));
     955             :             }
     956             :          }
     957           0 :       case WX_IP:
     958           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     959           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     960           0 :              (ugly->cover[0] == COV_CHC)) {
     961           0 :             switch (ugly->wx[1]) {
     962           0 :                case WX_R: /* Sleet/Rain */
     963           0 :                   return (NDFD_WxTable2_StdInten (46, ugly->intens[0]));
     964           0 :                case WX_S: /* Sleet/Snow */
     965           0 :                   return (NDFD_WxTable2_StdInten (49, ugly->intens[0]));
     966           0 :                case WX_ZR: /* Sleet/Freezing Rain */
     967           0 :                   return (NDFD_WxTable2_StdInten (79, ugly->intens[0]));
     968           0 :                default:
     969           0 :                   return (NDFD_WxTable2_StdInten (64, ugly->intens[0]));
     970             :             }
     971             :          } else {
     972           0 :             switch (ugly->wx[1]) {
     973           0 :                case WX_R: /* Sleet/Rain */
     974           0 :                   return (NDFD_WxTable2_StdInten (58, ugly->intens[0]));
     975           0 :                case WX_S: /* Sleet/Snow */
     976           0 :                   return (NDFD_WxTable2_StdInten (61, ugly->intens[0]));
     977           0 :                case WX_ZR: /* Sleet/Freezing Rain */
     978           0 :                   return (NDFD_WxTable2_StdInten (97, ugly->intens[0]));
     979           0 :                default:
     980           0 :                   return (NDFD_WxTable2_StdInten (82, ugly->intens[0]));
     981             :             }
     982             :          }
     983           0 :       case WX_SW:
     984           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
     985           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
     986           0 :              (ugly->cover[0] == COV_CHC)) {
     987           0 :             switch (ugly->wx[1]) {
     988           0 :                case WX_R: /* Snow Showers/Rain */
     989             :                case WX_RW: /* Snow Showers/Rain Showers */
     990           0 :                   return (NDFD_WxTable2_StdInten (43, ugly->intens[0]));
     991           0 :                default: /* Snow Showers */
     992           0 :                   return (NDFD_WxTable2_StdInten (106, ugly->intens[0]));
     993             :             }
     994             :          } else {
     995           0 :             switch (ugly->wx[1]) {
     996           0 :                case WX_R: /* Snow Showers/Rain */
     997             :                case WX_RW: /* Snow Showers/Rain Showers */
     998           0 :                   return (NDFD_WxTable2_StdInten (55, ugly->intens[0]));
     999           0 :                default: /* Snow Showers */
    1000           0 :                   return (NDFD_WxTable2_StdInten (112, ugly->intens[0]));
    1001             :             }
    1002             :          }
    1003           0 :       case WX_S:
    1004           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
    1005           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
    1006           0 :              (ugly->cover[0] == COV_CHC)) {
    1007           0 :             switch (ugly->wx[1]) {
    1008           0 :                case WX_R: /* Snow/Rain */
    1009             :                case WX_RW: /* Snow/Rain Showers */
    1010           0 :                   return (NDFD_WxTable2_StdInten (40, ugly->intens[0]));
    1011           0 :                case WX_IP: /* Snow/Sleet */
    1012           0 :                   return (NDFD_WxTable2_StdInten (49, ugly->intens[0]));
    1013           0 :                default:
    1014           0 :                   return (NDFD_WxTable2_StdInten (109, ugly->intens[0]));
    1015             :             }
    1016             :          } else {
    1017           0 :             switch (ugly->wx[1]) {
    1018           0 :                case WX_R: /* Snow/Rain */
    1019             :                case WX_RW:
    1020           0 :                   return (NDFD_WxTable2_StdInten (52, ugly->intens[0]));
    1021           0 :                case WX_IP: /* Snow/Sleet */
    1022           0 :                   return (NDFD_WxTable2_StdInten (61, ugly->intens[0]));
    1023           0 :                default:
    1024           0 :                   return (NDFD_WxTable2_StdInten (115, ugly->intens[0]));
    1025             :             }
    1026             :          }
    1027           0 :       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           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
    1038           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
    1039           0 :              (ugly->cover[0] == COV_CHC)) {
    1040           0 :             switch (ugly->wx[1]) {
    1041           0 :                case WX_RW: /* Thunderstorms/Rain Showers */
    1042           0 :                   switch (ugly->intens[0]) {
    1043           0 :                      case INT_D:
    1044             :                      case INT_DD:
    1045           0 :                         return 17;
    1046           0 :                      case INT_P:
    1047           0 :                         return 14;
    1048           0 :                      default:
    1049           0 :                         return 15;
    1050             :                   }
    1051           0 :                case WX_R: /* Thunderstorms/Rain */
    1052           0 :                   switch (ugly->intens[0]) {
    1053           0 :                      case INT_D:
    1054             :                      case INT_DD:
    1055           0 :                         return 9;
    1056           0 :                      case INT_P:
    1057           0 :                         return 7;
    1058           0 :                      default:
    1059           0 :                         return 10;
    1060             :                   }
    1061           0 :                default: /* Thunderstorms. */
    1062           0 :                   switch (ugly->intens[0]) {
    1063           0 :                      case INT_D:
    1064             :                      case INT_DD:
    1065           0 :                         return 18;
    1066           0 :                      case INT_P:
    1067           0 :                         return 19;
    1068           0 :                      default:
    1069           0 :                         return 18;
    1070             :                   }
    1071             :             }
    1072             :          } else {
    1073           0 :             switch (ugly->wx[1]) {
    1074           0 :                case WX_RW: /* Thunderstorms/Rain Showers */
    1075           0 :                   switch (ugly->intens[0]) {
    1076           0 :                      case INT_D:
    1077             :                      case INT_DD:
    1078           0 :                         return 36;
    1079           0 :                      case INT_P:
    1080           0 :                         return 34;
    1081           0 :                      default:
    1082           0 :                         return 33; /* corrected from 37 */
    1083             :                   }
    1084           0 :                case WX_R: /* Thunderstorms/Rain */
    1085           0 :                   switch (ugly->intens[0]) {
    1086           0 :                      case INT_D:
    1087             :                      case INT_DD:
    1088           0 :                         return 29;
    1089           0 :                      case INT_P:
    1090           0 :                         return 26;
    1091           0 :                      default:
    1092           0 :                         return 27;
    1093             :                   }
    1094           0 :                default: /* Thunderstorms. */
    1095           0 :                   switch (ugly->intens[0]) {
    1096           0 :                      case INT_D:
    1097             :                      case INT_DD:
    1098           0 :                         return 37;
    1099           0 :                      case INT_P:
    1100           0 :                         return 38;
    1101           0 :                      default:
    1102           0 :                         return 37;
    1103             :                   }
    1104             :             }
    1105             :          }
    1106           0 :       case WX_A:       /* Ignore Hail */
    1107           0 :          return 0;
    1108           0 :       case WX_F:       /* Fog */
    1109           0 :          switch (ugly->intens[0]) {
    1110           0 :             case INT_P:
    1111           0 :                return 118;
    1112           0 :             default:
    1113           0 :                return 117;
    1114             :          }
    1115           0 :       case WX_H:       /* Haze */
    1116           0 :          return 119;
    1117           0 :       case WX_K:       /* Smoke */
    1118           0 :          return 120;
    1119           0 :       case WX_FR:      /* Ignore Frost */
    1120           0 :          return 0;
    1121           0 :       case WX_BS:      /* Blowing Snow */
    1122           0 :          return 121;
    1123           0 :       case WX_BD:      /* Blowing Dust */
    1124           0 :          return 122;
    1125           0 :       default:
    1126           0 :          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             :  */
    1296           0 : static int NDFD_WxTable3 (UglyStringType * ugly)
    1297             : {
    1298           0 :    switch (ugly->wx[0]) {
    1299           0 :       case WX_NOWX:
    1300           0 :          return 0;
    1301           0 :       case WX_R:
    1302           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
    1303           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
    1304           0 :              (ugly->cover[0] == COV_CHC)) {
    1305           0 :             switch (ugly->wx[1]) {
    1306           0 :                case WX_S:
    1307           0 :                   return (NDFD_WxTable2_StdInten (40, ugly->intens[0]));
    1308           0 :                case WX_ZR: /* Rain/Freezing Rain */
    1309           0 :                   return (NDFD_WxTable2_StdInten (76, ugly->intens[0]));
    1310           0 :                case WX_IP: /* Rain/Sleet */
    1311           0 :                   return (NDFD_WxTable2_StdInten (46, ugly->intens[0]));
    1312           0 :                case WX_ZL: /* Rain/Freezing Drizzle */
    1313           0 :                   return (NDFD_WxTable2_StdInten (70, ugly->intens[0]));
    1314           0 :                case WX_SW: /* Rain/Snow Showers */
    1315           0 :                   return (NDFD_WxTable2_StdInten (40, ugly->intens[0]));
    1316           0 :                case WX_T: /* Rain/Thunderstorms */
    1317           0 :                   switch (ugly->intens[0]) {
    1318           0 :                      case INT_D:
    1319             :                      case INT_DD:
    1320           0 :                         return 9;
    1321           0 :                      case INT_P:
    1322           0 :                         return 8;
    1323           0 :                      default:
    1324           0 :                         return 27;
    1325             :                   }
    1326           0 :                default:
    1327           0 :                   return (NDFD_WxTable2_StdInten (5, ugly->intens[0]));
    1328             :             }
    1329             :          } else {
    1330           0 :             switch (ugly->wx[1]) {
    1331           0 :                case WX_S: /* Rain/Snow */
    1332           0 :                   return (NDFD_WxTable2_StdInten (52, ugly->intens[0]));
    1333           0 :                case WX_ZR: /* Rain/Freezing Rain */
    1334           0 :                   return (NDFD_WxTable2_StdInten (94, ugly->intens[0]));
    1335           0 :                case WX_IP: /* Rain/Sleet */
    1336           0 :                   return (NDFD_WxTable2_StdInten (58, ugly->intens[0]));
    1337           0 :                case WX_ZL: /* Rain/Freezing Drizzle */
    1338           0 :                   return (NDFD_WxTable2_StdInten (88, ugly->intens[0]));
    1339           0 :                case WX_SW: /* Rain/Snow Showers */
    1340           0 :                   return (NDFD_WxTable2_StdInten (52, ugly->intens[0]));
    1341           0 :                case WX_T: /* Rain/Thunderstorms */
    1342           0 :                   switch (ugly->intens[0]) {
    1343           0 :                      case INT_D:
    1344             :                      case INT_DD:
    1345           0 :                         return 29;
    1346           0 :                      case INT_P:
    1347           0 :                         return 28;
    1348           0 :                      default:
    1349           0 :                         return 27;
    1350             :                   }
    1351           0 :                default:
    1352           0 :                   return (NDFD_WxTable2_StdInten (24, ugly->intens[0]));
    1353             :             }
    1354             :          }
    1355           0 :       case WX_RW:
    1356           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
    1357           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
    1358           0 :              (ugly->cover[0] == COV_CHC)) {
    1359           0 :             switch (ugly->wx[1]) {
    1360           0 :                case WX_T: /* Rain Showers/Thunderstorms */
    1361           0 :                   switch (ugly->intens[0]) {
    1362           0 :                      case INT_D:
    1363             :                      case INT_DD:
    1364           0 :                         return 17;
    1365           0 :                      case INT_P:
    1366           0 :                         return 16;
    1367           0 :                      default:
    1368           0 :                         return 15;
    1369             :                   }
    1370           0 :                case WX_SW: /* Rain Showers/Snow Showers */
    1371             :                case WX_S: /* Rain Showers/Snow */
    1372           0 :                   return (NDFD_WxTable2_StdInten (43, ugly->intens[0]));
    1373           0 :                default:
    1374           0 :                   return (NDFD_WxTable2_StdInten (12, ugly->intens[0]));
    1375             :             }
    1376             :          } else {
    1377           0 :             switch (ugly->wx[1]) {
    1378           0 :                case WX_T: /* Rain Showers/Thunderstorms */
    1379           0 :                   switch (ugly->intens[0]) {
    1380           0 :                      case INT_D:
    1381             :                      case INT_DD:
    1382           0 :                         return 36;
    1383           0 :                      case INT_P:
    1384           0 :                         return 35;
    1385           0 :                      default:
    1386           0 :                         return 33;
    1387             :                   }
    1388           0 :                case WX_SW: /* Rain Showers/Snow Showers */
    1389             :                case WX_S: /* Rain Showers/Snow */
    1390           0 :                   return (NDFD_WxTable2_StdInten (55, ugly->intens[0]));
    1391           0 :                default:
    1392           0 :                   return (NDFD_WxTable2_StdInten (31, ugly->intens[0]));
    1393             :             }
    1394             :          }
    1395           0 :       case WX_L:
    1396           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
    1397           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
    1398           0 :              (ugly->cover[0] == COV_CHC)) {
    1399           0 :             switch (ugly->wx[1]) {
    1400           0 :                case WX_ZL: /* Drizzle/Freezing Drizzle */
    1401           0 :                   return (NDFD_WxTable2_StdInten (100, ugly->intens[0]));
    1402           0 :                case WX_F:
    1403             :                default: /* Drizzle */
    1404           0 :                   return (NDFD_WxTable2_StdInten (2, ugly->intens[0]));
    1405             :             }
    1406             :          } else {
    1407           0 :             switch (ugly->wx[1]) {
    1408           0 :                case WX_ZL: /* Drizzle/Freezing Drizzle */
    1409           0 :                   return (NDFD_WxTable2_StdInten (103, ugly->intens[0]));
    1410           0 :                case WX_F:
    1411             :                default: /* Drizzle */
    1412           0 :                   return (NDFD_WxTable2_StdInten (21, ugly->intens[0]));
    1413             :             }
    1414             :          }
    1415           0 :       case WX_ZL:
    1416           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
    1417           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
    1418           0 :              (ugly->cover[0] == COV_CHC)) {
    1419           0 :             switch (ugly->wx[1]) {
    1420           0 :                case WX_R: /* Freezing Drizzle/Rain */
    1421           0 :                   return (NDFD_WxTable2_StdInten (70, ugly->intens[0]));
    1422           0 :                case WX_L: /* Freezing Drizzle/Drizzle */
    1423           0 :                   return (NDFD_WxTable2_StdInten (100, ugly->intens[0]));
    1424           0 :                default:
    1425           0 :                   return (NDFD_WxTable2_StdInten (67, ugly->intens[0]));
    1426             :             }
    1427             :          } else {
    1428           0 :             switch (ugly->wx[1]) {
    1429           0 :                case WX_R: /* Freezing Drizzle/Rain */
    1430           0 :                   return (NDFD_WxTable2_StdInten (88, ugly->intens[0]));
    1431           0 :                case WX_L: /* Freezing Drizzle/Drizzle */
    1432           0 :                   return (NDFD_WxTable2_StdInten (103, ugly->intens[0]));
    1433           0 :                default: /* Freezing Drizzle */
    1434           0 :                   return (NDFD_WxTable2_StdInten (85, ugly->intens[0]));
    1435             :             }
    1436             :          }
    1437           0 :       case WX_ZR:
    1438           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
    1439           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
    1440           0 :              (ugly->cover[0] == COV_CHC)) {
    1441           0 :             switch (ugly->wx[1]) {
    1442           0 :                case WX_R: /* Freezing Rain/Rain */
    1443           0 :                   return (NDFD_WxTable2_StdInten (76, ugly->intens[0]));
    1444           0 :                case WX_IP: /* Freezing Rain/Sleet */
    1445           0 :                   return (NDFD_WxTable2_StdInten (79, ugly->intens[0]));
    1446           0 :                default:
    1447           0 :                   return (NDFD_WxTable2_StdInten (73, ugly->intens[0]));
    1448             :             }
    1449             :          } else {
    1450           0 :             switch (ugly->wx[1]) {
    1451           0 :                case WX_R: /* Freezing Rain/Rain */
    1452           0 :                   return (NDFD_WxTable2_StdInten (94, ugly->intens[0]));
    1453           0 :                case WX_IP: /* Freezing Rain/Sleet */
    1454           0 :                   return (NDFD_WxTable2_StdInten (97, ugly->intens[0]));
    1455           0 :                default:
    1456           0 :                   return (NDFD_WxTable2_StdInten (91, ugly->intens[0]));
    1457             :             }
    1458             :          }
    1459           0 :       case WX_IP:
    1460           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
    1461           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
    1462           0 :              (ugly->cover[0] == COV_CHC)) {
    1463           0 :             switch (ugly->wx[1]) {
    1464           0 :                case WX_R: /* Sleet/Rain */
    1465           0 :                   return (NDFD_WxTable2_StdInten (46, ugly->intens[0]));
    1466           0 :                case WX_S: /* Sleet/Snow */
    1467           0 :                   return (NDFD_WxTable2_StdInten (49, ugly->intens[0]));
    1468           0 :                case WX_ZR: /* Sleet/Freezing Rain */
    1469           0 :                   return (NDFD_WxTable2_StdInten (79, ugly->intens[0]));
    1470           0 :                default:
    1471           0 :                   return (NDFD_WxTable2_StdInten (64, ugly->intens[0]));
    1472             :             }
    1473             :          } else {
    1474           0 :             switch (ugly->wx[1]) {
    1475           0 :                case WX_R: /* Sleet/Rain */
    1476           0 :                   return (NDFD_WxTable2_StdInten (58, ugly->intens[0]));
    1477           0 :                case WX_S: /* Sleet/Snow */
    1478           0 :                   return (NDFD_WxTable2_StdInten (61, ugly->intens[0]));
    1479           0 :                case WX_ZR: /* Sleet/Freezing Rain */
    1480           0 :                   return (NDFD_WxTable2_StdInten (97, ugly->intens[0]));
    1481           0 :                default:
    1482           0 :                   return (NDFD_WxTable2_StdInten (82, ugly->intens[0]));
    1483             :             }
    1484             :          }
    1485           0 :       case WX_SW:
    1486           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
    1487           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
    1488           0 :              (ugly->cover[0] == COV_CHC)) {
    1489           0 :             switch (ugly->wx[1]) {
    1490           0 :                case WX_R: /* Snow Showers/Rain */
    1491             :                case WX_RW: /* Snow Showers/Rain Showers */
    1492           0 :                   return (NDFD_WxTable2_StdInten (43, ugly->intens[0]));
    1493           0 :                default: /* Snow Showers */
    1494           0 :                   return (NDFD_WxTable2_StdInten (106, ugly->intens[0]));
    1495             :             }
    1496             :          } else {
    1497           0 :             switch (ugly->wx[1]) {
    1498           0 :                case WX_R: /* Snow Showers/Rain */
    1499             :                case WX_RW: /* Snow Showers/Rain Showers */
    1500           0 :                   return (NDFD_WxTable2_StdInten (55, ugly->intens[0]));
    1501           0 :                default: /* Snow Showers */
    1502           0 :                   return (NDFD_WxTable2_StdInten (112, ugly->intens[0]));
    1503             :             }
    1504             :          }
    1505           0 :       case WX_S:
    1506           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
    1507           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
    1508           0 :              (ugly->cover[0] == COV_CHC)) {
    1509           0 :             switch (ugly->wx[1]) {
    1510           0 :                case WX_R: /* Snow/Rain */
    1511             :                case WX_RW: /* Snow/Rain Showers */
    1512           0 :                   return (NDFD_WxTable2_StdInten (40, ugly->intens[0]));
    1513           0 :                case WX_IP: /* Snow/Sleet */
    1514           0 :                   return (NDFD_WxTable2_StdInten (49, ugly->intens[0]));
    1515           0 :                default:
    1516           0 :                   return (NDFD_WxTable2_StdInten (109, ugly->intens[0]));
    1517             :             }
    1518             :          } else {
    1519           0 :             switch (ugly->wx[1]) {
    1520           0 :                case WX_R: /* Snow/Rain */
    1521             :                case WX_RW:
    1522           0 :                   return (NDFD_WxTable2_StdInten (52, ugly->intens[0]));
    1523           0 :                case WX_IP: /* Snow/Sleet */
    1524           0 :                   return (NDFD_WxTable2_StdInten (61, ugly->intens[0]));
    1525           0 :                default:
    1526           0 :                   return (NDFD_WxTable2_StdInten (115, ugly->intens[0]));
    1527             :             }
    1528             :          }
    1529           0 :       case WX_T:
    1530           0 :          if ((ugly->cover[0] == COV_SCT) || (ugly->cover[0] == COV_SCHC) ||
    1531           0 :              (ugly->cover[0] == COV_PATCHY) || (ugly->cover[0] == COV_ISO) ||
    1532           0 :              (ugly->cover[0] == COV_CHC)) {
    1533           0 :             switch (ugly->wx[1]) {
    1534           0 :                case WX_RW: /* Thunderstorms/Rain Showers */
    1535           0 :                   switch (ugly->intens[0]) {
    1536           0 :                      case INT_D:
    1537             :                      case INT_DD:
    1538           0 :                         return 17;
    1539           0 :                      case INT_P:
    1540           0 :                         return 14;
    1541           0 :                      default:
    1542           0 :                         return 15;
    1543             :                   }
    1544           0 :                case WX_R: /* Thunderstorms/Rain */
    1545           0 :                   switch (ugly->intens[0]) {
    1546           0 :                      case INT_D:
    1547             :                      case INT_DD:
    1548           0 :                         return 9;
    1549           0 :                      case INT_P:
    1550           0 :                         return 7;
    1551           0 :                      default:
    1552           0 :                         return 10;
    1553             :                   }
    1554           0 :                default: /* Thunderstorms. */
    1555           0 :                   switch (ugly->intens[0]) {
    1556           0 :                      case INT_D:
    1557             :                      case INT_DD:
    1558           0 :                         return 18;
    1559           0 :                      case INT_P:
    1560           0 :                         return 19;
    1561           0 :                      default:
    1562           0 :                         return 18;
    1563             :                   }
    1564             :             }
    1565             :          } else {
    1566           0 :             switch (ugly->wx[1]) {
    1567           0 :                case WX_RW: /* Thunderstorms/Rain Showers */
    1568           0 :                   switch (ugly->intens[0]) {
    1569           0 :                      case INT_D:
    1570             :                      case INT_DD:
    1571           0 :                         return 36;
    1572           0 :                      case INT_P:
    1573           0 :                         return 34;
    1574           0 :                      default:
    1575           0 :                         return 33;
    1576             :                   }
    1577           0 :                case WX_R: /* Thunderstorms/Rain */
    1578           0 :                   switch (ugly->intens[0]) {
    1579           0 :                      case INT_D:
    1580             :                      case INT_DD:
    1581           0 :                         return 29;
    1582           0 :                      case INT_P:
    1583           0 :                         return 26;
    1584           0 :                      default:
    1585           0 :                         return 27;
    1586             :                   }
    1587           0 :                default: /* Thunderstorms. */
    1588           0 :                   switch (ugly->intens[0]) {
    1589           0 :                      case INT_D:
    1590             :                      case INT_DD:
    1591           0 :                         return 37;
    1592           0 :                      case INT_P:
    1593           0 :                         return 38;
    1594           0 :                      default:
    1595           0 :                         return 37;
    1596             :                   }
    1597             :             }
    1598             :          }
    1599           0 :       case WX_A:       /* Ignore Hail */
    1600           0 :          return 0;
    1601           0 :       case WX_F:       /* Fog */
    1602           0 :          switch (ugly->intens[0]) {
    1603           0 :             case INT_P:
    1604           0 :                return 118;
    1605           0 :             default:
    1606           0 :                return 117;
    1607             :          }
    1608           0 :       case WX_H:       /* Haze */
    1609           0 :          return 119;
    1610           0 :       case WX_K:       /* Smoke */
    1611           0 :          return 120;
    1612           0 :       case WX_FR:      /* Ignore Frost */
    1613           0 :          return 0;
    1614           0 :       case WX_BS:      /* Blowing Snow */
    1615           0 :          return 121;
    1616           0 :       case WX_BD:      /* Blowing Dust */
    1617           0 :          return 122;
    1618           0 :       case WX_ZF:      /* Freezing Fog */
    1619           0 :          return 123;
    1620           0 :       case WX_IF:      /* Ice Fog */
    1621           0 :          return 124;
    1622           0 :       case WX_IC:      /* Ice Crystals */
    1623           0 :          return 125;
    1624           0 :       case WX_BN:      /* Blowing Sand */
    1625           0 :          return 126;
    1626           0 :       case WX_ZY:      /* Freezing Spray */
    1627           0 :          return 127;
    1628           0 :       case WX_VA:      /* Volcanic Ash */
    1629           0 :          return 128;
    1630           0 :       case WX_WP:      /* Water Spouts */
    1631           0 :          return 129;
    1632           0 :       default:
    1633           0 :          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             :  */
    1660           0 : static int NDFD_Wx2Code4 (int wxtype)
    1661             : {
    1662           0 :    switch (wxtype) {
    1663           0 :       case WX_R:
    1664           0 :          return 0;
    1665           0 :       case WX_RW:
    1666           0 :          return 10;
    1667           0 :       case WX_L:
    1668           0 :          return 20;
    1669           0 :       case WX_ZL:
    1670           0 :          return 30;
    1671           0 :       case WX_ZR:
    1672           0 :          return 40;
    1673           0 :       case WX_IP:
    1674           0 :          return 50;
    1675           0 :       case WX_SW:
    1676           0 :          return 60;
    1677           0 :       case WX_S:
    1678           0 :          return 70;
    1679           0 :       case WX_T:
    1680           0 :          return 80;
    1681           0 :       case WX_F:
    1682           0 :          return 90;
    1683           0 :       default:
    1684           0 :          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             :  */
    1713           0 : static int NDFD_CodeIntens4 (int inten1, int inten2)
    1714             : {
    1715           0 :    switch (inten2) {
    1716           0 :       case INT_NOINT:
    1717             :       case INT_UNKNOWN:
    1718             :       case INT_M:
    1719           0 :          if ((inten1 == INT_NOINT) || (inten1 == INT_UNKNOWN) ||
    1720             :              (inten1 == INT_M)) {
    1721           0 :             return 0;
    1722           0 :          } else if ((inten1 == INT_D) || (inten1 == INT_DD)) {
    1723           0 :             return 1;
    1724             :          }
    1725             :          /* Default case */
    1726             :          /* else if (inten1 == INT_P) */
    1727           0 :          return 2;
    1728           0 :       case INT_D:
    1729             :       case INT_DD:
    1730           0 :          if ((inten1 == INT_NOINT) || (inten1 == INT_UNKNOWN) ||
    1731             :              (inten1 == INT_M)) {
    1732           0 :             return 3;
    1733           0 :          } else if ((inten1 == INT_D) || (inten1 == INT_DD)) {
    1734           0 :             return 4;
    1735             :          }
    1736             :          /* Default case */
    1737             :          /* else if (inten1 == INT_P) */
    1738           0 :          return 5;
    1739           0 :       case INT_P:
    1740             :       default:
    1741           0 :          if ((inten1 == INT_NOINT) || (inten1 == INT_UNKNOWN) ||
    1742             :              (inten1 == INT_M)) {
    1743           0 :             return 6;
    1744           0 :          } else if ((inten1 == INT_D) || (inten1 == INT_DD)) {
    1745           0 :             return 7;
    1746             :          }
    1747             :          /* Default case */
    1748             :          /* else if (inten1 == INT_P) */
    1749           0 :          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             :  */
    1783           0 : static int NDFD_WxTable4 (UglyStringType * ugly)
    1784             : {
    1785           0 :    int code = 0;
    1786           0 :    int numValid = ugly->numValid;
    1787           0 :    int cover1 = ugly->cover[1];
    1788           0 :    int intens1 = ugly->intens[1];
    1789             : 
    1790           0 :    if (numValid > 1) {
    1791           0 :       if ((ugly->wx[1] != WX_R) && (ugly->wx[1] != WX_S) &&
    1792           0 :           (ugly->wx[1] != WX_RW) && (ugly->wx[1] != WX_SW) &&
    1793           0 :           (ugly->wx[1] != WX_T) && (ugly->wx[1] != WX_ZR) &&
    1794           0 :           (ugly->wx[1] != WX_IP) && (ugly->wx[1] != WX_ZL) &&
    1795           0 :           (ugly->wx[1] != WX_L) && (ugly->wx[1] != WX_F)) {
    1796           0 :          numValid = 1;
    1797           0 :          cover1 = COV_UNKNOWN;
    1798           0 :          intens1 = INT_UNKNOWN;
    1799             :       }
    1800             :    }
    1801             : 
    1802           0 :    switch (ugly->wx[0]) {
    1803           0 :       case WX_NOWX:    /* NoWx */
    1804             :       case WX_A:       /* Hail */
    1805             :       case WX_FR:      /* Frost */
    1806           0 :          code = 0;
    1807           0 :          break;
    1808           0 :       case WX_R:       /* Rain */
    1809           0 :          code = 1;
    1810           0 :          if (numValid > 1) {
    1811           0 :             code = 100 + NDFD_Wx2Code4 (ugly->wx[1]);
    1812             :          }
    1813           0 :          break;
    1814           0 :       case WX_RW:      /* Rain Showers */
    1815           0 :          code = 4;
    1816           0 :          if (numValid > 1) {
    1817           0 :             code = 200 + NDFD_Wx2Code4 (ugly->wx[1]);
    1818             :          }
    1819           0 :          break;
    1820           0 :       case WX_L:       /* Drizzle */
    1821           0 :          code = 7;
    1822           0 :          if (numValid > 1) {
    1823           0 :             code = 300 + NDFD_Wx2Code4 (ugly->wx[1]);
    1824             :          }
    1825           0 :          break;
    1826           0 :       case WX_ZL:      /* Freezing Drizzle */
    1827           0 :          code = 10;
    1828           0 :          if (numValid > 1) {
    1829           0 :             code = 400 + NDFD_Wx2Code4 (ugly->wx[1]);
    1830             :          }
    1831           0 :          break;
    1832           0 :       case WX_ZR:      /* Freezing Rain */
    1833           0 :          code = 13;
    1834           0 :          if (numValid > 1) {
    1835           0 :             code = 500 + NDFD_Wx2Code4 (ugly->wx[1]);
    1836             :          }
    1837           0 :          break;
    1838           0 :       case WX_IP:      /* Sleet */
    1839           0 :          code = 16;
    1840           0 :          if (numValid > 1) {
    1841           0 :             code = 600 + NDFD_Wx2Code4 (ugly->wx[1]);
    1842             :          }
    1843           0 :          break;
    1844           0 :       case WX_SW:      /* Snow Showers */
    1845           0 :          code = 19;
    1846           0 :          if (numValid > 1) {
    1847           0 :             code = 700 + NDFD_Wx2Code4 (ugly->wx[1]);
    1848             :          }
    1849           0 :          break;
    1850           0 :       case WX_S:       /* Snow */
    1851           0 :          code = 22;
    1852           0 :          if (numValid > 1) {
    1853           0 :             code = 800 + NDFD_Wx2Code4 (ugly->wx[1]);
    1854             :          }
    1855           0 :          break;
    1856           0 :       case WX_T:       /* Thunderstorms */
    1857           0 :          code = 25;
    1858           0 :          if (numValid > 1) {
    1859           0 :             code = 900 + NDFD_Wx2Code4 (ugly->wx[1]);
    1860             :          }
    1861           0 :          break;
    1862           0 :       case WX_F:       /* Fog */
    1863           0 :          code = 28;
    1864           0 :          if (numValid > 1) {
    1865           0 :             code = 1000 + NDFD_Wx2Code4 (ugly->wx[1]);
    1866             :          }
    1867           0 :          break;
    1868           0 :       case WX_K:       /* Smoke */
    1869           0 :          code = 31;
    1870           0 :          break;
    1871           0 :       case WX_BS:      /* Blowing Snow */
    1872           0 :          code = 32;
    1873           0 :          break;
    1874           0 :       case WX_BD:      /* Blowing Dust */
    1875           0 :          code = 33;
    1876           0 :          break;
    1877           0 :       case WX_ZF:      /* Freezing Fog */
    1878           0 :          code = 34;
    1879           0 :          break;
    1880           0 :       case WX_IF:      /* Ice Fog */
    1881           0 :          code = 35;
    1882           0 :          break;
    1883           0 :       case WX_IC:      /* Ice Crystals */
    1884           0 :          code = 36;
    1885           0 :          break;
    1886           0 :       case WX_BN:      /* Blowing Sand */
    1887           0 :          code = 37;
    1888           0 :          break;
    1889           0 :       case WX_ZY:      /* Freezing Spray */
    1890           0 :          code = 38;
    1891           0 :          break;
    1892           0 :       case WX_VA:      /* Volcanic Ash */
    1893           0 :          code = 39;
    1894           0 :          break;
    1895           0 :       case WX_WP:      /* Water Spouts */
    1896           0 :          code = 40;
    1897           0 :          break;
    1898           0 :       case WX_H:       /* Haze */
    1899           0 :          code = 41;
    1900           0 :          break;
    1901           0 :       default:
    1902           0 :          code = 0;
    1903             :    }                    /* End of Switch statement. */
    1904             : 
    1905           0 :    if ((ugly->wx[0] == WX_R) || (ugly->wx[0] == WX_S) ||
    1906           0 :        (ugly->wx[0] == WX_RW) || (ugly->wx[0] == WX_SW) ||
    1907           0 :        (ugly->wx[0] == WX_T) || (ugly->wx[0] == WX_ZR) ||
    1908           0 :        (ugly->wx[0] == WX_IP) || (ugly->wx[0] == WX_ZL) ||
    1909           0 :        (ugly->wx[0] == WX_L) || (ugly->wx[0] == WX_F)) {
    1910           0 :       code += NDFD_CodeIntens4 (ugly->intens[0], intens1);
    1911             :    }
    1912             : 
    1913           0 :    if ((ugly->cover[0] == COV_WIDE) || (ugly->cover[0] == COV_LKLY) ||
    1914           0 :        (ugly->cover[0] == COV_NUM) || (ugly->cover[0] == COV_OCNL) ||
    1915           0 :        (ugly->cover[0] == COV_DEF) || (ugly->cover[0] == COV_AREAS) ||
    1916           0 :        (ugly->cover[0] == COV_PDS) || (ugly->cover[0] == COV_FRQ) ||
    1917           0 :        (ugly->cover[0] == COV_INTER) || (ugly->cover[0] == COV_BRIEF) ||
    1918           0 :        (cover1 == COV_WIDE) || (cover1 == COV_LKLY) || (cover1 == COV_NUM) ||
    1919           0 :        (cover1 == COV_OCNL) || (cover1 == COV_DEF) ||
    1920           0 :        (cover1 == COV_AREAS) || (cover1 == COV_PDS) || (cover1 == COV_FRQ) ||
    1921           0 :        (cover1 == COV_INTER) || (cover1 == COV_BRIEF)) {
    1922           0 :       code += 1100;
    1923             :    }
    1924             : 
    1925           0 :    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             :  */
    1949           0 : void FreeUglyString (UglyStringType * ugly)
    1950             : {
    1951             :    int j;               /* Used to free all the English words. */
    1952             : 
    1953           0 :    for (j = 0; j < NUM_UGLY_WORD; j++) {
    1954           0 :       free (ugly->english[j]);
    1955             :    }
    1956           0 :    free (ugly->errors);
    1957           0 : }
    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             :  */
    1982           0 : 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           0 :    ugly->numValid = 0;
    1988           0 :    ugly->minVis = 0;
    1989           0 :    ugly->validIndex = 0;
    1990           0 :    ugly->SimpleCode = 0;
    1991           0 :    ugly->errors = NULL;
    1992           0 :    for (i = 0; i < NUM_UGLY_WORD; i++) {
    1993           0 :       ugly->wx[i] = 0;
    1994           0 :       ugly->cover[i] = 0;
    1995           0 :       ugly->intens[i] = 0;
    1996           0 :       ugly->vis[i] = VIS_UNKNOWN;
    1997           0 :       for (j = 0; j < NUM_UGLY_ATTRIB; j++) {
    1998           0 :          ugly->attrib[i][j] = 0;
    1999             :       }
    2000           0 :       ugly->f_or[i] = 0;
    2001           0 :       ugly->f_priority[i] = 0;
    2002           0 :       ugly->english[i] = NULL;
    2003           0 :       ugly->wx_inten[i] = 0;
    2004           0 :       ugly->HazCode[i] = 0;
    2005             :    }
    2006           0 : }
    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             :  */
    2035           0 : 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           0 :    for (i = 0; i < tableLen; i++) {
    2040           0 :       if (strcmp (data, table[i].abrev) == 0) {
    2041           0 :          *ans = i;
    2042           0 :          return 0;
    2043             :       }
    2044             :    }
    2045           0 :    if (strcmp (data, "<Invalid>") == 0) {
    2046           0 :       return 1;
    2047             :    } else {
    2048           0 :       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             :  */
    2083           0 : static int UglyLookUp (UglyStringType * ugly, char *data, uChar word,
    2084             :                        uChar place, uChar attNum)
    2085             : {
    2086             :    int ans;
    2087             : 
    2088           0 :    switch (place) {
    2089           0 :       case 0:          /* Cover */
    2090           0 :          ans = FindInTable (WxCover, (sizeof (WxCover) / sizeof (WxTable)),
    2091           0 :                             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           0 :          if (ans != 0) {
    2100           0 :             if (strlen (data) == 0) {
    2101           0 :                ugly->cover[word] = COV_NOCOV;
    2102             :             } else {
    2103           0 :                ugly->cover[word] = COV_UNKNOWN;
    2104             : #ifdef VERBOSE
    2105             :                printf ("No '%s' in WxCover\n", data);
    2106             : #endif
    2107             : #ifdef STORE_ERRORS
    2108           0 :                reallocSprintf (&(ugly->errors), "No '%s' in WxCover ", data);
    2109             : #endif
    2110             : /*
    2111             :                return -2;
    2112             : */
    2113             :             }
    2114             :          }
    2115           0 :          break;
    2116           0 :       case 1:          /* Weather */
    2117           0 :          ans = FindInTable (WxCode, (sizeof (WxCode) / sizeof (WxTable)),
    2118           0 :                             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           0 :          if (ans != 0) {
    2127           0 :             if (strlen (data) == 0) {
    2128           0 :                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           0 :                reallocSprintf (&(ugly->errors), "No '%s' in WxCode ", data);
    2135             : #endif
    2136           0 :                return -2;
    2137             :             }
    2138             :          }
    2139           0 :          break;
    2140           0 :       case 2:          /* Intensity */
    2141           0 :          ans = FindInTable (WxIntens, (sizeof (WxIntens) / sizeof (WxTable)),
    2142           0 :                             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           0 :          if (ans != 0) {
    2151           0 :             if (strlen (data) == 0) {
    2152           0 :                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           0 :                reallocSprintf (&(ugly->errors), "No '%s' in WxIntens ", data);
    2159             : #endif
    2160           0 :                return -2;
    2161             :             }
    2162             :          }
    2163           0 :          break;
    2164           0 :       case 3:          /* Vis */
    2165           0 :          ans = FindInTable (WxVisib, (sizeof (WxVisib) / sizeof (WxTable)),
    2166           0 :                             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           0 :          if (ans != 0) {
    2175           0 :             if (strlen (data) == 0) {
    2176           0 :                ugly->vis[word] = 0;
    2177             :             } else {
    2178             : #ifdef VERBOSE
    2179             :                printf ("No '%s' in WxVisib\n", data);
    2180             : #endif
    2181             : #ifdef STORE_ERRORS
    2182           0 :                reallocSprintf (&(ugly->errors), "No '%s' in WxVisib ", data);
    2183             : #endif
    2184           0 :                return -2;
    2185             :             }
    2186             :          }
    2187           0 :          ugly->vis[word] = atoi (WxVisib[ugly->vis[word]].name);
    2188           0 :          if (word == 0) {
    2189           0 :             ugly->minVis = ugly->vis[word];
    2190           0 :          } else if (ugly->minVis > ugly->vis[word]) {
    2191           0 :             ugly->minVis = ugly->vis[word];
    2192             :          }
    2193           0 :          break;
    2194           0 :       case 4:          /* Attrib */
    2195           0 :          ans = FindInTable (WxAttrib, (sizeof (WxAttrib) / sizeof (WxTable)),
    2196           0 :                             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           0 :          if (ans != 0) {
    2205             : #ifdef VERBOSE
    2206             :             printf ("No '%s' in WxAttrib\n", data);
    2207             : #endif
    2208             : #ifdef STORE_ERRORS
    2209           0 :             reallocSprintf (&(ugly->errors), "No '%s' in WxAttrib ", data);
    2210             : #endif
    2211           0 :             return -2;
    2212             :          } else {
    2213             :             /* Check if it is the "OR" or "MX" case. */
    2214           0 :             if (ugly->attrib[word][attNum] == HAZ_OR) {
    2215           0 :                ugly->attrib[word][attNum] = 0;
    2216           0 :                ugly->f_or[word] = 1;
    2217           0 :             } else if (ugly->attrib[word][attNum] == HAZ_PRI2) {
    2218           0 :                ugly->attrib[word][attNum] = 0;
    2219           0 :                ugly->f_priority[word] = 2;
    2220           0 :             } else if (ugly->attrib[word][attNum] == HAZ_PRI1) {
    2221           0 :                ugly->attrib[word][attNum] = 0;
    2222           0 :                ugly->f_priority[word] = 1;
    2223             :             }
    2224             :          }
    2225           0 :          break;
    2226           0 :       default:
    2227           0 :          return -1;
    2228             :    }
    2229           0 :    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             : 
    2260           0 : static void safe_strcat(char* target, size_t target_size,
    2261             :                         const char* string_to_append)
    2262             : {
    2263           0 :     size_t target_length = strlen(target);
    2264           0 :     if( target_length + strlen(string_to_append) < target_size )
    2265           0 :         strcat(target + target_length, string_to_append);
    2266           0 : }
    2267             : 
    2268           0 : 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           0 :    for (i = 0; i < ugly->numValid; i++) {
    2280           0 :       buffer[0] = '\0';
    2281             :       /* Handle Coverage. */
    2282           0 :       if (ugly->cover[i] != 0) {
    2283           0 :          safe_strcat (buffer, sizeof(buffer), WxCover[ugly->cover[i]].name);
    2284           0 :          safe_strcat (buffer, sizeof(buffer), " ");
    2285             :       }
    2286             :       /* Handle Intensity. */
    2287           0 :       if (ugly->intens[i] != 0) {
    2288           0 :          safe_strcat (buffer, sizeof(buffer), WxIntens[ugly->intens[i]].name);
    2289           0 :          safe_strcat (buffer, sizeof(buffer), " ");
    2290             :       }
    2291           0 :       safe_strcat (buffer, sizeof(buffer), WxCode[ugly->wx[i]].name);
    2292             :       /* Handle Attributes. */
    2293           0 :       f_first = 1;
    2294           0 :       for (j = 0; j < NUM_UGLY_ATTRIB; j++) {
    2295           0 :          if (ugly->attrib[i][j] != 0) {
    2296             :             /* Fixed by GDAL */
    2297           0 :             if (ugly->f_priority[i] == 0) {
    2298           0 :                if (f_first) {
    2299           0 :                   safe_strcat (buffer, sizeof(buffer), " with ");
    2300           0 :                   f_first = 0;
    2301             :                } else {
    2302           0 :                   safe_strcat (buffer, sizeof(buffer), ", ");
    2303             :                }
    2304           0 :                safe_strcat (buffer, sizeof(buffer), WxAttrib[ugly->attrib[i][j]].name);
    2305             :             }
    2306             :          }
    2307             :       }
    2308           0 :       ugly->english[i] = (char *) malloc ((strlen (buffer) + 1) *
    2309             :                                           sizeof (char));
    2310           0 :       strcpy (ugly->english[i], buffer);
    2311             :       /* Compute a code number for wx&inten, as well as attrib. */
    2312           0 :       if (WxCode[ugly->wx[i]].number != 0) {
    2313           0 :          ugly->wx_inten[i] = 1 + (WxCode[ugly->wx[i]].number - 1) *
    2314           0 :                (sizeof (WxIntens) / sizeof (WxTable)) +
    2315           0 :                WxIntens[ugly->intens[i]].number;
    2316             :       } else {
    2317           0 :          ugly->wx_inten[i] = 0;
    2318             :       }
    2319             :       /* Compute a code number for hazards. */
    2320           0 :       for (j = 0; j < NUM_UGLY_ATTRIB; j++) {
    2321           0 :          HazCode[j] = WxAttrib[ugly->attrib[i][j]].number;
    2322           0 :          if (HazCode[j] > 250) {
    2323           0 :             HazCode[j] = 0;
    2324             :          }
    2325             :       }
    2326           0 :       for (j = 0; j < NUM_UGLY_ATTRIB - 1; j++) {
    2327           0 :          for (k = j + 1; k < NUM_UGLY_ATTRIB; k++) {
    2328           0 :             if (HazCode[j] > HazCode[k]) {
    2329           0 :                temp = HazCode[j];
    2330           0 :                HazCode[j] = HazCode[k];
    2331           0 :                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           0 :       ugly->HazCode[i] = 0;
    2338           0 :       for (j = 0; j < NUM_UGLY_ATTRIB; j++) {
    2339           0 :          ugly->HazCode[i] = (ugly->HazCode[i] * 100) + HazCode[j];
    2340             :       }
    2341             :    }
    2342           0 : }
    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             :  */
    2373           0 : 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           0 :    uChar attNum = 0;    /* piece of attribute phrase (# of , seen) */
    2378           0 :    uChar place = 0;     /* location in a word (# of : seen) */
    2379           0 :    uChar word = 0;      /* Which word in sentence (# of ^ seen) */
    2380             : 
    2381             :    /* Init first message */
    2382           0 :    ugly->SimpleCode = 0;
    2383           0 :    InitUglyString (ugly);
    2384           0 :    start = wxData;
    2385           0 :    for (cur = wxData; *cur != '\0'; cur++) {
    2386           0 :       switch (*cur) {
    2387           0 :          case '^':
    2388           0 :             *cur = '\0';
    2389           0 :             if (UglyLookUp (ugly, start, word, place, attNum) != 0) {
    2390           0 :                *cur = '^';
    2391             : #ifdef VERBOSE
    2392             :                printf ("(A) %s\n", wxData);
    2393             : #endif
    2394             : #ifdef STORE_ERRORS
    2395           0 :                reallocSprintf (&(ugly->errors), "(A) '%s'\n", wxData);
    2396             : #endif
    2397             :                /* Convert what we have to "English phrase" */
    2398           0 :                ugly->numValid = word + 1;
    2399           0 :                Ugly2English (ugly);
    2400           0 :                if (simpleVer == 1) {
    2401           0 :                   ugly->SimpleCode = NDFD_WxTable1 (ugly);
    2402           0 :                } else if (simpleVer == 2) {
    2403           0 :                   ugly->SimpleCode = NDFD_WxTable2 (ugly);
    2404           0 :                } else if (simpleVer == 3) {
    2405           0 :                   ugly->SimpleCode = NDFD_WxTable3 (ugly);
    2406             :                } else {
    2407           0 :                   ugly->SimpleCode = NDFD_WxTable4 (ugly);
    2408             :                }
    2409           0 :                return -1;
    2410             :             }
    2411           0 :             *cur = '^';
    2412           0 :             word++;
    2413             :             /* Make sure we don't start writing out of bounds. */
    2414           0 :             if (word >= NUM_UGLY_WORD) {
    2415             : #ifdef VERBOSE
    2416             :                printf ("(B) %s\n", wxData);
    2417             : #endif
    2418             : #ifdef STORE_ERRORS
    2419           0 :                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           0 :                Ugly2English (ugly);
    2426           0 :                if (simpleVer == 1) {
    2427           0 :                   ugly->SimpleCode = NDFD_WxTable1 (ugly);
    2428           0 :                } else if (simpleVer == 2) {
    2429           0 :                   ugly->SimpleCode = NDFD_WxTable2 (ugly);
    2430           0 :                } else if (simpleVer == 3) {
    2431           0 :                   ugly->SimpleCode = NDFD_WxTable3 (ugly);
    2432             :                } else {
    2433           0 :                   ugly->SimpleCode = NDFD_WxTable4 (ugly);
    2434             :                }
    2435           0 :                return -1;
    2436             :             }
    2437           0 :             place = 0;
    2438           0 :             attNum = 0;
    2439           0 :             start = cur + 1;
    2440           0 :             break;
    2441           0 :          case ':':
    2442           0 :             *cur = '\0';
    2443           0 :             if (UglyLookUp (ugly, start, word, place, attNum) != 0) {
    2444           0 :                *cur = ':';
    2445             : #ifdef VERBOSE
    2446             :                printf ("(C) %s\n", wxData);
    2447             : #endif
    2448             : #ifdef STORE_ERRORS
    2449           0 :                reallocSprintf (&(ugly->errors), "(C) '%s'\n", wxData);
    2450             : #endif
    2451             :                /* Convert what we have to "English phrase" */
    2452           0 :                ugly->numValid = word + 1;
    2453           0 :                Ugly2English (ugly);
    2454           0 :                if (simpleVer == 1) {
    2455           0 :                   ugly->SimpleCode = NDFD_WxTable1 (ugly);
    2456           0 :                } else if (simpleVer == 2) {
    2457           0 :                   ugly->SimpleCode = NDFD_WxTable2 (ugly);
    2458           0 :                } else if (simpleVer == 3) {
    2459           0 :                   ugly->SimpleCode = NDFD_WxTable3 (ugly);
    2460             :                } else {
    2461           0 :                   ugly->SimpleCode = NDFD_WxTable4 (ugly);
    2462             :                }
    2463           0 :                return -1;
    2464             :             }
    2465           0 :             *cur = ':';
    2466           0 :             place++;
    2467           0 :             attNum = 0;
    2468           0 :             start = cur + 1;
    2469           0 :             break;
    2470           0 :          case ',':
    2471           0 :             if (place == 4) {
    2472           0 :                *cur = '\0';
    2473           0 :                if (UglyLookUp (ugly, start, word, place, attNum) != 0) {
    2474           0 :                   *cur = ',';
    2475             : #ifdef VERBOSE
    2476             :                   printf ("(D) %s\n", wxData);
    2477             : #endif
    2478             : #ifdef STORE_ERRORS
    2479           0 :                   reallocSprintf (&(ugly->errors), "(D) '%s'\n", wxData);
    2480             : #endif
    2481             :                   /* Convert what we have to "English phrase" */
    2482           0 :                   ugly->numValid = word + 1;
    2483           0 :                   Ugly2English (ugly);
    2484           0 :                   if (simpleVer == 1) {
    2485           0 :                      ugly->SimpleCode = NDFD_WxTable1 (ugly);
    2486           0 :                   } else if (simpleVer == 2) {
    2487           0 :                      ugly->SimpleCode = NDFD_WxTable2 (ugly);
    2488           0 :                   } else if (simpleVer == 3) {
    2489           0 :                      ugly->SimpleCode = NDFD_WxTable3 (ugly);
    2490             :                   } else {
    2491           0 :                      ugly->SimpleCode = NDFD_WxTable4 (ugly);
    2492             :                   }
    2493           0 :                   return -1;
    2494             :                }
    2495           0 :                *cur = ',';
    2496           0 :                attNum++;
    2497           0 :                start = cur + 1;
    2498             :             }
    2499           0 :             break;
    2500           0 :          default:
    2501           0 :             break;
    2502             :       }
    2503             : /*
    2504             :       if (word == 2) {
    2505             :          return;
    2506             :       }
    2507             : */
    2508             :    }
    2509           0 :    if (start != NULL) {
    2510           0 :       if (UglyLookUp (ugly, start, word, place, attNum) != 0) {
    2511             : #ifdef VERBOSE
    2512             :          printf ("(E) '%s'\n", wxData);
    2513             : #endif
    2514             : #ifdef STORE_ERRORS
    2515           0 :          reallocSprintf (&(ugly->errors), "(E) '%s'\n", wxData);
    2516             : #endif
    2517             :          /* Convert what we have to "English phrase" */
    2518           0 :          ugly->numValid = word + 1;
    2519           0 :          Ugly2English (ugly);
    2520           0 :          if (simpleVer == 1) {
    2521           0 :             ugly->SimpleCode = NDFD_WxTable1 (ugly);
    2522           0 :          } else if (simpleVer == 2) {
    2523           0 :             ugly->SimpleCode = NDFD_WxTable2 (ugly);
    2524           0 :          } else if (simpleVer == 3) {
    2525           0 :             ugly->SimpleCode = NDFD_WxTable3 (ugly);
    2526             :          } else {
    2527           0 :             ugly->SimpleCode = NDFD_WxTable4 (ugly);
    2528             :          }
    2529           0 :          return -1;
    2530             :       }
    2531             :    }
    2532             : 
    2533           0 :    ugly->numValid = word + 1;
    2534             :    /* Convert what we have to "English phrase" */
    2535           0 :    Ugly2English (ugly);
    2536           0 :    if (simpleVer == 1) {
    2537           0 :       ugly->SimpleCode = NDFD_WxTable1 (ugly);
    2538           0 :    } else if (simpleVer == 2) {
    2539           0 :       ugly->SimpleCode = NDFD_WxTable2 (ugly);
    2540           0 :    } else if (simpleVer == 3) {
    2541           0 :       ugly->SimpleCode = NDFD_WxTable3 (ugly);
    2542             :    } else {
    2543           0 :       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           0 :    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             :  */
    2582           0 : 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           0 :    printf ("numValid %d\n", ugly->numValid);
    2588           0 :    for (i = 0; i < ugly->numValid; i++) {
    2589           0 :       if (ugly->vis[i] == VIS_UNKNOWN) {
    2590           0 :          vis = 9999;
    2591             :       } else {
    2592           0 :          vis = ugly->vis[i] / 32.;
    2593             :       }
    2594           0 :       printf ("Wx=%d, Cov=%d, inten=%d, vis=%d, attrib=%d,%d,%d,%d,%d\n",
    2595           0 :               ugly->wx[i], ugly->cover[i], ugly->intens[i],
    2596           0 :               ugly->vis[i], ugly->attrib[i][0], ugly->attrib[i][1],
    2597           0 :               ugly->attrib[i][2], ugly->attrib[i][3], ugly->attrib[i][4]);
    2598           0 :       printf ("Wx=%s, Cov=%s, intens=%s, vis=%f, attrib=%s,%s,%s,%s,%s\n",
    2599           0 :               WxCode[ugly->wx[i]].name, WxCover[ugly->cover[i]].name,
    2600           0 :               WxIntens[ugly->intens[i]].name, vis,
    2601           0 :               WxAttrib[ugly->attrib[i][0]].name,
    2602           0 :               WxAttrib[ugly->attrib[i][1]].name,
    2603           0 :               WxAttrib[ugly->attrib[i][2]].name,
    2604           0 :               WxAttrib[ugly->attrib[i][3]].name,
    2605           0 :               WxAttrib[ugly->attrib[i][4]].name);
    2606             :    }
    2607           0 :    printf ("\n");
    2608           0 : }
    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             :  */
    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

Generated by: LCOV version 1.14