Files
eacp_webapp/htdocs/js/clients_2dmap.js
T
2026-06-16 11:24:50 +08:00

625 lines
19 KiB
JavaScript

/********************************************************************
* 2D Sensor List for Jetvision MLAT Server
********************************************************************
* Guenter Koellner Embedded Development GmbH
*
* Am Rain 24
* 85256 Vierkirchen
* Geschaeftsfuehrer Guenter Koellner
*
* http://www.modesbeast.com
********************************************************************/
var Gmap=null;
var Planes={};
var Filters={altitude: [undefined, undefined],
enable_alt: undefined,
speed: [undefined, undefined],
enable_spd: undefined,
distance: [undefined, undefined],
enable_dis: undefined,
typ_enable: undefined,
typ_filter: undefined,
fli_enable: undefined,
fli_filter: undefined,
tracklength: undefined,
fleetwatch: undefined,
reg_enable: undefined,
refreshtime: undefined
};
var GmapInit={
Zoomlevel : 6,
CenterLat : 48.353013,
CenterLon : 11.785958,
LatLonSrc : "GPS",
DistanceUnit : "km",
ShowRangeRings : false
};
var NumPlanes = 0;
var Selected=null;
var RangeCircle={};
var CircleStep=50;
var NauticalMiles_to_Meters=1852;
var KiloMeters_to_Meters=1000;
//var map_container;
var map_box;
var map_info_box;
var flight_info_box;
var hide_info;
var hide_info_btn;
function showInfoBox()
{
hide_info.style.visibility='visible';
map_info_box.style.width='210px';
hide_info_btn.setAttribute("class", "glyphicon glyphicon-minus");
}
function hideInfoBox()
{
hide_info.style.visibility='hidden';
map_info_box.style.width='1px';
hide_info_btn.setAttribute("class", "glyphicon glyphicon-plus");
}
function toggleInfoBox()
{
if(hide_info.style.visibility == 'hidden')
showInfoBox();
else
hideInfoBox();
}
function get_image_object(ac_category, ac_type)
{
return {x:12, y:12, scale:1, rotcorr: 180, path:"M0,0 6,12 12,0z"};
}
function getIconForPlane(plane)
{
var rFill = 255; gFill = 255; bFill = 0;
var rBorder = 64, gBorder = 64, bBorder = 64;
if (plane.timeout == 1) /* after timeout 1 */
{
rFill = 128; gFill = 128; bFill = 128; /* dark gray */
rBorder = rFill; gBorder=gFill; bBorder=bFill;
}
var maxalt = 40000; /* Max altitude in the average case */
var invalt = maxalt-plane.alt;
var selected = (Selected == plane.id);
var imageObj = get_image_object("dummy1", "dummy2");
var object_box = Raphael.pathBBox(imageObj.path);
var offset_x = (object_box.x + object_box.x2) / 2;
var offset_y = (object_box.y + object_box.y2) / 2;
if (invalt < 0) invalt = 0;
var strokew = 1;
if (selected) { strokew = 2; }
if (plane.timeout == 2) { strokew = 0.333; } /* light on timeout 2 */
var ac_symbol = {
strokeColor: 'rgb('+rBorder+','+gBorder+','+bBorder+')',
strokeWeight: strokew,
path: imageObj.path,
scale: imageObj.scale,
fillColor: 'rgb('+rFill+','+gFill+','+bFill+')',
fillOpacity: 0.9,
anchor: new google.maps.Point(offset_x, offset_y),
rotation: (plane.trk + imageObj.rotcorr) % 360
};
var myZoom = Gmap.getZoom();
if((myZoom <= 14) && ((6 < myZoom))) {
ac_symbol.scale = ac_symbol.scale + 0.2 * ((myZoom-10)/4);
}
else if(myZoom < 14) {
ac_symbol.scale = ac_symbol.scale - 0.2
}
else {
ac_symbol.scale = ac_symbol.scale + 0.2
}
return ac_symbol;
}
function selectPlane()
{
if (!Planes[this.planehex])
return;
var Old_Selected = Selected;
Selected = this.planehex;
if (Planes[Old_Selected])
{
/* Remove the highlight in the previously selected plane. */
Planes[Old_Selected].marker1.setIcon(getIconForPlane(Planes[Old_Selected]));
labelSetStyle(Planes[Old_Selected], Planes[Old_Selected].marker1);
}
Planes[Selected].marker1.setIcon(getIconForPlane(Planes[Selected]));
labelSetStyle(Planes[Selected],Planes[Selected].marker1);
refreshSelectedInfo();
showInfoBox();
}
function deselectPlane()
{
if (Selected) {
var Old_Selected = Selected;
Selected = null;
Planes[Old_Selected].marker1.setIcon(getIconForPlane(Planes[Old_Selected]));
labelSetStyle(Planes[Old_Selected],Planes[Old_Selected].marker1);
flight_info_box.innerHTML = "";
}
}
function sortPlaneSymbolList(a, b)
{
var al = a.id;
var bl = b.id;
if (al < bl) return 1;
if (al > bl) return -1;
return 0;
}
/* Check if an aircraft disappeared and therefore was deselected */
function checkAircraftDeselected()
{
if (Selected == null)
{
}
}
function getTimeString(isLocal) {
var hours;
var minutes;
var date = new Date();
var zone_offset = date.getTimezoneOffset();
if(isLocal)
{
hours = date.getHours();
minutes = date.getMinutes();
}
else
{
hours = date.getUTCHours();
minutes = date.getUTCMinutes();
}
if(hours < 10) {hours = '0'+hours;}
if(minutes < 10) {minutes = '0'+minutes;}
var zeit_string = hours + ':' + minutes;
return zeit_string;
}
/* Info box in div map_info_box - 0=Aircraft Info 1=Config */
function refreshGeneralInfo()
{
var html = '';
html += "<table class=\"info_box_table\">";
html += " <thead>";
html += " <tr class=\"info_header\">";
html += " <td colspan=\"2\"><span class=\"glyphicon glyphicon-time\" aria-hidden=\"true\"></span> General Information</td>";
html += " </tr>";
html += " </thead>";
html += " <tbody>";
html += " <tr class=\"info_label\">";
html += " <td>UTC Time</td>";
html += " <td>Local Time</td>";
html += " </tr>";
html += " <tr class=\"info_value\">";
html += " <td>" + getTimeString(false) + "</td>";
html += " <td>" + getTimeString(true) + "</td>";
html += " </tr>";
html += " <tr class=\"info_label\">";
html += " <td colspan=\"2\">Number of Aircraft on Map</td>";
html += " </tr>";
html += " <tr class=\"info_value\">";
html += " <td colspan=\"2\">" + NumPlanes +"</td>";
html += " </tr>";
html += " </tbody>";
html += "</table>";
document.getElementById('general_info_box').innerHTML = html;
}
function refreshSelectedInfo()
{
var p = undefined;
if(Selected)
p = Planes[Selected];
if (p && Selected)
{
var html = '';
html += '<table class="info_box_table">';
/* AC Details Header */
html += ' <tr class="info_header">';
html += ' <td colspan="2"><span class="glyphicon glyphicon-plane" aria-hidden="true"></span> Aircraft Details</td>';
html += ' </tr>';
/* AC Details Row 1 */
html += ' <tr class="info_label">';
html += ' <td width="50%">Registration</td>';
html += ' <td width="50%">Mode-S</td>';
html += ' </tr>';
html += ' <tr class="info_value">';
if(p.reg != "") {
html += ' <td><a href="https://planespotters.net/search?q='
+ encodeURIComponent(p.reg) + '" target="_blank">' + p.reg + '</a>&nbsp;</td>';
} else {
html += ' <td>' + p.reg + '&nbsp;</td>';
}
html += ' <td>'+ p.id +'&nbsp;</td>';
html += ' </tr>';
/* AC Details Row 2 */
html += ' <tr class="info_label">';
html += ' <td>Type</td>';
html += ' <td>Category</td>';
html += ' </tr>';
html += ' <tr class="info_value">';
html += ' <td>' + p.typ + '&nbsp;</td>';
html += ' <td>' + p.cat + '&nbsp;</td>';
html += ' </tr>';
/* Flight Details Header */
html += ' <tr class="info_header">';
if (p.fli.length) {
html += ' <td colspan="2"><span class="glyphicon glyphicon-plane" aria-hidden="true"></span> Flight '+ p.fli +'</td>';
} else {
html += ' <td colspan="2"><span class="glyphicon glyphicon-plane" aria-hidden="true"></span> Flight Details</td>';
}
html += ' </tr>';
/* Flight Details Row 1 */
html += ' <tr class="info_label">';
html += ' <td>Origin</td>';
html += ' <td>Destination</td>';
html += ' </tr>';
html += ' <tr class="info_value">';
html += ' <td>' + p.org + '&nbsp;</td>';
html += ' <td>' + p.dst + '&nbsp;</td>';
html += ' </tr>';
/* Flight Details Row 2 */
html += ' <tr class="info_label">';
html += ' <td>Track</td>';
html += ' <td>Speed</td>';
html += ' </tr>';
html += ' <tr class="info_value">';
html += ' <td>' + p.trk + '&deg;</td>';
html += ' <td>' + p.spd + ' kt</td>';
html += ' </tr>';
/* Flight Details Row 3 */
html += ' <tr class="info_label">';
html += ' <td>Altitude</td>';
html += ' <td>Vertical Rate</td>';
html += ' </tr>';
html += ' <tr class="info_value">';
html += ' <td>' + p.alt + ' ft</td>';
if(p.vrt) {
html += ' <td>' + p.vrt + ' ft/min</td>';
} else {
html += ' <td></td>';
}
html += ' </tr>';
/* AC Tracking Header */
html += ' <tr class="info_header">';
html += ' <td colspan="2"><span class="glyphicon glyphicon-map-marker" aria-hidden="true"></span> Aircraft Tracking</td>';
html += ' </tr>';
/* AC Tracking Row 1 */
html += ' <tr class="info_label">';
html += ' <td>Latitude</td>';
html += ' <td>Longitude</td>';
html += ' </tr>';
html += ' <tr class="info_value">';
html += ' <td>' + p.lat + '&deg;</td>';
html += ' <td>' + p.lon + '&deg;</td>';
html += ' </tr>';
/* AC Tracking Row 2 */
html += ' <tr class="info_label">';
html += ' <td>Distance</td>';
html += ' <td>Source</td>';
html += ' </tr>';
html += ' <tr class="info_value">';
html += ' <td>' + "@PH1" + ' ' + DistanceUnit + '</td>';
html += ' <td>@PH2</td>';
html += ' </tr>';
/* AC Tracking Row 3 */
html += ' <tr class="info_label">';
html += ' <td>Last Signal</td>';
html += ' <td>&nbsp;</td>';
html += ' </tr>';
html += ' <tr class="info_value">';
html += ' <td>' + p.lla + ' sec</td>';
html += ' <td>&nbsp;</td>';
html += ' </tr>';
html += '</table>';
flight_info_box.innerHTML = html;
}
else
{
/* Remove Selected Info */
flight_info_box.innerHTML = "<p>Click on a client for more info.</p>";
}
}
// This is the text that appears with all displayed aircraft
function labelDataTable(plane)
{
var labelDataTab = "<table class=\"aircraft_label\">" +
"<tr><td class=\"flight\">" + plane.id + "</td><td class=\"altitude\">" + plane.ac + "</td></tr>" +
"<tr><td class=\"verticalRate\">" + plane.iBy + "</td><td class=\"speed\">" + plane.iMsg + "</td></tr>" +
"</table>";
return labelDataTab;
}
function labelSetAnchor(plane, marker, offset)
{
if (plane.trk > 315) { marker.set("labelAnchor", new google.maps.Point( 66, -1 + offset)); return; }
if (plane.trk < 45) { marker.set("labelAnchor", new google.maps.Point( 66, -1 + offset)); return; }
if (plane.trk < 135) { marker.set("labelAnchor", new google.maps.Point( 37, -1 + 28 + offset)); return; }
if (plane.trk < 225) { marker.set("labelAnchor", new google.maps.Point(-17, -1 + offset)); return; }
marker.set("labelAnchor", new google.maps.Point(37, -1 - 28 + offset));
}
// https://www.quackit.com/html/codes/color/html_color_chart.cfm
function labelSetStyle(plane, marker)
{
if (plane.active!= 1 ) {marker.set("labelStyle", { opacity: 0.66, 'background-color': 'red'}); return; }
if (plane.iMsg < 1 ) {marker.set("labelStyle", { opacity: 0.66, 'background-color': 'orange'}); return; }
if (plane.id == Selected) {marker.set("labelStyle", { opacity: 0.66, 'background-color': 'greenyellow'}); return; }
marker.set("labelStyle", {opacity: 0.6, 'background-color': 'LimeGreen'});
}
function fetchData() {
if ( Gmap.getBounds()==null) {
return;
}
var vps = Gmap.getBounds().getSouthWest().lat().toFixed(2);
var vpw = Gmap.getBounds().getSouthWest().lng().toFixed(2);
var vpn = Gmap.getBounds().getNorthEast().lat().toFixed(2);
var vpe = Gmap.getBounds().getNorthEast().lng().toFixed(2);
var viewpoint = '&vpn='+vpn+'&vpe='+vpe+'&vps='+vps+'&vpw='+vpw
var latcntr = Gmap.getCenter().lat().toFixed(2);
var loncntr = Gmap.getCenter().lng().toFixed(2);
var alt_min = "";
var alt_max = "";
if ( Filters.enable_alt ) {
if ( typeof Filters.altitude[0]!=="undefined" && Filters.altitude[0]!==null ) {
alt_min = "&altitude.from=" + Filters.altitude[0];
}
if ( typeof Filters.altitude[1]!=="undefined" && Filters.altitude[1]!==null ) {
alt_max = "&altitude.to=" + Filters.altitude[1];
}
}
getJSON(rcd_globals.fcgipath+'clients.json',
function(data_unfiltered) {
var stillhere = {}
var data = data_unfiltered["TLS"];
for (var j=0; j < data.length; j++) {
var plane = data[j];
var marker1 = null;
stillhere[plane.id] = true;
plane.fli = $.trim(plane.fli);
/* update */
if (Planes[plane.id]) {
marker1 = Planes[plane.id].marker1;
var newpos = new google.maps.LatLng(plane.lat, plane.lon);
/* update flight number */
marker1.setIcon(getIconForPlane(plane));
marker1.setPosition(newpos);
marker1.set("labelContent", labelDataTable(plane));
labelSetAnchor(plane, marker1, 12);
labelSetStyle(plane, marker1);
marker1.label.draw();
if (plane.id == Selected)
refreshSelectedInfo();
} else {
/* new flight */
marker1 = new MarkerWithLabel({
position: new google.maps.LatLng(plane.lat, plane.lon),
draggable: false,
raiseOnDrag: false,
zIndex: 70000,
map: Gmap,
labelContent: labelDataTable(plane),
labelAnchor: new google.maps.Point(0,0),
labelClass: "labels",
labelStyle: {},
labelZIndex: 60000,
icon: getIconForPlane(plane)
});
labelSetAnchor(plane,marker1,12);
labelSetStyle(plane,marker1);
/* Trap clicks for this marker. */
// marker1.addListener('click', selectPlane);
}
marker1.planehex = plane.id; /* for click */
plane.marker1 = marker1;
Planes[plane.id] = plane;
if (plane.fli.length == 0) {
marker1.setTitle(plane.id)
} else {
/* Popup window when mouse over aircraft icon */
var title = plane.reg+' ('+plane.id+')';
if (plane.org.length && plane.dst.length)
title += '\n'+plane.org+'>'+plane.dst;
marker1.setTitle(title)
}
}
NumPlanes = data.length;
/* Remove idle planes. */
for (var p in Planes) {
if (! stillhere[Planes[p].id]) {
if(Planes[p].id == Selected) {
deselectPlane();
}
Planes[p].marker1.setMap(null);
delete Planes[p];
}
}
});
}
var CenterLat = 0.0;
var CenterLon = 0.0;
var DistanceUnit = 0;
var Zoomlevel = 7;
var MapStyle = "terrain";
$(document).ready(function() {
getJSON( rcd_globals.fcgipath+"param.json?param=ownlat,ownlon,distanceunit", function(params) {
CenterLat = params.ownlat;
CenterLon = params.ownlon;
DistanceUnit = params.distanceunit ? "km" : "nm";
initialize();
});
});
function initialize()
{
/* There is no info_box_table without refreshGeneralInfo() */
refreshGeneralInfo();
map_box = document.getElementById('map_box');
map_info_box = document.getElementById('map_info_box');
flight_info_box = document.getElementById('flight_info_box');
info_box_table = document.getElementById('info_box_table');
hide_info = document.getElementById('hide_info');
hide_info_btn = document.getElementById('hide_info_btn');
document.getElementById("btn_hide_info_box").onclick = toggleInfoBox;
my_cookie = getCookie('clients_gmap_init');
if (my_cookie) $.extend(GmapInit, JSON.parse(my_cookie));
Gmap = new google.maps.Map(map_box,{
disableDefaultUI: true,
center: new google.maps.LatLng(GmapInit.CenterLat, GmapInit.CenterLon),
zoom: GmapInit.Zoomlevel,
zoomControl: true,
zoomControlOptions: {
position: google.maps.ControlPosition.RIGHT_BOTTOM
},
scaleControl: false,
streetViewControl: false
});
// switch(MapStyle)
// {
// case "grey":
// Gmap.mapTypes.set('Grey map', rcmaptype1);
// Gmap.setMapTypeId('Grey map');
// break;
// case "terrain":
// Gmap.setMapTypeId(google.maps.MapTypeId.TERRAIN);
// break;
// case "roadmap":
// Gmap.setMapTypeId(google.maps.MapTypeId.ROADMAP);
// break;
// case "satellite":
// Gmap.setMapTypeId(google.maps.MapTypeId.SATELLITE);
// break;
// case "hybrid":
// Gmap.setMapTypeId(google.maps.MapTypeId.HYBRID);
// break;
// default:
// Gmap.setMapTypeId(google.maps.MapTypeId.TERRAIN);
// }
var currCntr = new google.maps.LatLng (GmapInit.CenterLat, GmapInit.CenterLon);
// Gmap.addListener('click', deselectPlane);
Gmap.addListener('zoom_changed', function() {
GmapInit.Zoomlevel=Gmap.getZoom();
setCookie('clients_gmap_init',JSON.stringify(GmapInit),9999);
});
Gmap.addListener('dragend', function() {
var currCntr = new google.maps.LatLng;
GmapInit.CenterLat = Gmap.getCenter().lat();
GmapInit.CenterLon = Gmap.getCenter().lng();
setCookie("pos", currCntr, 9999);
setCookie('clients_gmap_init',JSON.stringify(GmapInit),9999);
});
hideInfoBox();
var refreshLoop = function() {
return function() {
if (!typeof Filters.refreshtime !== "number") {
var timeout = 1000;
} else {
var timeout = Math.max(1000, 1000 * refreshtime);
}
window.setTimeout(refreshLoop, timeout);
if( rcd_globals.initialized ) {
fetchData();
}
}
}();
window.setTimeout(refreshLoop, 0);
}