From 5e0f04cdef10e41c82091ab99206f303de016e00 Mon Sep 17 00:00:00 2001 From: Ray Hammond Date: Tue, 6 Jan 2015 20:32:48 +0000 Subject: [PATCH 1/3] Added METAR|SPECI type parsing --- metar.js | 14 ++++++++++++++ test/parse_metar_test.js | 5 +++++ 2 files changed, 19 insertions(+) diff --git a/metar.js b/metar.js index e345543..6a9f70d 100644 --- a/metar.js +++ b/metar.js @@ -4,6 +4,8 @@ // http://en.wikipedia.org/wiki/METAR // http://www.unc.edu/~haines/metar.html +var TYPES = [ 'METAR', 'SPECI' ]; + var CLOUDS = { NCD: "no clouds", SKC: "sky clear", @@ -104,6 +106,17 @@ METAR.prototype.peek = function() { return this.fields[this.i+1]; }; +METAR.prototype.parseType = function() { + var token = this.peek(); + + if (TYPES.indexOf(token) !== -1) { + this.next(); + this.result.type = this.current; + } else { + this.result.type = 'METAR'; + } +}; + METAR.prototype.parseStation = function() { this.next(); this.result.station = this.current; @@ -277,6 +290,7 @@ METAR.prototype.parseAltimeter = function() { }; METAR.prototype.parse = function() { + this.parseType(); this.parseStation(); this.parseDate(); this.parseAuto(); diff --git a/test/parse_metar_test.js b/test/parse_metar_test.js index def2e72..7464626 100644 --- a/test/parse_metar_test.js +++ b/test/parse_metar_test.js @@ -5,6 +5,11 @@ var parseMetar = require("../metar"); describe("METAR parser", function() { + it("can parse type", function(){ + var m = parseMetar("SPECI EFJY 171750Z AUTO 29007KT CAVOK 15/12 Q1006"); + assert.equal("SPECI", m.type); + }); + it("can parse station", function(){ var m = parseMetar("EFJY 171750Z AUTO 29007KT CAVOK 15/12 Q1006"); assert.equal("EFJY", m.station); From 2d90b65dee1aa524857c5d20a12131069da052a4 Mon Sep 17 00:00:00 2001 From: Ray Hammond Date: Wed, 7 Jan 2015 20:42:26 +0000 Subject: [PATCH 2/3] Added extra tests for types --- test/parse_metar_test.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/parse_metar_test.js b/test/parse_metar_test.js index 7464626..7ab253c 100644 --- a/test/parse_metar_test.js +++ b/test/parse_metar_test.js @@ -8,6 +8,12 @@ describe("METAR parser", function() { it("can parse type", function(){ var m = parseMetar("SPECI EFJY 171750Z AUTO 29007KT CAVOK 15/12 Q1006"); assert.equal("SPECI", m.type); + + m = parseMetar("METAR EFJY 171750Z AUTO 29007KT CAVOK 15/12 Q1006"); + assert.equal("METAR", m.type); + + m = parseMetar("EFJY 171750Z AUTO 29007KT CAVOK 15/12 Q1006"); + assert.equal("METAR", m.type); }); it("can parse station", function(){ From 61f92b6bfc3be754c541149996ef23be4ad678d8 Mon Sep 17 00:00:00 2001 From: Ray Hammond Date: Wed, 7 Jan 2015 22:44:01 +0000 Subject: [PATCH 3/3] Added RVR parser and tests --- metar.js | 5 ++- rvr.js | 50 ++++++++++++++++++++++++++ test/parse_metar_test.js | 9 +++++ test/parse_rvr_test.js | 78 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 rvr.js create mode 100644 test/parse_rvr_test.js diff --git a/metar.js b/metar.js index 6a9f70d..c2eb0ba 100644 --- a/metar.js +++ b/metar.js @@ -1,4 +1,6 @@ (function() { + +var parseRVR = require("./rvr"); // http://www.met.tamu.edu/class/metar/metar-pg10-sky.html // https://ww8.fltplan.com/AreaForecast/abbreviations.htm // http://en.wikipedia.org/wiki/METAR @@ -214,7 +216,8 @@ METAR.prototype.parseRunwayVisibility = function() { if (this.result.cavok) return; if (this.peek().match(/^R[0-9]+/)) { this.next(); - // TODO: Parse it! + this.result.rvr = parseRVR(this.current); + // TODO: peek is more than one RVR in METAR and parse } }; diff --git a/rvr.js b/rvr.js new file mode 100644 index 0000000..57f47f8 --- /dev/null +++ b/rvr.js @@ -0,0 +1,50 @@ +(function() { + +var re = /(R\d{2})([L|R|C])?(\/)([P|M])?(\d+)(?:([V])([P|M])?(\d+))?([N|U|D])?(FT)?/g; + +function RVR(rvrString) { + this.result = {}; + this.rvrString = rvrString; + this.parse(); +} + +RVR.prototype.parse = function() { + + var matches; + + while ((matches = re.exec(this.rvrString)) != null) { + + if (matches.index === re.lastIndex) { + re.lastIndex++; + } + + this.result = { + "runway": matches[1], + "direction": matches[2], + "seperator": matches[3], + "minIndicator": matches[4], + "minValue": matches[5], + "variableIndicator": matches[6], + "maxIndicator": matches[7], + "maxValue": matches[8], + "trend": matches[9], + "unitsOfMeasure": matches[10] + } + } + +}; + +function parseRVR(rvrString) { + var m = new RVR(rvrString); + m.parse(); + return m.result; +} + +if (typeof module !== "undefined") { + module.exports = parseRVR; +} +else if (typeof window !== "undefined") { + window.parseMETAR = parseMETAR; +} + +}()); diff --git a/test/parse_metar_test.js b/test/parse_metar_test.js index 7ab253c..c28c2a6 100644 --- a/test/parse_metar_test.js +++ b/test/parse_metar_test.js @@ -268,4 +268,13 @@ describe("METAR parser", function() { }); + describe("for rvr", function() { + it("runway can be parsed", function() { + var m = parseMetar("EFJY 082120Z AUTO 00000KT 9999 R30/1300U BKN083 BKN101 15/12 Q1013"); + assert("R30", m.rvr.runway); + assert("/", m.rvr.seperator); + assert("1300", m.rvr.minValue); + assert("U", m.rvr.trend); + }); + }); }); diff --git a/test/parse_rvr_test.js b/test/parse_rvr_test.js new file mode 100644 index 0000000..a796482 --- /dev/null +++ b/test/parse_rvr_test.js @@ -0,0 +1,78 @@ +/*global it:true, describe:true */ +var assert = require("assert"); +var parseRVR = require("../rvr"); + +describe("RVR parser", function() { + + it("can handle null", function() { + var m = parseRVR(null); + assert.equal(null, m.runway); + }); + + it("can handle empty string", function() { + var m = parseRVR(""); + assert.equal(null, m.runway); + }); + + it("can parse runway", function() { + var m = parseRVR("R34/0300U"); + assert.equal("R34", m.runway); + }); + + it("can parse runway approach direction Left", function() { + var m = parseRVR("R34L/0300U"); + assert.equal("L", m.direction); + }); + + it("can parse runway approach direction Right", function() { + var m = parseRVR("R34R/0300U"); + assert.equal("R", m.direction); + }); + + it("can parse runway approach direction Center", function() { + var m = parseRVR("R34C/0300U"); + assert.equal("C", m.direction); + }); + + it("can parse runway seperator", function() { + var m = parseRVR("R34L/0300U"); + assert.equal("/", m.seperator); + }); + + it("can parse runway min indicator", function() { + var m = parseRVR("R34L/P0300U"); + assert.equal("P", m.minIndicator); + }); + + it("can parse runway min value (non variable)", function() { + var m = parseRVR("R34L/0300U"); + assert.equal("0300", m.minValue); + }); + + it("can parse runway min/max and variable value", function() { + var m = parseRVR("R34L/M0600V1000FT"); + assert.equal("0600", m.minValue); + assert.equal("V", m.variableIndicator); + assert.equal("1000", m.maxValue); + }); + + it("can parse runway trend D", function() { + var m = parseRVR("R34L/0300D"); + assert.equal("D", m.trend); + }); + + it("can parse runway trend N", function() { + var m = parseRVR("R34L/0300N"); + assert.equal("N", m.trend); + }); + + it("can parse runway trend U", function() { + var m = parseRVR("R34L/0300U"); + assert.equal("U", m.trend); + }); + + it("can parse units of measure", function() { + var m = parseRVR("R34L/M0600V1000FT"); + assert.equal("FT", m.unitsOfMeasure); + }); +});