feat: Add weather phenomenon decoding to METAR parser
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
+60
@@ -89,6 +89,66 @@
|
|||||||
return `${code}: Visibility ${vis} statute miles`;
|
return `${code}: Visibility ${vis} statute miles`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function decodeWeather(code) {
|
||||||
|
const originalCode = code;
|
||||||
|
const intensityMap = {
|
||||||
|
'-': 'Light ',
|
||||||
|
'+': 'Heavy '
|
||||||
|
};
|
||||||
|
const descriptorMap = {
|
||||||
|
'MI': 'Shallow ', 'PR': 'Partial ', 'BC': 'Patches of ', 'DR': 'Low drifting ',
|
||||||
|
'BL': 'Blowing ', 'SH': 'Showers of ', 'TS': 'Thunderstorm with ', 'FZ': 'Freezing '
|
||||||
|
};
|
||||||
|
const weatherMap = {
|
||||||
|
'DZ': 'drizzle', 'RA': 'rain', 'SN': 'snow', 'SG': 'snow grains',
|
||||||
|
'IC': 'ice crystals', 'PL': 'ice pellets', 'GR': 'hail', 'GS': 'small hail and/or snow pellets',
|
||||||
|
'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'
|
||||||
|
};
|
||||||
|
const precipitationTypes = ['DZ', 'RA', 'SN', 'SG', 'IC', 'PL', 'GR', 'GS', 'UP'];
|
||||||
|
|
||||||
|
let decoding = '';
|
||||||
|
let codeToParse = code;
|
||||||
|
|
||||||
|
if (codeToParse.startsWith('-') || codeToParse.startsWith('+')) {
|
||||||
|
decoding += intensityMap[codeToParse[0]];
|
||||||
|
codeToParse = codeToParse.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let vicinity = '';
|
||||||
|
if (codeToParse.startsWith('VC')) {
|
||||||
|
vicinity = ' in the vicinity';
|
||||||
|
codeToParse = codeToParse.substring(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
const chunks = codeToParse.match(/.{1,2}/g) || [];
|
||||||
|
let decodedChunks = [];
|
||||||
|
let hasPrecipitation = false;
|
||||||
|
|
||||||
|
chunks.forEach(chunk => {
|
||||||
|
if (descriptorMap[chunk]) {
|
||||||
|
decodedChunks.push(descriptorMap[chunk]);
|
||||||
|
} else if (weatherMap[chunk]) {
|
||||||
|
decodedChunks.push(weatherMap[chunk]);
|
||||||
|
} else {
|
||||||
|
decodedChunks.push(`unknown (${chunk})`);
|
||||||
|
}
|
||||||
|
if (precipitationTypes.includes(chunk)) {
|
||||||
|
hasPrecipitation = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ((codeToParse.includes('TS') || codeToParse.includes('SH')) && !hasPrecipitation) {
|
||||||
|
decodedChunks.push('rain');
|
||||||
|
}
|
||||||
|
|
||||||
|
decoding += decodedChunks.join('');
|
||||||
|
|
||||||
|
return `${originalCode}: ${decoding.trim()}${vicinity}`;
|
||||||
|
}
|
||||||
|
|
||||||
function decodeClouds(code) {
|
function decodeClouds(code) {
|
||||||
const coverMap = {
|
const coverMap = {
|
||||||
'SKC': 'Sky clear',
|
'SKC': 'Sky clear',
|
||||||
|
|||||||
Reference in New Issue
Block a user