dump1090/gmap.html
forever 372f7b4f51
All checks were successful
构建Dump1090 / build (push) Successful in 1m43s
优化地图
2024-10-27 21:46:45 +08:00

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>