diff --git a/public_html/index.html b/public_html/index.html
index 6be1b20c3..930f6e4c8 100644
--- a/public_html/index.html
+++ b/public_html/index.html
@@ -116,6 +116,10 @@
Site Position and Range Rings
diff --git a/public_html/layers.js b/public_html/layers.js
index 2062ba7c9..dac83aeba 100644
--- a/public_html/layers.js
+++ b/public_html/layers.js
@@ -267,3 +267,82 @@ function createBaseLayers() {
return layers;
}
+
+function createMetarLayer() {
+ var metarTileGrid = ol.tilegrid.createXYZ({ minZoom: 3, maxZoom: 16 });
+
+ var metarSource = new ol.source.Vector({
+ // The API doesn't support CORS, so we have to use JSONP with a custom loader
+ loader: function (extent, resolution, projection, success, failure) {
+ var lonLat = ol.proj.transformExtent(extent, 'EPSG:3857', 'EPSG:4326');
+ var url = 'https://www.aviationweather.gov/cgi-bin/json/MetarJSON.php';
+ $.ajax({
+ url: url,
+ data: {
+ filter: 'prior',
+ density: 0,
+ date: new Date().toISOString().replace(/\D/g, '').slice(0, 12),
+ bbox: lonLat.join(','),
+ zoom: metarTileGrid.getZForResolution(resolution) - 1
+ },
+ dataType: 'jsonp',
+ jsonpCallback: 'metarCallback',
+ success: metarCallback(extent, projection, success, failure)
+ });
+ },
+ strategy: ol.loadingstrategy.bbox,
+ attributions: 'METAR courtesy of
Aviation Weather Center'
+ });
+
+ var metarCallback = function (extent, projection, success, failure) {
+ return function (data) {
+ var format = new ol.format.GeoJSON();
+ var features = format.readFeatures(data, { extent: extent, featureProjection: projection });
+ metarSource.addFeatures(features);
+ if (success !== undefined) {
+ success(features);
+ }
+ }
+ };
+
+ var metar = new ol.layer.Vector({
+ name: 'metar',
+ type: 'overlay',
+ title: 'METAR',
+ opacity: 0.8,
+ visible: false,
+ source: metarSource,
+ style: function style(feature) {
+ var cat = feature.get('fltcat');
+ var color = '#666';
+ if (cat === 'VFR') {
+ color = '#00AB42'
+ } else if (cat === 'MVFR') {
+ color = '#0016E8'
+ } else if (cat === 'IFR') {
+ color = '#FF0007'
+ } else if (cat === 'LIFR') {
+ color = '#CA33F9'
+ }
+ return new ol.style.Style({
+ image: new ol.style.Circle({
+ radius: 5,
+ fill: new ol.style.Fill({
+ color: color
+ }),
+ stroke: new ol.style.Stroke({
+ color: '#fff',
+ width: 2
+ })
+ })
+ });
+ }
+ });
+
+ var refreshMetar = function () {
+ metar.getSource().refresh();
+ };
+ window.setInterval(refreshMetar, 5 * 60000);
+
+ return metar;
+}
diff --git a/public_html/script.js b/public_html/script.js
index 7217613ca..41f57ed7b 100644
--- a/public_html/script.js
+++ b/public_html/script.js
@@ -930,6 +930,8 @@ function initialize_map() {
})
});
+ var metarLayer = createMetarLayer();
+
layers.push(new ol.layer.Group({
title: 'Overlays',
layers: [
@@ -951,6 +953,8 @@ function initialize_map() {
})
}),
+ metarLayer,
+
iconsLayer
]
}));
@@ -1042,12 +1046,15 @@ function initialize_map() {
}
}
});
-
+
OLMap.getView().on('change:resolution', function(event) {
ZoomLvl = localStorage['ZoomLvl'] = OLMap.getView().getZoom();
for (var plane in Planes) {
Planes[plane].updateMarker(false);
};
+ if (metarLayer.getVisible()) {
+ metarLayer.getSource().refresh();
+ }
});
OLMap.on(['click', 'dblclick'], function(evt) {
@@ -1097,6 +1104,7 @@ function initialize_map() {
// handle the layer settings pane checkboxes
OLMap.once('postrender', function(e) {
toggleLayer('#nexrad_checkbox', 'nexrad');
+ toggleLayer('#metar_checkbox', 'metar');
toggleLayer('#sitepos_checkbox', 'site_pos');
toggleLayer('#actrail_checkbox', 'ac_trail');
toggleLayer('#acpositions_checkbox', 'ac_positions');