<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;
}
});
})();