fix: Improve METAR remark decoding for directional and cloud-related remarks
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
+52
-2
@@ -260,7 +260,7 @@
|
|||||||
'CB': 'Cumulonimbus'
|
'CB': 'Cumulonimbus'
|
||||||
};
|
};
|
||||||
const specialRemarks = {
|
const specialRemarks = {
|
||||||
'FROIN': 'Frost on indicator',
|
'FROIN': 'Frontal passage in vicinity',
|
||||||
'CONTRAILS': 'Contrails observed',
|
'CONTRAILS': 'Contrails observed',
|
||||||
'VIRGA': 'Virga (precipitation not reaching the ground)',
|
'VIRGA': 'Virga (precipitation not reaching the ground)',
|
||||||
'HALO': 'Halo phenomenon observed'
|
'HALO': 'Halo phenomenon observed'
|
||||||
@@ -282,6 +282,11 @@
|
|||||||
const location = parts[i+1];
|
const location = parts[i+1];
|
||||||
decoded.push(` - VIA ${location}: relayed via ${location}`);
|
decoded.push(` - VIA ${location}: relayed via ${location}`);
|
||||||
i++; // Consume location
|
i++; // Consume location
|
||||||
|
} else if (part === 'VIS' && i + 2 < parts.length) {
|
||||||
|
const direction = parts[i+1];
|
||||||
|
const distance = parts[i+2];
|
||||||
|
decoded.push(` - VIS ${direction} ${distance}: Sector visibility to the ${direction} of ${distance} statute miles`);
|
||||||
|
i += 2;
|
||||||
} else if (part === 'VIRGA' && i + 1 < parts.length && parts[i+1] === 'ALQDS') {
|
} else if (part === 'VIRGA' && i + 1 < parts.length && parts[i+1] === 'ALQDS') {
|
||||||
decoded.push(` - VIRGA ALQDS: Virga in all quadrants`);
|
decoded.push(` - VIRGA ALQDS: Virga in all quadrants`);
|
||||||
i++; // Consume ALQDS
|
i++; // Consume ALQDS
|
||||||
@@ -289,6 +294,16 @@
|
|||||||
const direction = directions[parts[i+1]];
|
const direction = directions[parts[i+1]];
|
||||||
decoded.push(` - VIRGA ${parts[i+1]}: Virga to the ${direction.toLowerCase()}`);
|
decoded.push(` - VIRGA ${parts[i+1]}: Virga to the ${direction.toLowerCase()}`);
|
||||||
i++; // Consume direction part
|
i++; // Consume direction part
|
||||||
|
} else if (part === 'TCU' && i + 1 < parts.length && parts[i+1] === 'ASOCTD') {
|
||||||
|
let remark = ' - TCU ASOCTD: Towering cumulus associated';
|
||||||
|
let consumed = 1;
|
||||||
|
if (i + 2 < parts.length && directions[parts[i+2]]) {
|
||||||
|
const direction = directions[parts[i+2]];
|
||||||
|
remark += ` to the ${direction.toLowerCase()}`;
|
||||||
|
consumed = 2;
|
||||||
|
}
|
||||||
|
decoded.push(remark);
|
||||||
|
i += consumed;
|
||||||
} else if (part === 'TCU' && i + 1 < parts.length && parts[i+1] === 'ALQDS') {
|
} else if (part === 'TCU' && i + 1 < parts.length && parts[i+1] === 'ALQDS') {
|
||||||
decoded.push(` - TCU ALQDS: Towering cumulus in all quadrants`);
|
decoded.push(` - TCU ALQDS: Towering cumulus in all quadrants`);
|
||||||
i++; // Consume ALQDS
|
i++; // Consume ALQDS
|
||||||
@@ -319,6 +334,10 @@
|
|||||||
if (i + 3 < parts.length && parts[i+2] === '/' && parts[i+3] === 'HALO') {
|
if (i + 3 < parts.length && parts[i+2] === '/' && parts[i+3] === 'HALO') {
|
||||||
remark = ` - ${part} ASOCTD / HALO: ${cloudName} associated with Halo phenomenon`;
|
remark = ` - ${part} ASOCTD / HALO: ${cloudName} associated with Halo phenomenon`;
|
||||||
consumed = 3;
|
consumed = 3;
|
||||||
|
} else if (i + 2 < parts.length && directions[parts[i+2]]) {
|
||||||
|
const direction = directions[parts[i+2]];
|
||||||
|
remark += ` to the ${direction.toLowerCase()}`;
|
||||||
|
consumed = 2;
|
||||||
}
|
}
|
||||||
decoded.push(remark);
|
decoded.push(remark);
|
||||||
i += consumed;
|
i += consumed;
|
||||||
@@ -326,6 +345,16 @@
|
|||||||
const cloudName = cloudTypes[part];
|
const cloudName = cloudTypes[part];
|
||||||
decoded.push(` - ${part} ALQDS: ${cloudName} in all quadrants`);
|
decoded.push(` - ${part} ALQDS: ${cloudName} in all quadrants`);
|
||||||
i++; // Consume ALQDS
|
i++; // Consume ALQDS
|
||||||
|
} else if (cloudTypes[part] && i + 1 < parts.length && directions[parts[i+1]]) {
|
||||||
|
const cloudName = cloudTypes[part];
|
||||||
|
let remark = ` - ${part} ${parts[i+1]}: ${cloudName} to the ${directions[parts[i+1]].toLowerCase()}`;
|
||||||
|
let consumed = 1;
|
||||||
|
if (i + 2 < parts.length && parts[i+2] === 'MOV' && i + 3 < parts.length && directions[parts[i+3]]) {
|
||||||
|
remark += `, moving ${directions[parts[i+3]].toLowerCase()}`;
|
||||||
|
consumed = 3;
|
||||||
|
}
|
||||||
|
decoded.push(remark);
|
||||||
|
i += consumed;
|
||||||
} else if (specialRemarks[part]) {
|
} else if (specialRemarks[part]) {
|
||||||
decoded.push(` - ${part}: ${specialRemarks[part]}`);
|
decoded.push(` - ${part}: ${specialRemarks[part]}`);
|
||||||
} else if (cloudTypes[part] && i + 1 < parts.length && parts[i + 1] === 'TR') {
|
} else if (cloudTypes[part] && i + 1 < parts.length && parts[i + 1] === 'TR') {
|
||||||
@@ -335,7 +364,28 @@
|
|||||||
} else if (weatherRegex.test(part)) {
|
} else if (weatherRegex.test(part)) {
|
||||||
decoded.push(` - ${decodeWeather(part, metarString)}`);
|
decoded.push(` - ${decodeWeather(part, metarString)}`);
|
||||||
} else if (part.match(/^(AC|CI|CC)/)) {
|
} else if (part.match(/^(AC|CI|CC)/)) {
|
||||||
decoded.push(` - ${part}: Cloud types and coverage details`);
|
// This is a cloud-like remark, e.g. ACC for Altocumulus Castellanus
|
||||||
|
// It can have modifiers like other clouds.
|
||||||
|
const cloudName = cloudTypes[part] || part; // part will be ACC
|
||||||
|
let remark = ` - ${cloudName}: Cloud types and coverage details`;
|
||||||
|
let consumed = 0;
|
||||||
|
|
||||||
|
if (i + 1 < parts.length && parts[i+1] === 'TR') {
|
||||||
|
remark = ` - ${cloudName} TR: ${cloudName} clouds are translucent (thin)`;
|
||||||
|
consumed = 1;
|
||||||
|
} else if (i + 1 < parts.length && parts[i+1] === 'ASOCTD') {
|
||||||
|
remark = ` - ${cloudName} ASOCTD: ${cloudName} associated`;
|
||||||
|
consumed = 1;
|
||||||
|
if (i + 2 < parts.length && directions[parts[i+2]]) {
|
||||||
|
remark += ` to the ${directions[parts[i+2]].toLowerCase()}`;
|
||||||
|
consumed = 2;
|
||||||
|
}
|
||||||
|
} else if (i + 1 < parts.length && directions[parts[i+1]]) {
|
||||||
|
remark = ` - ${cloudName} ${parts[i+1]}: ${cloudName} to the ${directions[parts[i+1]].toLowerCase()}`;
|
||||||
|
consumed = 1;
|
||||||
|
}
|
||||||
|
decoded.push(remark);
|
||||||
|
i += consumed;
|
||||||
} else if (part === '/') {
|
} else if (part === '/') {
|
||||||
// separator, ignore
|
// separator, ignore
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user