METAR decoding of weather
Posted: Sat Jan 22, 2005 11:43 pm
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
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;