194 lines
9.7 KiB
HTML
194 lines
9.7 KiB
HTML
<!DOCTYPE html>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"
|
|
integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
|
|
crossorigin="" />
|
|
<style type="text/css">
|
|
html {
|
|
height: 100%
|
|
}
|
|
|
|
body {
|
|
height: 100%;
|
|
margin: 0;
|
|
padding: 0
|
|
}
|
|
|
|
#map_canvas {
|
|
height: 100%
|
|
}
|
|
|
|
</style>
|
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
|
|
<script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"
|
|
integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
|
|
crossorigin=""></script>
|
|
<script type="text/javascript">
|
|
//Leaflet.RotatedMarker 库
|
|
(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;
|
|
}
|
|
});
|
|
})();
|
|
</script>
|
|
<script type="text/javascript">
|
|
Map = null;
|
|
CenterLat = 45.0;
|
|
CenterLon = 9.0;
|
|
Planes = {};
|
|
NumPlanes = 0;
|
|
let planeSVG='data:image/svg+xml;charset=utf-8,%3Csvg%20alt%3D%22Airliner%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2025%2026%22%20width%3D%2225px%22%20height%3D%2226px%22%20class%3D%22flightPageAircraftIcon%20Enroute%20progressBarAircraftIcon%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%23FFFFFF%3B%7D.cls-2%7Bfill%3A%235A5A5A%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Ctitle%3Eairliner_live%3C%2Ftitle%3E%3Cg%20id%3D%22Layer_2%22%20data-name%3D%22Layer%202%22%3E%3Cg%20id%3D%22Airliner%22%3E%3Cpath%20class%3D%22cls-1%22%20d%3D%22M12.51%2C25.75c-.26%2C0-.74-.71-.86-1.41l-3.33.86L8%2C25.29l.08-1.41.11-.07c1.13-.68%2C2.68-1.64%2C3.2-2-.37-1.06-.51-3.92-.43-8.52v0L8%2C13.31C5.37%2C14.12%2C1.2%2C15.39%2C1%2C15.5a.5.5%2C0%2C0%2C1-.21%2C0%2C.52.52%2C0%2C0%2C1-.49-.45%2C1%2C1%2C0%2C0%2C1%2C.52-1l1.74-.91c1.36-.71%2C3.22-1.69%2C4.66-2.43a4%2C4%2C0%2C0%2C1%2C0-.52c0-.69%2C0-1%2C0-1.14l.25-.13H7.16A1.07%2C1.07%2C0%2C0%2C1%2C8.24%2C7.73%2C1.12%2C1.12%2C0%2C0%2C1%2C9.06%2C8a1.46%2C1.46%2C0%2C0%2C1%2C.26.87L9.08%2C9h.25c0%2C.14%2C0%2C.31%2C0%2C.58l1.52-.84c0-1.48%2C0-7.06%2C1.1-8.25a.74.74%2C0%2C0%2C1%2C1.13%2C0c1.15%2C1.19%2C1.13%2C6.78%2C1.1%2C8.25l1.52.84c0-.32%2C0-.48%2C0-.58l.25-.13H15.7A1.46%2C1.46%2C0%2C0%2C1%2C16%2C8a1.11%2C1.11%2C0%2C0%2C1%2C.82-.28%2C1.06%2C1.06%2C0%2C0%2C1%2C1.08%2C1.16V9c0%2C.19%2C0%2C.48%2C0%2C1.17a4%2C4%2C0%2C0%2C1%2C0%2C.52c1.75.9%2C4.4%2C2.29%2C5.67%2C3l.73.38a.9.9%2C0%2C0%2C1%2C.5%2C1%2C.55.55%2C0%2C0%2C1-.5.47h0l-.11%2C0c-.28-.11-4.81-1.49-7.16-2.2H14.06v0c.09%2C4.6-.06%2C7.46-.43%2C8.52.52.33%2C2.07%2C1.29%2C3.2%2C2l.11.07L17%2C25.29l-.33-.09-3.33-.86c-.12.7-.6%2C1.41-.86%2C1.41h0Z%22%2F%3E%3Cpath%20class%3D%22cls-2%22%20d%3D%22M12.51.5C13.93.5%2C14%2C7%2C13.93%2C8.91c.3.16%2C1.64.91%2C2%2C1.1%2C0-.6%2C0-.85%2C0-1s0-.09%2C0-.13a1.18%2C1.18%2C0%2C0%2C1%2C.19-.7A.88.88%2C0%2C0%2C1%2C16.78%2C8h0a.82.82%2C0%2C0%2C1%2C.83.91s0%2C.07%2C0%2C.13%2C0%2C.44%2C0%2C1.17a3.21%2C3.21%2C0%2C0%2C1-.06.66c2.33%2C1.19%2C6.51%2C3.39%2C6.56%2C3.42.59.3.4%2C1%2C.11%2C1h-.07c-.37-.14-7.18-2.21-7.18-2.21l-3.18%2C0c0%2C.22.22%2C7.56-.48%2C8.91%2C0%2C0%2C2%2C1.26%2C3.39%2C2.08l.06.93L13.15%2C24a2.14%2C2.14%2C0%2C0%2C1-.64%2C1.47A2.14%2C2.14%2C0%2C0%2C1%2C11.87%2C24L8.26%2C25%2C8.31%2C24c1.38-.82%2C3.39-2.08%2C3.39-2.08-.7-1.35-.48-8.69-.48-8.91L8%2C13.06S1.17%2C15.13.86%2C15.27l-.11%2C0c-.32%2C0-.43-.73.14-1S5.13%2C12%2C7.46%2C10.85a3.21%2C3.21%2C0%2C0%2C1-.06-.66c0-.73%2C0-1%2C0-1.17s0-.09%2C0-.13A.82.82%2C0%2C0%2C1%2C8.24%2C8h0a.88.88%2C0%2C0%2C1%2C.65.21%2C1.18%2C1.18%2C0%2C0%2C1%2C.19.7s0%2C.07%2C0%2C.13%2C0%2C.39%2C0%2C1c.36-.19%2C1.71-.94%2C2-1.1C11.05%2C7%2C11.09.5%2C12.51.5m0-.5a1%2C1%2C0%2C0%2C0-.74.34c-1.16%2C1.2-1.2%2C6.3-1.18%2C8.28L10%2C8.93l-.46.25V8.91a1.68%2C1.68%2C0%2C0%2C0-.33-1.06%2C1.34%2C1.34%2C0%2C0%2C0-1-.36%2C1.31%2C1.31%2C0%2C0%2C0-1.33%2C1.4V9h0v0c0%2C.16%2C0%2C.46%2C0%2C1.14%2C0%2C.13%2C0%2C.26%2C0%2C.38l-4.5%2C2.35-1.74.91A1.2%2C1.2%2C0%2C0%2C0%2C0%2C15.15a.77.77%2C0%2C0%2C0%2C.73.64.74.74%2C0%2C0%2C0%2C.31-.07c.29-.12%2C4.35-1.35%2C7-2.17l2.6%2C0c-.1%2C5.54.17%2C7.46.38%2C8.2-.64.4-2%2C1.25-3%2C1.86l-.22.13%2C0%2C.26-.06.93%2C0%2C.81.7-.31%2C3.06-.79c.19.67.63%2C1.35%2C1%2C1.35s.86-.68%2C1-1.35l3.06.79.7.31%2C0-.81L17.2%2C24l0-.26L17%2C23.6c-1-.61-2.4-1.47-3-1.86.21-.74.48-2.66.38-8.2l2.6%2C0c2.72.83%2C6.81%2C2.07%2C7.07%2C2.18a.68.68%2C0%2C0%2C0%2C.25%2C0%2C.79.79%2C0%2C0%2C0%2C.74-.67%2C1.15%2C1.15%2C0%2C0%2C0-.63-1.29l-.71-.37c-1.23-.65-3.78-2-5.53-2.88%2C0-.12%2C0-.25%2C0-.38%2C0-.67%2C0-1%2C0-1.14h0V8.92a1.32%2C1.32%2C0%2C0%2C0-1.32-1.44%2C1.35%2C1.35%2C0%2C0%2C0-1%2C.36%2C1.67%2C1.67%2C0%2C0%2C0-.33%2C1V9h0v.22L15%2C8.93l-.57-.32c0-2%2C0-7.08-1.18-8.28A1%2C1%2C0%2C0%2C0%2C12.51%2C0Z%22%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E';
|
|
function getIconForPlane(plane) {
|
|
var r = 255, g = 255, b = 0;
|
|
var maxalt = 40000; /* Max altitude in the average case */
|
|
var invalt = maxalt - plane.altitude;
|
|
|
|
if (invalt < 0) invalt = 0;
|
|
b = parseInt(255 / maxalt * invalt);
|
|
var myIcon = L.icon({
|
|
iconUrl: planeSVG,
|
|
iconSize: [24, 24],
|
|
className: 'plane-icon'
|
|
});
|
|
return myIcon;
|
|
}
|
|
function showPopup(plane){
|
|
let machConst=1225.044; //1马赫常数
|
|
let atmConst=1013.25;//标准大气压常数
|
|
//设置回调
|
|
return function(){
|
|
let info=plane.flight+"<br/>"+
|
|
"ICAO:"+plane.hex+"<br/>"+
|
|
"高度:"+plane.altitude+" 米<br/>"+
|
|
"速度:"+plane.speed+" km/h ("+(plane.speed/machConst).toFixed(2)+" 马赫)<br/>"+
|
|
"气压: 约"+(atmConst-(plane.altitude*0.10936)).toFixed(2)+" hPa<br/>"+
|
|
"航向:"+plane.track;
|
|
L.popup()
|
|
.setLatLng([plane.lat, plane.lon])
|
|
.setContent(info)
|
|
.openOn(Map);
|
|
}
|
|
}
|
|
//更新数据
|
|
function fetchData() {
|
|
$.getJSON('/data.json', function (data) {
|
|
var stillhere = {}
|
|
for (var j = 0; j < data.length; j++) {
|
|
var plane = data[j];
|
|
var marker = null;
|
|
stillhere[plane.hex] = true;
|
|
plane.flight = $.trim(plane.flight);
|
|
if (Planes[plane.hex]) {
|
|
var myplane = Planes[plane.hex];
|
|
marker = myplane.marker;
|
|
marker.options.rotationAngle=plane.track; //添加航向
|
|
marker.setLatLng([plane.lat, plane.lon]);
|
|
marker.setIcon(getIconForPlane(plane));
|
|
myplane.altitude = plane.altitude;
|
|
myplane.speed = plane.speed;
|
|
myplane.lat = plane.lat;
|
|
myplane.lon = plane.lon;
|
|
myplane.track = plane.track;
|
|
myplane.flight = plane.flight;
|
|
} else {
|
|
var icon = getIconForPlane(plane);
|
|
var marker = L.marker([plane.lat, plane.lon], { icon: icon ,title:plane.flight,alt:plane.flight,rotationAngle:plane.track}).addTo(Map);
|
|
var hex = plane.hex;
|
|
marker.on('click', showPopup(plane));//注册飞机点击事件
|
|
plane.marker = marker;
|
|
marker.planehex = plane.hex;
|
|
Planes[plane.hex] = plane;
|
|
}
|
|
}
|
|
NumPlanes = data.length;
|
|
|
|
/* 移除没用的飞机 */
|
|
for (var p in Planes) {
|
|
if (!stillhere[p]) {
|
|
Map.removeLayer(Planes[p].marker);
|
|
delete Planes[p];
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function initialize() {
|
|
Map = L.map('map_canvas').setView([29.0, 121.0], 5);
|
|
|
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
attribution: '使用 OpenStreetMap',
|
|
maxZoom: 18,
|
|
id: 'mapbox/streets-v11',
|
|
accessToken: '0'
|
|
}).addTo(Map);
|
|
|
|
/* 定时刷新*/
|
|
window.setInterval(function () {
|
|
fetchData();
|
|
}, 1000);
|
|
}
|
|
|
|
</script>
|
|
</head>
|
|
|
|
<body onload="initialize()">
|
|
<div id="map_canvas" style="width:100%; height:100%"></div>
|
|
</body>
|
|
|
|
</html> |