diff --git a/metar.html b/metar.html index 26d0cb3..82eac47 100644 --- a/metar.html +++ b/metar.html @@ -120,12 +120,41 @@ const hpa = (pressure < 500 ? 1000 : 900) + (pressure / 10); return `SLP${pressure}: Sea-level pressure ${hpa.toFixed(1)} hPa`; } + + function decodeCloudTypesRemark(code) { + const cloudTypes = { + 'CI': 'Cirrus', + 'CC': 'Cirrocumulus', + 'CS': 'Cirrostratus', + 'AC': 'Altocumulus', + 'AS': 'Altostratus', + 'NS': 'Nimbostratus', + 'SC': 'Stratocumulus', + 'ST': 'Stratus', + 'CU': 'Cumulus', + 'CB': 'Cumulonimbus' + }; + + let decodedParts = []; + const matches = code.matchAll(/([A-Z]{2})(\d)/g); + + for (const match of matches) { + const cloudCode = match[1]; + const oktas = match[2]; + const cloudName = cloudTypes[cloudCode] || `Unknown cloud type (${cloudCode})`; + decodedParts.push(`${oktas}/8 ${cloudName}`); + } + + return `${code}: ${decodedParts.join(', ')}`; + } function decodeRemarks(parts) { let decoded = ["RMK: Remarks"]; 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 (part.match(/^(AC|CI|CC)/)) { decoded.push(` - ${part}: Cloud types and coverage details`); } else {