Created
February 13, 2022 20:34
-
-
Save LunaticMuch/275e10e11087302467d7f2faf5263944 to your computer and use it in GitHub Desktop.
Decode metar weather string
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
extension String { | |
func index(from: Int) -> Index { | |
return self.index(startIndex, offsetBy: from) | |
} | |
func substring(from: Int) -> String { | |
let fromIndex = index(from: from) | |
return String(self[fromIndex...]) | |
} | |
func substring(to: Int) -> String { | |
let toIndex = index(from: to) | |
return String(self[..<toIndex]) | |
} | |
func substring(with r: Range<Int>) -> String { | |
let startIndex = index(from: r.lowerBound) | |
let endIndex = index(from: r.upperBound) | |
return String(self[startIndex..<endIndex]) | |
} | |
} | |
// An example of a full length metar | |
let fullMetar: String = "FM2000 30015G25KT 1SM SHRA OVC15CB PROB40 2022 1/2SM TSRA +FZFG OVC008CB -RA RERA" | |
// The pattern extracts only the weather part, ie. winds, clouds, etc are discarded | |
let pattern = #"[+-]?\S{0,2}(?:RA|SN|SG|IC|PL|GR|GS|UP|FG|FU|VA|DU|SA|HZ|PY|SQ|FC|SS|SS)"# | |
let regex = try NSRegularExpression(pattern: pattern, options: []) | |
let regularExpression = try! NSRegularExpression(pattern: pattern, options: []) | |
let matchesArray = regularExpression.matches(in: fullMetar, options: [], range: NSRange(location: 0, length: fullMetar.utf16.count)) | |
for match in matchesArray { | |
for i in 0..<match.numberOfRanges { | |
let range = match.range(at: i) | |
if range.location == NSNotFound {continue} | |
print(readWeather((fullMetar as NSString).substring(with: range))) | |
} | |
} | |
// The function parses the weather string which can be either 2,3,4 or five chars | |
// It composes a strict just adding each decoded part | |
func readWeather (_ codedMetar:String) -> String { | |
var decoded: String = "" | |
switch codedMetar.count { | |
case 5: decoded += decodeWeather(codedMetar.substring(with: 0..<1)) + " " | |
decoded += decodeWeather(codedMetar.substring(with: 1..<3)) + " " | |
decoded += decodeWeather(codedMetar.substring(with: 3..<5)) | |
case 4: decoded += decodeWeather(codedMetar.substring(with: 0..<2)) + " " | |
decoded += decodeWeather(codedMetar.substring(with: 2..<4)) | |
case 3: | |
decoded += decodeWeather(codedMetar.substring(with: 0..<1)) + " " | |
decoded += decodeWeather(codedMetar.substring(with: 1..<3)) | |
case 2: | |
decoded += decodeWeather(codedMetar.substring(with: 0..<2)) | |
default: decoded = "" | |
} | |
return decoded | |
} | |
// The decoder of weather codes | |
func decodeWeather (_ code:String) -> String { | |
switch code { | |
case "VC": return "In the vicinity" | |
case "MI": return "Shallow" | |
case "PR": return "Partial" | |
case "BC": return "Patches" | |
case "DR": return "Low Drifting" | |
case "BL": return "Blowing" | |
case "SH": return "Shower" | |
case "TS": return "Thunderstorm" | |
case "FZ": return "Freezing" | |
case "DZ": return "Drizzle" | |
case "RA": return "Rain" | |
case "SN": return "Snow" | |
case "SG": return "Snow Grains" | |
case "IC": return "Ice Crystals" | |
case "PL": return "Ice Pellets" | |
case "GR": return "Hail" | |
case "GS": return "Small Hail" | |
case "UP": return "Unknown Precipitation" | |
case "BR": return "Mist" | |
case "FG": return "Fog" | |
case "FU": return "Smoke" | |
case "VA": return "Volcanic Ash" | |
case "DU": return "Widespread Dust" | |
case "SA": return "Sand" | |
case "HZ": return "Haze" | |
case "PY": return "Spray" | |
case "PO": return "Well- Developed Dust/Sand Whirls" | |
case "SQ": return "Squalls" | |
case "FC": return "Funnel Cloud Tornado Waterspout" | |
case "SS": return "Sandstorm" | |
case "SS": return "Duststorm" | |
case "RE": return "Recent" | |
case "+": return "Heavy" | |
case "-": return "Light" | |
default: return "" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment