Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added METAR|SPECI type parsing #15

Merged
merged 3 commits into from
Feb 24, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion metar.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
(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
// http://www.unc.edu/~haines/metar.html

var TYPES = [ 'METAR', 'SPECI' ];

var CLOUDS = {
NCD: "no clouds",
SKC: "sky clear",
Expand Down Expand Up @@ -104,6 +108,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;
Expand Down Expand Up @@ -201,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
}
};

Expand Down Expand Up @@ -277,6 +293,7 @@ METAR.prototype.parseAltimeter = function() {
};

METAR.prototype.parse = function() {
this.parseType();
this.parseStation();
this.parseDate();
this.parseAuto();
Expand Down
50 changes: 50 additions & 0 deletions rvr.js
Original file line number Diff line number Diff line change
@@ -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;
}

}());
20 changes: 20 additions & 0 deletions test/parse_metar_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ 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);

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(){
var m = parseMetar("EFJY 171750Z AUTO 29007KT CAVOK 15/12 Q1006");
assert.equal("EFJY", m.station);
Expand Down Expand Up @@ -257,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);
});
});
});
78 changes: 78 additions & 0 deletions test/parse_rvr_test.js
Original file line number Diff line number Diff line change
@@ -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);
});
});