1
0
Fork 0
fgdata/webgui/topics/Map/NavdbLayer.js

197 lines
6.5 KiB
JavaScript
Raw Normal View History

(function(factory) {
if (typeof define === "function" && define.amd) {
// AMD. Register as an anonymous module.
define([
'leaflet'
], factory);
} else {
// Browser globals
factory();
}
}(function() {
function SquareIcon(w, url) {
return L.icon({
iconSize : [
w, w
],
iconAnchor : [
w / 2, w / 2
],
popupAnchor : [
0, w / 2 - 2
],
iconUrl : url,
})
}
var MAP_ICON = {};
MAP_ICON["VOR"] = SquareIcon(30, 'images/vor.svg');
MAP_ICON["NDB"] = SquareIcon(30, 'images/ndb.svg');
MAP_ICON["dme"] = SquareIcon(30, 'images/dme.svg');
MAP_ICON["airport-paved"] = SquareIcon(30, 'images/airport-paved.svg');
MAP_ICON["airport-unpaved"] = SquareIcon(30, 'images/airport-unpaved.svg');
MAP_ICON["airport-unknown"] = SquareIcon(30, 'images/airport-unknown.svg');
MAP_ICON["arp"] = SquareIcon(30, 'images/arp.svg');
MAP_ICON["aircraft"] = SquareIcon(20, 'images/aircraft.svg');
L.NavdbLayer = L.GeoJSON.extend({
options : {
pointToLayer : function(feature, latlng) {
var options = {
title : feature.properties.id + ' (' + feature.properties.name + ')',
alt : feature.properties.id,
riseOnHover : true,
};
if (feature.properties.type == "airport") {
if (this._map && this._map.getZoom() >= 13) {
options.icon = MAP_ICON['arp'];
} else {
options.angle = feature.properties.longestRwyHeading_deg;
switch (feature.properties.longestRwySurface) {
case 'asphalt':
case 'concrete':
options.icon = MAP_ICON['airport-paved'];
break;
case 'unknown':
options.icon = MAP_ICON['airport-unknown'];
break;
default:
options.icon = MAP_ICON['airport-unpaved'];
break;
}
}
} else {
if (feature.properties.type in MAP_ICON) {
options.icon = MAP_ICON[feature.properties.type];
}
}
return new L.RotatedMarker(latlng, options);
},
onEachFeature : function(feature, layer) {
if (feature.properties) {
var popupString = '<div class="popup">';
for ( var k in feature.properties) {
var v = feature.properties[k];
popupString += k + ': ' + v + '<br />';
}
popupString += '</div>';
layer.bindPopup(popupString, {
maxHeight : 200
});
}
},
filter : function(feature) {
var zoom = (this._map && this._map.getZoom()) || 11;
switch (feature.properties.type) {
case 'airport':
if (zoom >= 10)
return true;
return feature.properties.longestRwyLength_m >= 2000;
break;
case 'NDB':
if (zoom >= 10)
return true;
if (zoom >= 8)
return feature.properties.range_nm >= 30;
return feature.properties.range_nm > 50;
}
return true;
},
style : function(feature) {
if (feature.properties.type == "ILS" || feature.properties.type == "localizer") {
return {
color : 'black',
weight : 2,
};
}
if (feature.properties.type == "airport") {
return {
color : 'black',
weight : 3,
fill : 'true',
fillColor : '#606060',
fillOpacity : 1.0,
lineJoin : 'bevel',
};
}
},
},
onAdd : function(map) {
L.GeoJSON.prototype.onAdd.call(this, map);
this.dirty = true;
this.update(++this.updateId);
},
onRemove : function(map) {
this.updateId++;
L.GeoJSON.prototype.onRemove.call(this, map);
},
invalidate : function() {
this.dirty = true;
},
dirty : true,
updateId : 0,
update : function(id) {
var that = this;
if (this.updateId != id)
return;
if (this.dirty) {
this.dirty = false;
var bounds = this._map.getBounds();
// radius in NM
var radius = bounds.getSouthWest().distanceTo(bounds.getNorthEast()) / 3704;
if (radius > 250)
radius = 250;
if (radius < 10)
radius = 10;
var filter = "vor,ndb,airport";
if (radius < 60)
filter += ",ils,dme,loc,om";
if (radius < 20)
filter += ",mm";
var center = this._map.getCenter();
var lat = center.lat;
var lon = center.lng;
var url = "/navdb?q=findWithinRange&type=" + filter + "&range=" + radius + "&lat=" + lat + "&lon=" + lon;
var jqxhr = $.get(url).done(function(data) {
if (that.updateId == id) {
that.clearLayers();
that.addData.call(that, data);
}
}).fail(function() {
that.updateId++;
alert('failed to load navdb data');
}).always(function() {
});
}
if (this.updateId == id) {
setTimeout(function() {
that.update(id)
}, 5000);
}
},
});
L.navdbLayer = function(options) {
return new L.NavdbLayer(null, options);
}
}));