METAR decoding of weather

This is the place to get help with Digital Atmosphere, suggest improvements, and get tips.
Post Reply
Tim Vasquez
Administrator
Posts: 534
Joined: Sat Nov 22, 2003 10:47 pm

METAR decoding of weather

Post by Tim Vasquez »

I thought I'd share the METAR algorithm for decoding weather & obstructions to vision so that you all can help make Digital Atmosphere the best it can be.

Basically each element shown in quotes after "pos(" is what must appear in the weather/precipitation group. It maps to the WMO ww code shown at the end (i.e. HZ maps to ww=5). Code at the end gets higher priority, thus while there may be an SN in BLSN, and it initially gets mapped incorrectly, it is discarded later in the algorithm when BLSN is found.

Some references:
http://www.crh.noaa.gov/arx/wx.tbl.html - METAR weather codes
http://www.jodc.go.jp/data_format/weath ... ml#wmo4677 - ww code (Present Weather WMO Code 4677)

Note there is no ww for things like volcanic ash (VA) and spray (PY), so these are discarded.

If you have suggestions or comments or see something missing, feel free to speak out.

Tim

Code: Select all

      if (pos('UP',tempclip) <> 0) then    surface.weather := 1;
      if (pos('HZ',tempclip) <> 0) then    surface.weather := 5;
      if (pos('BR',tempclip) <> 0) then    surface.weather := 10;
      if (pos('FG',tempclip) <> 0) then    surface.weather := 45;
      if (pos('FU',tempclip) <> 0) then    surface.weather := 4;
      if (pos('SA',tempclip) <> 0) then    surface.weather := 7;
      if (pos('DU',tempclip) <> 0) then    surface.weather := 6;
      if (pos('SQ',tempclip) <> 0) then    surface.weather := 18;
      if (pos('SS',tempclip) <> 0) then    surface.weather := 34;
      if (pos('DS',tempclip) <> 0) then    surface.weather := 31;
      if (pos('PO',tempclip) <> 0) then    surface.weather := 8;
      if (pos('FC',tempclip) <> 0) then    surface.weather := 19;

      // TEST FOR MINOR WORDS FIRST
      if (pos('FZFG',tempclip) <> 0) then    surface.weather := 49;
      if (pos('SG',tempclip) <> 0) then    surface.weather := 77;
      if (pos('DZ',tempclip) <> 0) then    surface.weather := 53;
      if (pos('-DZ',tempclip) <> 0) then   surface.weather := 51;
      if (pos('RA',tempclip) <> 0) then    surface.weather := 63;
      if (pos('-RA',tempclip) <> 0) then   surface.weather := 61;
      if (pos('SN',tempclip) <> 0) then    surface.weather := 73;
      if (pos('-SN',tempclip) <> 0) then   surface.weather := 71;
      if (pos('IC',tempclip) <> 0) then    surface.weather := 76;
      if (pos('PE',tempclip) <> 0) then    surface.weather := 79;
      if (pos('PL',tempclip) <> 0) then    surface.weather := 79;
      if (pos('GR',tempclip) <> 0) then    surface.weather := 77;
      if (pos('GS',tempclip) <> 0) then    surface.weather := 87;

      // COMPOUND WORDS MUST BE PROCESSED AFTERWARD TO AVOID
      // FRAGMENT DETECTIONS
      if (pos('BLSN',tempclip) <> 0) then   surface.weather := 38;
      if (pos('-BLSN',tempclip) <> 0) then  surface.weather := 38;
      if (pos('SHRA',tempclip) <> 0) then   surface.weather := 81;
      if (pos('-SHRA',tempclip) <> 0) then  surface.weather := 80;
      if (pos('SHSN',tempclip) <> 0) then   surface.weather := 86;
      if (pos('-SHSN',tempclip) <> 0) then  surface.weather := 85;
      if (pos('FZDZ',tempclip) <> 0) then   surface.weather := 57;
      if (pos('-FZDZ',tempclip) <> 0) then  surface.weather := 56;
      if (pos('FZRA',tempclip) <> 0) then   surface.weather := 67;
      if (pos('-FZRA',tempclip) <> 0) then  surface.weather := 66;
      if (pos('RASN',tempclip) <> 0) then   surface.weather := 69;
      if (pos('-RASN',tempclip) <> 0) then  surface.weather := 68;
      if (pos('DRSN',tempclip) <> 0) then   surface.weather := 36;
      if (pos('TS',tempclip) <> 0) then     surface.weather := 17;
      if (pos('TSRA',tempclip) <> 0) then   surface.weather := 92;
      if (pos('-TSRA',tempclip) <> 0) then  surface.weather := 91;
      if (pos('TSSN',tempclip) <> 0) then   surface.weather := 94;
      if (pos('-TSSN',tempclip) <> 0) then  surface.weather := 93;
      if (pos('TSGR',tempclip) <> 0) then   surface.weather := 96;

      // HEAVY STUFF, SINCE IT IS RARE, ALWAYS TAKES THE CAKE
      // Test simple words FIRST
      if (pos('+DZ',tempclip) <> 0) then   surface.weather := 55;
      if (pos('+RA',tempclip) <> 0) then   surface.weather := 65;
      if (pos('+SN',tempclip) <> 0) then   surface.weather := 75;
      // Test for longer words last
      if (pos('+BLSN',tempclip) <> 0) then  surface.weather := 39;
      if (pos('+SHRA',tempclip) <> 0) then  surface.weather := 82;
      if (pos('+SHSN',tempclip) <> 0) then  surface.weather := 87;
      if (pos('+FZDZ',tempclip) <> 0) then  surface.weather := 57;
      if (pos('+FZRA',tempclip) <> 0) then  surface.weather := 67;
      if (pos('+RASN',tempclip) <> 0) then  surface.weather := 69;
      if (pos('+TSRA',tempclip) <> 0) then  surface.weather := 97;
      if (pos('+TSSN',tempclip) <> 0) then  surface.weather := 97;
      if (pos('+TSGR',tempclip) <> 0) then  surface.weather := 99;

      // TEST FOR RECENT WEATHER LAST
      if (pos('REDZ',tempclip) <> 0) then  surface.weather := 20;
      if (pos('RERA',tempclip) <> 0) then  surface.weather := 21;
      if (pos('RESN',tempclip) <> 0) then  surface.weather := 22;
      if (pos('RERASN',tempclip) <> 0) then  surface.weather := 23;
      if (pos('REFZ',tempclip) <> 0) then  surface.weather := 24;
      if (pos('RESH',tempclip) <> 0) then  surface.weather := 25;
      if (pos('RESHRA',tempclip) <> 0) then  surface.weather := 25;
      if (pos('RESHSN',tempclip) <> 0) then  surface.weather := 26;
      if (pos('REGR',tempclip) <> 0) then  surface.weather := 27;
      if (pos('REFG',tempclip) <> 0) then  surface.weather := 28;
      if (pos('RETS',tempclip) <> 0) then  surface.weather := 29;


----- IF TEMPERATURE IS BELOW FREEZING AND LIQUID PRECIP
----- IS BEING REPORTED, FORCE THE WW AS FOLLOWS:
-----  (I1 IS THE WW THAT WE HAVE FOUND SO FAR)
              if ((i1 >= 50) and (i1 <= 51)) then surface.weather := 56;
              if ((i1 >= 52) and (i1 <= 55)) then surface.weather := 57;
              if ((i1 >= 60) and (i1 <= 61)) then surface.weather := 66;
              if ((i1 >= 62) and (i1 <= 65)) then surface.weather := 67;
Post Reply