diff --git a/metar.html b/metar.html index 28f3700..a4f56b2 100644 --- a/metar.html +++ b/metar.html @@ -105,7 +105,7 @@ 'UP': 'unknown precipitation', 'BR': 'mist', 'FG': 'fog', 'FU': 'smoke', 'VA': 'volcanic ash', 'DU': 'widespread dust', 'SA': 'sand', 'HZ': 'haze', 'PY': 'spray', 'PO': 'well-developed dust/sand whirls', 'SQ': 'squalls', - 'FC': 'funnel cloud(s)', 'SS': 'sandstorm', 'DS': 'duststorm' + 'FC': 'funnel cloud(s)', 'SS': 'sandstorm', 'DS': 'duststorm', 'TR': 'trace' }; const precipitationTypes = ['DZ', 'RA', 'SN', 'SG', 'IC', 'PL', 'GR', 'GS', 'UP']; @@ -210,11 +210,14 @@ function decodeRemarks(parts) { let decoded = ["RMK: Remarks"]; + const weatherRegex = /^([+-]|VC)?(MI|PR|BC|DR|BL|SH|TS|FZ|DZ|RA|SN|SG|IC|PL|GR|GS|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS|TR)+$/; parts.forEach(part => { if (part.startsWith('SLP')) { decoded.push(` - ${decodeSlp(part)}`); } else if (part.match(/^([A-Z]{2}\d)+$/)) { decoded.push(` - ${decodeCloudTypesRemark(part)}`); + } else if (weatherRegex.test(part)) { + decoded.push(` - ${decodeWeather(part)}`); } else if (part.match(/^(AC|CI|CC)/)) { decoded.push(` - ${part}: Cloud types and coverage details`); } else { @@ -265,7 +268,7 @@ sections.push({ raw: part, decoded: decodeWind(part) }); } else if (part.endsWith('SM') || part.match(/^\d+$/) || part.match(/^\d\/\dSM$/)) { sections.push({ raw: part, decoded: decodeVisibility(part) }); - } else if (part.match(/^([+-]|VC)?(MI|PR|BC|DR|BL|SH|TS|FZ|DZ|RA|SN|SG|IC|PL|GR|GS|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS)+$/)) { + } else if (part.match(/^([+-]|VC)?(MI|PR|BC|DR|BL|SH|TS|FZ|DZ|RA|SN|SG|IC|PL|GR|GS|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS|TR)+$/)) { sections.push({ raw: part, decoded: decodeWeather(part) }); } else if (part.match(/^(SKC|CLR|FEW|SCT|BKN|OVC)/)) { sections.push({ raw: part, decoded: decodeClouds(part) });