"Real-Time Flights Map (by AirLabs.Co)"
Bootstrap 4.1.1 Snippet by airlabs

<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <!------ Include the above in your HEAD tag ----------> <html lang="en"> <head> <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" crossorigin="" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="/> <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js" crossorigin="" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script> <script type="text/javascript"> // follow to get your api key var base_url = "https://airlabs.co/"; var api_key = "YOUR-API-KEY"; $(document).ready(function () { $("body").tooltip({ selector: '[data-toggle=tooltip]' }); var mymap = L.map('mapid').setView([51.76696254499177, -1.2647357121383023], 5); L.tileLayer('http://services.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{z}/{y}/{x}', { attribution : false, zoomControl: false, draggable: false, interactive: false, subdomains: 'abcd' }).addTo(mymap); var getIcon = function(dir, state) { var color = (state && state === 'active' ? '42ba96' : '335eea'); var border = '#ffffff'; var svg = '<svg id="plane_21" height="640" style="transform:rotate('+(+dir||0)+'deg)" preserveAspectRatio="xMidYMid meet" viewBox="0 0 640 640" width="640" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path id="a" d="m321.66 609.69c57.26 14.18 89.07 22.05 95.44 23.63 5.72 1.55 11.03-2.07 11.88-6.54.7-1.25.7-1.25.14-3.21-.08-2.51-.71-22.61-.79-25.13.15-3.21-1.66-5.86-4.17-7.26-7.36-5.1-66.25-45.86-73.61-50.96-2.51-1.4-3.62-5.31-3.47-8.52.77-18.5 6.97-166.45 7.75-184.95-.41-5.17 5.6-10.04 10.07-9.19 1.25.7 3.21.14 3.21.14 25.35 11.19 228.21 100.7 253.57 111.89 5.02 2.8 11.58-.12 13.13-5.84.7-1.26 1.4-2.51.85-4.47-.12-4.51-1.06-40.58-1.17-45.09.14-3.21-1.67-5.87-4.18-7.27-26.57-19.93-239.12-179.36-265.68-199.29-2.51-1.4-4.32-4.06-4.18-7.27-.47-46.34-3.27-112.1-4.65-124.39-1.02-48.3-70.31-95.19-79.17 15.07-.59 12.84.96 77.9 3.27 112.1.55 1.96-.85 4.47-3.5 6.28-26.54 20.41-238.81 183.72-265.35 204.13-1.4 2.51-2.8 5.02-2.94 8.23-.01 4.44-.08 39.96-.09 44.4-1.54 5.72 2.78 9.77 9.2 10.06 1.25.7 3.21.15 3.91-1.1 25.43-11.65 228.86-104.85 254.28-116.5 4.62-2.36 10.34-.82 12 5.05.55 1.96.55 1.96 1.11 3.91.7 18.5 6.34 166.48 7.04 184.98-.14 3.21-1.54 5.72-4.9 8.78-7.38 5.27-66.43 47.37-73.81 52.63-2.65 1.81-4.05 4.32-4.2 7.53-.05 2.44-.42 21.98-.46 24.43.4 5.16 4.02 10.47 9.19 10.07 1.25.7 1.95-.56 3.21.14 6.47-1.76 38.83-10.59 97.07-26.47z"/></defs><use fill="#'+color+'" xlink:href="#a" stroke="'+border+'" stroke-width="2%" /><use fill="none" xlink:href="#a"/></svg>'; return L.icon({ iconUrl : 'data:image/svg+xml;base64,' + btoa(svg), iconSize : [20, 20, dir], iconAnchor : [10, 10, dir] }); }; var planes = {}; var delay_timeout = null; var repeat_timeout = null; var get_flights = function () { clearTimeout(delay_timeout); delay_timeout = setTimeout(function() { var bounds = mymap.getBounds(); var sW = bounds._southWest; var nE = bounds._northEast; var bbox = [sW.lat, sW.lng, nE.lat, nE.lng].join(','); $.get(base_url+'api/v9/flights?api_key='+api_key+'&bbox='+bbox, function (result) { planes = (result.response||[]).reduce(function (all, one) { all[one.hex] = one; return all; }, {}); redraw_planes(); clearTimeout(repeat_timeout); repeat_timeout = setTimeout(get_flights, 2222); }).fail(function () { clearTimeout(repeat_timeout); repeat_timeout = setTimeout(get_flights, 5555); }); }, 333); }; get_flights(); var markers = {}; var redraw_planes = function () { for(let hex in markers) { if(!planes[hex]) { mymap.removeLayer(markers[hex]); delete markers[hex]; } } for(let hex in planes) { if(!planes.hasOwnProperty(hex)) continue; var label = ""; if(planes[hex].dep_icao || planes[hex].dep_iata) { label += (planes[hex].dep_icao||"") + " / " + (planes[hex].dep_iata||""); } if(planes[hex].arr_icao || planes[hex].arr_iata) { label += " > " + (planes[hex].arr_icao||"") + " / " + (planes[hex].arr_iata||""); } label += "<br/> "; if(planes[hex].flag) { label += planes[hex].flag; } if(planes[hex].airline_icao || planes[hex].airline_iata) { label += (planes[hex].airline_icao||"") + " / " + (planes[hex].airline_iata||""); } if(planes[hex].hex) { label += "<br/> Hex: " + planes[hex].hex + "   "; } if(planes[hex].reg_number) { label += "<br/> Reg: "+planes[hex].reg_number; } if(planes[hex].flight_icao || planes[hex].flight_iata) { label += "<br/> Flight: "+(planes[hex].flight_icao||"")+' / '+(planes[hex].flight_iata||""); } if(planes[hex].speed) { label += "<br/> Speed: "+planes[hex].speed+" kph   "; } if(planes[hex].alt) { label += "<br/> Alt: "+planes[hex].alt+" m"; } if(!markers[hex]) { markers[hex] = L.marker( [planes[hex].lat, planes[hex].lng], {icon: getIcon(planes[hex].dir)} ); markers[hex].bindPopup(label); markers[hex].on('mouseover', function (e) { this.setIcon(getIcon(this.options.icon.options.iconSize[2], 'active')); }); markers[hex].on('mouseout', function (e) { this.setIcon(getIcon(this.options.icon.options.iconSize[2])); }); markers[hex].on('click', function (e) { this.openPopup(); setTimeout(function () { this.closePopup(); }.bind(this), 10000); }); markers[hex].addTo(mymap); } else { markers[hex].setLatLng([planes[hex].lat, planes[hex].lng]); markers[hex].setIcon(getIcon(planes[hex].dir)); markers[hex].bindPopup(label); } } }; }); </script> </head> <body> <div id="mapid" style="height: 400px; width: 600px" class="screenshot"></div> <br/> <a href="https://airlabs.co/" target="_blank">Powered by AirLabs.Co</a> </body> </html>
(function() { // save these original methods before they are overwritten var proto_initIcon = L.Marker.prototype._initIcon; var proto_setPos = L.Marker.prototype._setPos; var oldIE = (L.DomUtil.TRANSFORM === 'msTransform'); L.Marker.addInitHook(function () { var iconOptions = this.options.icon && this.options.icon.options; var iconAnchor = iconOptions && this.options.icon.options.iconAnchor; if (iconAnchor) { iconAnchor = (iconAnchor[0] + 'px ' + iconAnchor[1] + 'px'); } this.options.rotationOrigin = this.options.rotationOrigin || iconAnchor || 'center bottom' ; this.options.rotationAngle = this.options.rotationAngle || 0; // Ensure marker keeps rotated during dragging this.on('drag', function(e) { e.target._applyRotation(); }); }); L.Marker.include({ _initIcon: function() { proto_initIcon.call(this); }, _setPos: function (pos) { proto_setPos.call(this, pos); this._applyRotation(); }, _applyRotation: function () { if(this.options.rotationAngle) { this._icon.style[L.DomUtil.TRANSFORM+'Origin'] = this.options.rotationOrigin; if(oldIE) { // for IE 9, use the 2D rotation this._icon.style[L.DomUtil.TRANSFORM] = 'rotate(' + this.options.rotationAngle + 'deg)'; } else { // for modern browsers, prefer the 3D accelerated version this._icon.style[L.DomUtil.TRANSFORM] += ' rotateZ(' + this.options.rotationAngle + 'deg)'; } } }, setRotationAngle: function(angle) { this.options.rotationAngle = angle; this.update(); return this; }, setRotationOrigin: function(origin) { this.options.rotationOrigin = origin; this.update(); return this; } }); })();

Related: See More


Questions / Comments:

You just need to use your own api key from https://airlabs.co/

airlabs () - 2 years ago - Reply 0