UNPKG

metar-plot

Version:
281 lines (280 loc) 8.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseAltimeter = exports.parseWind = exports.parseClouds = exports.parseVisibility = exports.parseWeather = exports.parseTempNA = exports.parseTempInternation = exports.parseAuto = exports.parseCavok = exports.parseDate = exports.parseStation = exports.parseMetar = exports.METAR = void 0; var Weather_1 = require("./parts/Weather"); var Cloud_1 = require("./parts/Cloud"); var Wind_1 = require("./parts/Wind"); //Meassage types var TYPES = ["METAR", "SPECI"]; //Metar Object var METAR = /** @class */ (function () { /** * Extracted Metar data in a human readable format. * @param metarString raw metar string if provided station and time will be ignored and replaced with the content in the raw METAR * @param station staion name for instance creation * @param time time for instance creation */ function METAR(metarString, station, time) { //Wind speed, direction and unit this.wind = new Wind_1.Wind(); //List of weather conditions reported this.weather = new Array(); //List of Cloud observations this.clouds = new Array(); this.station = station !== null && station !== void 0 ? station : "----"; this.time = time !== null && time !== void 0 ? time : new Date(); if (metarString != null) { parseMetar(metarString, this); } } return METAR; }()); exports.METAR = METAR; /** * Parses a raw metar and binds or creates a METAR object * @param metarString Raw METAR string * @param ref Reference to a METAR object. This objects contents will be shallow replaced with the Raw metars values. * Meaning values will be updated or added but not removed. * @returns */ function parseMetar(metarString, ref) { var station = parseStation(metarString); var time = parseDate(metarString); if (ref != null) { ref.station = station; ref.time = time; } else { ref = new METAR(undefined, station, time); } //Parse Auto ref.auto = parseAuto(metarString); //Parse Wind ref.wind = parseWind(metarString); //Parse CAVOK ref.cavok = parseCavok(metarString); //Parse Visablility ref.visibility = parseVisibility(metarString); //Parse Runway VIS //TODO //Parse Weather ref.weather = parseWeather(metarString); //Parse Clouds ref.clouds = parseClouds(metarString); //Parse Temp Point Internations var temps_int = parseTempInternation(metarString); if (temps_int != null) { ref.temperature = temps_int[0]; ref.dewpoint = temps_int[1]; } //Parse Temp North american Will overwirte international since it is more precise var temps_ne = parseTempNA(metarString); if (temps_ne != null) { ref.temperature = temps_ne[0]; ref.dewpoint = temps_ne[1]; } //Parse Altimeter ref.altimeter = parseAltimeter(metarString); return ref; } exports.parseMetar = parseMetar; /** * Parses the station name form the metar * @param metar raw metar * @returns */ function parseStation(metar) { var re = /^(METAR\s)?([A-Z]{1,4})\s/g; var matches = re.exec(metar); if (matches != null) { return matches[2]; } else { throw new Error("Station could not be found invalid metar"); } } exports.parseStation = parseStation; /** * Parse Date object from metar. * NOTE: Raw metar data does not contain month or year data. So this function assumes this metar was created in the current month and current year * @param metar raw metar * @returns */ function parseDate(metar) { var re = /([\d]{2})([\d]{2})([\d]{2})Z/g; var matches = re.exec(metar); if (matches != null) { var d = new Date(); d.setUTCDate(parseInt(matches[1])); d.setUTCHours(parseInt(matches[2])); d.setUTCMinutes(parseInt(matches[3])); d.setUTCSeconds(0); d.setUTCMilliseconds(0); return d; } else { throw new Error("Failed to parse Date"); } } exports.parseDate = parseDate; /** * Parses for CAVOK (Ceiling and visabiliy OK) * @param metar raw metar * @returns */ function parseCavok(metar) { var re = /\sCAVOK\s/g; return metar.match(re) != null ? true : false; } exports.parseCavok = parseCavok; /** * Parses for Automation * @param metar raw metar * @returns */ function parseAuto(metar) { var re = /\s(AUTO)?(AO1)?(AO2)?\s/g; return metar.match(re) != null ? true : false; } exports.parseAuto = parseAuto; /** * Parse international temp dewp point format. * @param metar raw metar * @returns */ function parseTempInternation(metar) { var re = /\s(M)?(\d{2})\/(M)?(\d{2})\s/g; var matches = re.exec(metar); if (matches != null) { var temp = parseInt(matches[2]) * (matches[1] == null ? 1 : -1); var dew_point = parseInt(matches[4]) * (matches[3] == null ? 1 : -1); return [temp, dew_point]; } } exports.parseTempInternation = parseTempInternation; /** * Parse North American temp dew point format * @param metar raw metar * @returns */ function parseTempNA(metar) { var re = /(T)(\d{1})(\d{2})(\d{1})(\d{1})(\d{2})(\d{1})/g; var matches = re.exec(metar); if (matches != null) { var temp = parseFloat(matches[3] + "." + matches[4]) * (matches[2] === "0" ? 1 : -1); var dew_point = parseFloat(matches[6] + "." + matches[7]) * (matches[5] === "0" ? 1 : -1); return [temp, dew_point]; } } exports.parseTempNA = parseTempNA; /** * Parse Weather items * @param metar raw metar * @returns */ function parseWeather(metar) { var obs_keys = Object.keys(Weather_1.WEATHER).join('|').replace(/\+/g, "\\+"); var re = new RegExp("\\s?(" + obs_keys + ")\\s", 'g'); var matches = metar.match(re); if (matches != null) { return matches.map(function (match) { console.log(match); var key = match.trim(); return { abbreviation: key, meaning: Weather_1.WEATHER[key].text }; }); } else { return new Array(); } } exports.parseWeather = parseWeather; /** * Parse visability * @param metar raw metar * @returns */ function parseVisibility(metar) { var re = /\s([0-9]{1,2})?\s?([0-9]{1}\/[0-9]{1})?(SM)\s|\s([0-9]{1,4})\s/g; if (metar.match(re)) { var vis_parts = re.exec(metar); if (vis_parts != null) { var meters = vis_parts[4]; var miles = vis_parts[1]; var frac_miles = vis_parts[2]; //Metric case ex: 1000, 9999 if (meters != null) { return parseInt(meters); } //whole miles case ex: 1SM 10SM else if (frac_miles != null) { var total = 0.0; if (miles != null) { total += parseFloat(miles); } total += parseFloat(eval(frac_miles)); return total * 1609.34; } //factional miles case "1 1/2SM" "1/4SM" else { return parseInt(miles) * 1609.34; } } } return undefined; } exports.parseVisibility = parseVisibility; /** * Parse cloud coverages * @param metarString raw metar * @returns */ function parseClouds(metarString) { var _a; var re = /(NCD|SKC|CLR|NSC|FEW|SCT|BKN|OVC|VV)(\d{3})/g; var clouds = new Array(); var matches; while ((matches = re.exec(metarString)) != null) { var cloud = { abbreviation: matches[1], meaning: (_a = Cloud_1.CLOUDS[matches[1]]) === null || _a === void 0 ? void 0 : _a.text, altitude: parseInt(matches[2]) * 100 }; clouds.push(cloud); } return clouds; } exports.parseClouds = parseClouds; /** * Parse wind data * @param metar raw metar * @returns */ function parseWind(metar) { var wind = new Wind_1.Wind(); var re = /\s(\d{3})(\d{2})(G)?(\d{2})?(KT|MPS)\s/g; var matches = re.exec(metar); if (matches != null) { wind.direction = parseInt(matches[1]); wind.speed = parseInt(matches[2]); wind.unit = matches[5]; } return wind; } exports.parseWind = parseWind; function parseAltimeter(metar) { var re = /(A|Q)(\d{2})(\d{2})/g; var matches = re.exec(metar); if (matches != null) { if (matches[1] === "Q") { var pressure = parseFloat(matches[2] + matches[3]); return parseFloat((pressure * 0.029529).toFixed(2)); } else { return parseFloat(matches[2] + "." + matches[3]); } } } exports.parseAltimeter = parseAltimeter;