(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 = ''; 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) { 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 that = this; 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); } }));