Map = null; CenterLat = 45.0; CenterLon = 9.0; ZoomLvl = 5; Planes = {}; PlanesOnMap = 0; PlanesOnGrid = 0; Selected = null; if (localStorage['CenterLat']) { CenterLat = Number(localStorage['CenterLat']); } if (localStorage['CenterLon']) { CenterLon = Number(localStorage['CenterLon']); } if (localStorage['ZoomLvl']) { ZoomLvl = Number(localStorage['ZoomLvl']); } function getIconForPlane(plane, deselect) { var selected = false; var track = 0; var r = 255, g = 255, b = 0; var maxalt = 40000; // Max altitude in the average case var invalt = 0; // If there is plane object if (plane) { invalt = maxalt-plane.altitude; if (Selected == plane.hex && !deselect) { selected = true; } track = plane.track; } if (invalt < 0) invalt = 0; b = parseInt(255/maxalt*invalt); return { strokeWeight: (selected ? 2 : 1), path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW, scale: 5, fillColor: 'rgb('+r+','+g+','+b+')', fillOpacity: 0.9, rotation: track }; } /* Gets hex code of selected plane as string or nothing. * * Select not valid ICAO24 (hex) address to clear selection. */ function selectPlane(selectedPlane) { if (selectedPlane.length) this.planehex = selectedPlane; // Deselect planes if (!Planes[this.planehex]) { if (Planes[Selected].marker) { Planes[Selected].marker.setIcon(getIconForPlane(Planes[Selected], true)); } Selected = null; refreshSelectedInfo(); refreshTableInfo(); return; } var old = Selected; Selected = this.planehex; if (Planes[old] && Planes[old].validposition) { // Remove the highlight in the previously selected plane. Planes[old].marker.setIcon(getIconForPlane(Planes[old])); } if (Planes[Selected].validposition) { Planes[Selected].marker.setIcon(getIconForPlane(Planes[Selected])); } refreshSelectedInfo(); refreshTableInfo(); } function refreshGeneralInfo() { var i = document.getElementById('geninfo'); i.innerHTML = PlanesOnMap + ' planes on map.
'; i.innerHTML += PlanesOnGrid + ' planes on grid.'; } function refreshSelectedInfo() { var i = document.getElementById('selinfo'); var p = Planes[Selected]; // If no plane is selected if (!p) { p = {}; p.flight = ""; p.hex = ""; p.squawk = ""; p.altitude = "0"; p.speed = "0"; p.lat = "lat"; p.lon = "lon"; p.messages = "0"; p.seen = "0"; } var html = ''; html += ''; html += ''; if (p.squawk != "0000") { html += ''; } else { html += ''; } html += ''; html += ''; if (p.validposition) { html += ''; } else { html += ''; } html += ''; html += ''; html += '
'+p.flight+' 
ICAO:'+p.hex+'
Squawk:'+p.squawk+'
Squawk:n/a
Altitude:'+p.altitude+' feet
Speed:'+p.speed+' knots
Coordinates:'+p.lat+', '+p.lon+'
Coordinates:n/a
Messages:'+p.messages+'
Seen:'+p.seen+' sec
'; i.innerHTML = html; } function refreshTableInfo() { var html = ''; html += ''; html += ''; html += ''; html += ''; for (var p in Planes) { var specialStyle = ""; if (p == Selected) { html += ''; } else { html += ''; } if (Planes[p].validposition) { specialStyle = 'bold'; } html += ''; html += ''; html += ''; html += ''; html += ''; html += ''; html += ''; html += ''; html += ''; } html += '
hexFlightSquawkAltitudeSpeedTrackMsgsSeen
' + Planes[p].hex + '' + Planes[p].flight + '' + Planes[p].squawk + '' + Planes[p].altitude + '' + Planes[p].speed + '' + Planes[p].track + '' + Planes[p].messages + '' + Planes[p].seen + '
'; document.getElementById('tabinfo').innerHTML = html; // Click event for table - lags sometimes for some reason? $('#tableinfo').find('tr').click( function(){ var hex = $(this).find('td:first').text(); selectPlane(hex); }); } function fetchData() { $.getJSON('data.json', function(data) { // Planes that are still with us, and set map count to 0 var stillhere = {} PlanesOnMap = 0; // Loop through all the planes in the data packet for (var j=0; j < data.length; j++) { // Set plane to be this particular plane in the data set var plane = data[j]; // Add to the still here list stillhere[plane.hex] = true; plane.flight = $.trim(plane.flight); // Set the marker to null, for now var marker = null; // Either update the data or add it if (Planes[plane.hex]) { // Declare our plane that we are working with from our old data set var myplane = Planes[plane.hex]; // If the has valid position, we should make a marker for it if (plane.validposition) { if (myplane.marker != null) { marker = myplane.marker; var icon = marker.getIcon(); var newpos = new google.maps.LatLng(plane.lat, plane.lon); marker.setPosition(newpos); marker.setIcon(getIconForPlane(plane)); PlanesOnMap++; } else { // Add new plane to map, dont ask me why this is needed here now... marker = new google.maps.Marker({ position: new google.maps.LatLng(plane.lat, plane.lon), map: Map, icon: getIconForPlane(plane) }); myplane.marker = marker; marker.planehex = plane.hex; PlanesOnMap++; // Trap clicks for this marker. google.maps.event.addListener(marker, 'click', selectPlane); } } // Update all the other information myplane.altitude = plane.altitude; myplane.speed = plane.speed; myplane.lat = plane.lat; myplane.lon = plane.lon; myplane.track = plane.track; myplane.flight = plane.flight; myplane.seen = plane.seen; myplane.messages = plane.messages; myplane.squawk = plane.squawk; myplane.validposition = plane.validposition; myplane.validtrack = plane.validtrack; // If this is a selected plane, refresh its data outside of the table if (myplane.hex == Selected) refreshSelectedInfo(); } else { // This is a new plane // Do we have a lat/long that is not 0? if (plane.validposition) { // Add new plane to map marker = new google.maps.Marker({ position: new google.maps.LatLng(plane.lat, plane.lon), map: Map, icon: getIconForPlane(plane) }); plane.marker = marker; marker.planehex = plane.hex; PlanesOnMap++; // Trap clicks for this marker. google.maps.event.addListener(marker, 'click', selectPlane); } // Copy the plane into Planes Planes[plane.hex] = plane; } // If we have lat/long, we must have a marker, so lets set the marker title if (plane.validposition) { if (plane.flight.length == 0) { marker.setTitle(plane.hex) } else { marker.setTitle(plane.flight+' ('+plane.hex+')') } } } // How many planes have we heard from? PlanesOnGrid = data.length; /* Remove idle planes. */ for (var p in Planes) { if (!stillhere[p]) { if (Planes[p].marker != null) Planes[p].marker.setMap(null); delete Planes[p]; } } refreshTableInfo(); refreshSelectedInfo(); }); } function checkTime(i) { if (i < 10) { return "0" + i; } return i; } function printTime() { var currentTime = new Date(); var hours = checkTime(currentTime.getUTCHours()); var minutes = checkTime(currentTime.getUTCMinutes()); var seconds = checkTime(currentTime.getUTCSeconds()); if (document.getElementById) { document.getElementById('utcTime').innerHTML = hours + ":" + minutes + ":" + seconds; } } function placeFooter() { var windHeight = $(window).height(); var footerHeight = $('#info_footer').height(); var offset = parseInt(windHeight) - parseInt(footerHeight); var footerWidth = parseInt($('#info_footer').width()); var infoWidth = parseInt($('#info').width()); var marginLeft = parseInt((infoWidth / 2) - (footerWidth / 2)); $('#info_footer').css('top', offset); $('#info_footer').css('margin-left', marginLeft); } function resetMap() { localStorage['CenterLat'] = 45.0; localStorage['CenterLon'] = 9.0; localStorage['ZoomLvl'] = 5; Map.setZoom(parseInt(localStorage['ZoomLvl'])); Map.setCenter(new google.maps.LatLng(parseInt(localStorage['CenterLat']), parseInt(localStorage['CenterLon']))); Selected = null; refreshSelectedInfo(); } function initialize() { var mapTypeIds = []; for(var type in google.maps.MapTypeId) { mapTypeIds.push(google.maps.MapTypeId[type]); } mapTypeIds.push("OSM"); var mapOptions = { center: new google.maps.LatLng(CenterLat, CenterLon), zoom: ZoomLvl, mapTypeId: google.maps.MapTypeId.ROADMAP, mapTypeControlOptions: { mapTypeIds: mapTypeIds, } }; Map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions); //Define OSM map type pointing at the OpenStreetMap tile server Map.mapTypes.set("OSM", new google.maps.ImageMapType({ getTileUrl: function(coord, zoom) { return "http://tile.openstreetmap.org/" + zoom + "/" + coord.x + "/" + coord.y + ".png"; }, tileSize: new google.maps.Size(256, 256), name: "OpenStreetMap", maxZoom: 18 })); // show footer at info-area $(function(){ $(window).resize(function(e){ placeFooter(); }); placeFooter(); // hide it before it's positioned $('#info_footer').css('display','inline'); }); // Listener for newly created Map google.maps.event.addListener(Map, 'center_changed', function() { localStorage['CenterLat'] = Map.getCenter().lat(); localStorage['CenterLon'] = Map.getCenter().lng(); }); google.maps.event.addListener(Map, 'zoom_changed', function() { localStorage['ZoomLvl'] = Map.getZoom(); }); google.maps.event.addListener(Map, 'click', function() { if (Selected) { selectPlane("xyzxyz"); // Select not valid ICAO24 (hex) address to clear selection. } Selected = null; refreshSelectedInfo(); refreshTableInfo(); }); // Setup our timer to poll from the server. window.setInterval(function() { fetchData(); refreshGeneralInfo(); }, 1000); // Faster timer, smoother things window.setInterval(function() { printTime(); }, 250); refreshGeneralInfo(); refreshSelectedInfo(); refreshTableInfo(); }