From 29509d96333b8ad2d49dfaf98cff765a21222628 Mon Sep 17 00:00:00 2001 From: Oliver Jowett Date: Wed, 7 Jan 2015 17:18:33 +0000 Subject: [PATCH] Make PlaneObject a class. Rearrange internal storage of positions. Maintain sitedist within PlaneObject, not externally. Clean up speed/dist/etc formatting. Show both metric & imperial values in the plane detail infobox. --- public_html/gmap.html | 2 +- public_html/planeObject.js | 622 ++++++++++++++++++------------------- public_html/script.js | 208 +++++++------ 3 files changed, 419 insertions(+), 413 deletions(-) diff --git a/public_html/gmap.html b/public_html/gmap.html index 261a2e0..20dc878 100644 --- a/public_html/gmap.html +++ b/public_html/gmap.html @@ -117,7 +117,7 @@ - Lat/Long: n/a + Position: n/a diff --git a/public_html/planeObject.js b/public_html/planeObject.js index 5058647..8af6f24 100644 --- a/public_html/planeObject.js +++ b/public_html/planeObject.js @@ -28,333 +28,329 @@ var PlaneSvg = "M 0,0 " + "-2.858644 -0.145909,-5.208974 -0.209316,-5.222958 -0.06341,-0.01399 -0.974464," + "-0.0493 -2.024551,-0.07845 L 23.247235,38.61921 18.831373,39.8906 C 4.9432155," + "43.88916 4.2929558,44.057819 3.4954426,43.86823 2.7487826,43.690732 2.2007966," + - "42.916622 1.9565564,41.694305 z" + "42.916622 1.9565564,41.694305 z"; - -var planeObject = { - // Basic location information - altitude : null, - speed : null, - track : null, - latitude : null, - longitude : null, - +function PlaneObject(icao) { // Info about the plane - flight : null, - squawk : null, - icao : null, - is_selected : false, + this.icao = icao; + this.flight = null; + this.squawk = null; + this.selected = false; + + // Basic location information + this.altitude = null; + this.speed = null; + this.track = null; + this.position = null; + this.sitedist = null; // Data packet numbers - messages : null, + this.messages = null; // Track history as a series of line segments - track_linesegs : [], - + this.track_linesegs = []; + this.history_size = 0; + // When was this last updated (receiver timestamp) - last_message_time : null, - last_position_time : null, + this.last_message_time = null; + this.last_position_time = null; // When was this last updated (seconds before last update) - seen : null, - seen_pos : null, + this.seen = null; + this.seen_pos = null; - history_size : 0, - visible : true, + // Display info + this.visible = true; + this.marker = null; + this.icon = { strokeWeight: 1, + path: PlaneSvg, + scale: 0.4, + fillColor: MarkerColor, + fillOpacity: 0.9, + anchor: new google.maps.Point(32, 32), // Set anchor to middle of plane. + rotation: 0 }; +} - // GMap Details - marker : null, - icon : { - strokeWeight: 1, - path: PlaneSvg, - scale: 0.4, - fillColor: MarkerColor, - fillOpacity: 0.9, - anchor: new google.maps.Point(32, 32), // Set anchor to middle of plane. - rotation: 0 - }, +// Appends data to the running track so we can get a visual tail on the plane +// Only useful for a long running browser session. +PlaneObject.prototype.updateTrack = function() { + var here = this.position; - // Appends data to the running track so we can get a visual tail on the plane - // Only useful for a long running browser session. - updateTrack : function() { - var here = new google.maps.LatLng(this.latitude, this.longitude); - if (this.track_linesegs.length == 0) { - // Brand new track - //console.log(this.icao + " new track"); - var newseg = { track : new google.maps.MVCArray([here,here]), - line : null, - head_update : this.last_position_time, - tail_update : this.last_position_time, - estimated : false, - ground : (this.altitude === "ground") - }; - this.track_linesegs.push(newseg); - this.history_size += 2; - return; - } - - var lastseg = this.track_linesegs[this.track_linesegs.length - 1]; - var lastpos = lastseg.track.getAt(lastseg.track.getLength() - 1); - var elapsed = (this.last_position_time - lastseg.head_update); - - var new_data = (here !== lastpos); - var est_track = (elapsed > 5); - var ground_track = (this.altitude === "ground"); - - if (!new_data) - return false; - - if (est_track) { - if (!lastseg.estimated) { - // >5s gap in data, create a new estimated segment - //console.log(this.icao + " switching to estimated"); - this.track_linesegs.push({ track : new google.maps.MVCArray([lastpos, here]), - line : null, - head_update : this.last_position_time, - estimated : true }); - this.history_size += 2; - return true; - } - - // Append to ongoing estimated line - //console.log(this.icao + " extending estimated (" + lastseg.track.getLength() + ")"); - lastseg.track.push(here); - lastseg.head_update = this.last_position_time; - this.history_size++; - return true; - } - - if (lastseg.estimated) { - // We are back to good data. - //console.log(this.icao + " switching to good track"); - this.track_linesegs.push({ track : new google.maps.MVCArray([lastpos, here]), - line : null, - head_update : this.last_position_time, - tail_update : this.last_position_time, - estimated : false, - ground : (this.altitude === "ground") }); - this.history_size += 2; - return true; - } - - if ( (lastseg.ground && this.altitude !== "ground") || - (!lastseg.ground && this.altitude === "ground") ) { - //console.log(this.icao + " ground state changed"); - // Create a new segment as the ground state changed. - // assume the state changed halfway between the two points - var midpoint = google.maps.geometry.spherical.interpolate(lastpos,here,0.5); - lastseg.track.push(midpoint); - this.track_linesegs.push({ track : new google.maps.MVCArray([midpoint,here,here]), - line : null, - head_update : this.last_position_time, - tail_update : this.last_position_time, - estimated : false, - ground : (this.altitude === "ground") }); - this.history_size += 4; - return true; - } - - // Add more data to the existing track. - // We only retain some historical points, at 5+ second intervals, - // plus the most recent point - if (this.last_position_time - lastseg.tail_update >= 5) { - // enough time has elapsed; retain the last point and add a new one - //console.log(this.icao + " retain last point"); - lastseg.track.push(here); - lastseg.tail_update = lastseg.head_update; - this.history_size ++; - } else { - // replace the last point with the current position - lastseg.track.setAt(lastseg.track.getLength()-1, here); - } - lastseg.head_update = this.last_position_time; - return true; - }, - - // This is to remove the line from the screen if we deselect the plane - clearLines : function() { - for (var i = 0; i < this.track_linesegs.length; ++i) { - var seg = this.track_linesegs[i]; - if (seg.line !== null) { - seg.line.setMap(null); - seg.line = null; - } - } - }, - - updateIcon : function() { - var col = MarkerColor; - - // If this marker is selected we should make it lighter than the rest. - if (this.is_selected) - col = SelectedColor; - - // If we have not seen a recent update, change color - if (this.seen > 15) - col = StaleColor; - - // If the squawk code is one of the international emergency codes, - // match the info window alert color. - if (this.squawk in SpecialSquawks) - col = SpecialSquawks[this.squawk].markerColor; - - var weight = this.is_selected ? 2 : 1; - var rotation = (this.track === null ? 0 : this.track); - - if (col === this.icon.fillColor && weight === this.icon.strokeWeight && rotation === this.icon.rotation) - return false; // no changes - - this.icon.fillColor = col; - this.icon.strokeWeight = weight; - this.icon.rotation = rotation; - if (this.marker) - this.marker.setIcon(this.icon); - - return true; - }, - - // TODO: Trigger actions of a selecting a plane - selectPlane : function(){ - selectPlaneByHex(this.icao); - }, - - // Update our data - updateData : function(receiver_timestamp, data){ - // Update all of our data - this.icao = data.hex; - this.messages = data.messages; - this.last_message_time = receiver_timestamp - data.seen; - - if (typeof data.altitude !== "undefined") - this.altitude = data.altitude; - if (typeof data.speed !== "undefined") - this.speed = data.speed; - if (typeof data.track !== "undefined") - this.track = data.track; - if (typeof data.lat !== "undefined") { - this.latitude = data.lat; - this.longitude = data.lon; - this.last_position_time = receiver_timestamp - data.seen_pos; - } - if (typeof data.flight !== "undefined") - this.flight = data.flight; - if (typeof data.squawk !== "undefined") - this.squawk = data.squawk; - }, - - updateTick : function(receiver_timestamp) { - // recompute seen and seen_pos - this.seen = receiver_timestamp - this.last_message_time; - this.seen_pos = (this.last_position_time === null ? null : receiver_timestamp - this.last_position_time); - - // If no packet in over 58 seconds, clear the plane. - if (this.seen > 58) { - if (this.visible) { - //console.log("hiding " + this.icao); - this.clearMarker(); - this.visible = false; - if (SelectedPlane == this.icao) - selectPlaneByHex(null); - } - } else { - this.visible = true; - if (this.latitude !== null) { - if (this.updateTrack()) { - this.updateLines(); - this.updateMarker(true); - } else { - this.updateMarker(false); // didn't move - } - } - } - }, - - clearMarker: function() { - if (this.marker) { - this.marker.setMap(null); - this.marker = null; - } - }, - - // Update our marker on the map - updateMarker: function(moved) { - if (!this.visible) { - this.clearMarker(); - return; - } - - if (this.marker) { - if (moved) - this.marker.setPosition(new google.maps.LatLng(this.latitude, this.longitude)); - this.updateIcon(); - } else { - this.updateIcon(); - this.marker = new google.maps.Marker({ - position: new google.maps.LatLng(this.latitude, this.longitude), - map: GoogleMap, - icon: this.icon, - visible: true - }); - - // This is so we can match icao address - this.marker.icao = this.icao; - - // Trap clicks for this marker. - google.maps.event.addListener(this.marker, 'click', this.selectPlane); - } - - // Setting the marker title - if (this.flight === null || this.flight.length == 0) { - this.marker.setTitle(this.hex); - } else { - this.marker.setTitle(this.flight+' ('+this.icao+')'); - } - }, + if (this.track_linesegs.length == 0) { + // Brand new track + //console.log(this.icao + " new track"); + var newseg = { track : new google.maps.MVCArray([here,here]), + line : null, + head_update : this.last_position_time, + tail_update : this.last_position_time, + estimated : false, + ground : (this.altitude === "ground") + }; + this.track_linesegs.push(newseg); + this.history_size += 2; + return; + } - // Update our planes tail line, - updateLines: function() { - if (!this.is_selected) - return; - - for (var i = 0; i < this.track_linesegs.length; ++i) { - var seg = this.track_linesegs[i]; - if (seg.line === null) { - // console.log("create line for seg " + i + " with " + seg.track.getLength() + " points" + (seg.estimated ? " (estimated)" : "")); - // for (var j = 0; j < seg.track.getLength(); j++) { - // console.log(" point " + j + " at " + seg.track.getAt(j).lat() + "," + seg.track.getAt(j).lng()); - // } - - if (seg.estimated) { - var lineSymbol = { - path: 'M 0,-1 0,1', - strokeOpacity : 1, - strokeColor : '#804040', - strokeWeight : 2, - scale: 2 - }; - - seg.line = new google.maps.Polyline({ - path: seg.track, - strokeOpacity: 0, - icons: [{ - icon: lineSymbol, - offset: '0', - repeat: '10px' }], - map : GoogleMap }); - } else { - seg.line = new google.maps.Polyline({ - path: seg.track, - strokeOpacity: 1.0, - strokeColor: (seg.ground ? '#408040' : '#000000'), - strokeWeight: 3, - map: GoogleMap }); - } - } + var lastseg = this.track_linesegs[this.track_linesegs.length - 1]; + var lastpos = lastseg.track.getAt(lastseg.track.getLength() - 1); + var elapsed = (this.last_position_time - lastseg.head_update); + + var new_data = (here !== lastpos); + var est_track = (elapsed > 5); + var ground_track = (this.altitude === "ground"); + + if (!new_data) + return false; + + if (est_track) { + if (!lastseg.estimated) { + // >5s gap in data, create a new estimated segment + //console.log(this.icao + " switching to estimated"); + this.track_linesegs.push({ track : new google.maps.MVCArray([lastpos, here]), + line : null, + head_update : this.last_position_time, + estimated : true }); + this.history_size += 2; + return true; } - }, + + // Append to ongoing estimated line + //console.log(this.icao + " extending estimated (" + lastseg.track.getLength() + ")"); + lastseg.track.push(here); + lastseg.head_update = this.last_position_time; + this.history_size++; + return true; + } + + if (lastseg.estimated) { + // We are back to good data. + //console.log(this.icao + " switching to good track"); + this.track_linesegs.push({ track : new google.maps.MVCArray([lastpos, here]), + line : null, + head_update : this.last_position_time, + tail_update : this.last_position_time, + estimated : false, + ground : (this.altitude === "ground") }); + this.history_size += 2; + return true; + } + + if ( (lastseg.ground && this.altitude !== "ground") || + (!lastseg.ground && this.altitude === "ground") ) { + //console.log(this.icao + " ground state changed"); + // Create a new segment as the ground state changed. + // assume the state changed halfway between the two points + var midpoint = google.maps.geometry.spherical.interpolate(lastpos,here,0.5); + lastseg.track.push(midpoint); + this.track_linesegs.push({ track : new google.maps.MVCArray([midpoint,here,here]), + line : null, + head_update : this.last_position_time, + tail_update : this.last_position_time, + estimated : false, + ground : (this.altitude === "ground") }); + this.history_size += 4; + return true; + } + + // Add more data to the existing track. + // We only retain some historical points, at 5+ second intervals, + // plus the most recent point + if (this.last_position_time - lastseg.tail_update >= 5) { + // enough time has elapsed; retain the last point and add a new one + //console.log(this.icao + " retain last point"); + lastseg.track.push(here); + lastseg.tail_update = lastseg.head_update; + this.history_size ++; + } else { + // replace the last point with the current position + lastseg.track.setAt(lastseg.track.getLength()-1, here); + } + lastseg.head_update = this.last_position_time; + return true; +}; - destroy : function() { - this.clearLines(); - this.clearMarker(); +// This is to remove the line from the screen if we deselect the plane +PlaneObject.prototype.clearLines = function() { + for (var i = 0; i < this.track_linesegs.length; ++i) { + var seg = this.track_linesegs[i]; + if (seg.line !== null) { + seg.line.setMap(null); + seg.line = null; + } } }; + +PlaneObject.prototype.updateIcon = function() { + var col = MarkerColor; + + // If this marker is selected we should make it lighter than the rest. + if (this.is_selected) + col = SelectedColor; + + // If we have not seen a recent update, change color + if (this.seen > 15) + col = StaleColor; + + // If the squawk code is one of the international emergency codes, + // match the info window alert color. + if (this.squawk in SpecialSquawks) + col = SpecialSquawks[this.squawk].markerColor; + + var weight = this.is_selected ? 2 : 1; + var rotation = (this.track === null ? 0 : this.track); + + if (col === this.icon.fillColor && weight === this.icon.strokeWeight && rotation === this.icon.rotation) + return false; // no changes + + this.icon.fillColor = col; + this.icon.strokeWeight = weight; + this.icon.rotation = rotation; + if (this.marker) + this.marker.setIcon(this.icon); + + return true; +}; + +// Update our data +PlaneObject.prototype.updateData = function(receiver_timestamp, data) { + // Update all of our data + this.icao = data.hex; + this.messages = data.messages; + this.last_message_time = receiver_timestamp - data.seen; + + if (typeof data.altitude !== "undefined") + this.altitude = data.altitude; + if (typeof data.speed !== "undefined") + this.speed = data.speed; + if (typeof data.track !== "undefined") + this.track = data.track; + if (typeof data.lat !== "undefined") { + this.position = new google.maps.LatLng(data.lat, data.lon); + this.last_position_time = receiver_timestamp - data.seen_pos; + + if (SitePosition !== null) { + this.sitedist = google.maps.geometry.spherical.computeDistanceBetween (SitePosition, this.position); + } + } + if (typeof data.flight !== "undefined") + this.flight = data.flight; + if (typeof data.squawk !== "undefined") + this.squawk = data.squawk; +}; + +PlaneObject.prototype.updateTick = function(receiver_timestamp) { + // recompute seen and seen_pos + this.seen = receiver_timestamp - this.last_message_time; + this.seen_pos = (this.last_position_time === null ? null : receiver_timestamp - this.last_position_time); + + // If no packet in over 58 seconds, clear the plane. + if (this.seen > 58) { + if (this.visible) { + //console.log("hiding " + this.icao); + this.clearMarker(); + this.visible = false; + if (SelectedPlane == this.icao) + selectPlaneByHex(null); + } + } else { + this.visible = true; + if (this.position !== null) { + if (this.updateTrack()) { + this.updateLines(); + this.updateMarker(true); + } else { + this.updateMarker(false); // didn't move + } + } + } +}; + +PlaneObject.prototype.clearMarker = function() { + if (this.marker) { + this.marker.setMap(null); + google.maps.event.clearListeners(this.marker, 'click'); + this.marker = null; + } +}; + +// Update our marker on the map +PlaneObject.prototype.updateMarker = function(moved) { + if (!this.visible) { + this.clearMarker(); + return; + } + + if (this.marker) { + if (moved) + this.marker.setPosition(this.position); + this.updateIcon(); + } else { + this.updateIcon(); + this.marker = new google.maps.Marker({ + position: this.position, + map: GoogleMap, + icon: this.icon, + visible: true + }); + + // This is so we can match icao address + this.marker.icao = this.icao; + + // Trap clicks for this marker. + google.maps.event.addListener(this.marker, 'click', selectPlaneByHex.bind(undefined,this.icao)); + } + + // Setting the marker title + if (this.flight === null || this.flight.length == 0) { + this.marker.setTitle(this.hex); + } else { + this.marker.setTitle(this.flight+' ('+this.icao+')'); + } +}; + +// Update our planes tail line, +PlaneObject.prototype.updateLines = function() { + if (!this.is_selected) + return; + + for (var i = 0; i < this.track_linesegs.length; ++i) { + var seg = this.track_linesegs[i]; + if (seg.line === null) { + // console.log("create line for seg " + i + " with " + seg.track.getLength() + " points" + (seg.estimated ? " (estimated)" : "")); + // for (var j = 0; j < seg.track.getLength(); j++) { + // console.log(" point " + j + " at " + seg.track.getAt(j).lat() + "," + seg.track.getAt(j).lng()); + // } + + if (seg.estimated) { + var lineSymbol = { + path: 'M 0,-1 0,1', + strokeOpacity : 1, + strokeColor : '#804040', + strokeWeight : 2, + scale: 2 + }; + + seg.line = new google.maps.Polyline({ + path: seg.track, + strokeOpacity: 0, + icons: [{ + icon: lineSymbol, + offset: '0', + repeat: '10px' }], + map : GoogleMap }); + } else { + seg.line = new google.maps.Polyline({ + path: seg.track, + strokeOpacity: 1.0, + strokeColor: (seg.ground ? '#408040' : '#000000'), + strokeWeight: 3, + map: GoogleMap }); + } + } + } +}; + +PlaneObject.prototype.destroy = function() { + this.clearLines(); + this.clearMarker(); +}; diff --git a/public_html/script.js b/public_html/script.js index b8e682d..f0464ce 100644 --- a/public_html/script.js +++ b/public_html/script.js @@ -39,12 +39,10 @@ function fetchData() { if (Planes[hex]) { plane = Planes[hex]; } else { - plane = jQuery.extend(true, {}, planeObject); - + plane = new PlaneObject(hex); plane.tr = PlaneRowTemplate.cloneNode(true); plane.tr.cells[0].textContent = hex; // this won't change - plane.tr.addEventListener('click', $.proxy(plane.selectPlane, plane)); - plane.sitedist = null; + plane.tr.addEventListener('click', selectPlaneByHex.bind(undefined,hex)); Planes[hex] = plane; PlanesOrdered.push(plane); @@ -282,6 +280,98 @@ function reaper() { refreshSelected(); } +// +// formatting helpers +// + +var TrackDirections = ["North","Northeast","East","Southeast","South","Southwest","West","Northwest"]; + +// track in degrees (0..359) +function format_track_brief(track) { + return Math.round(track); +} + +// track in degrees (0..359) +function format_track_long(track) { + var trackDir = Math.floor((360 + track % 360 + 22.5) / 45) % 8; + return Math.round(track) + "\u00b0 (" + TrackDirections[trackDir] + ")"; +} + +// alt in ft +function format_altitude_brief(alt) { + if (alt === null) + return ""; + if (alt === "ground") + return "ground"; + + if (Metric) + return Math.round(alt / 3.2828); + else + return Math.round(alt); +} + +// alt in ft +function format_altitude_long(alt) { + if (alt === null) + return "n/a"; + if (alt === "ground") + return "on ground"; + + if (Metric) + return Math.round(alt / 3.2828) + " m / " + Math.round(alt) + " ft"; + else + return Math.round(alt) + " ft / " + Math.round(alt / 3.2828) + " m"; +} + +// speed in kts +function format_speed_brief(speed) { + if (speed === null) + return ""; + + if (Metric) + return Math.round(speed * 1.852); + else + return Math.round(speed); +} + +// speed in kts +function format_speed_long(speed) { + if (speed === null) + return "n/a"; + + if (Metric) + return Math.round(speed * 1.852) + " km/h / " + Math.round(speed) + " kt"; + else + return Math.round(speed) + " kt / " + Math.round(speed * 1.852) + " km/h"; +} + +// dist in metres +function format_distance_brief(dist) { + if (dist === null) + return ""; + + if (Metric) + return (dist/1000).toFixed(1); + else + return (dist/1852).toFixed(1); +} + +// dist in metres +function format_distance_long(dist) { + if (dist === null) + return "n/a"; + + if (Metric) + return (dist/1000).toFixed(1) + " km / " + (dist/1852).toFixed(1) + " NM"; + else + return (dist/1852).toFixed(1) + " NM / " + (dist/1000).toFixed(1) + " km"; +} + +// p as a LatLng +function format_latlng(p) { + return p.lat().toFixed(5) + "\u00b0, " + p.lng().toFixed(5) + "\u00b0"; +} + // Refresh the detail window about the plane function refreshSelected() { var selected = false; @@ -321,14 +411,7 @@ function refreshSelected() { emerg.className = 'hidden'; } - if (selected.altitude === null) - $("#selected_altitude").text("n/a"); - else if (selected.altitude === "ground") - $("#selected_altitude").text("on ground"); - else if (Metric) - $("#selected_altitude").text(Math.round(selected.altitude / 3.2828) + ' m'); - else - $("#selected_altitude").text(Math.round(selected.altitude) + ' ft'); + $("#selected_altitude").text(format_altitude_long(selected.altitude)); if (selected.squawk === null || selected.squawk === '0000') { $('#selected_squawk').text('n/a'); @@ -336,21 +419,9 @@ function refreshSelected() { $('#selected_squawk').text(selected.squawk); } - if (selected.speed === null) { - $('#selected_speed').text('n/a'); - } else if (Metric) { - $('#selected_speed').text(Math.round(selected.speed * 1.852) + ' km/h'); - } else { - $('#selected_speed').text(Math.round(selected.speed) + ' kt'); - } - + $('#selected_speed').text(format_speed_long(selected.speed)); $('#selected_icao').text(selected.icao); - - if (selected.track === null) { - $('#selected_track').text('n/a'); - } else { - $('#selected_track').text(selected.track + '\u00b0' + ' (' + trackLongName(selected.track) + ')'); - } + $('#selected_track').text(format_track_long(selected.track)); if (selected.seen <= 1) { $('#selected_seen').text('now'); @@ -358,72 +429,20 @@ function refreshSelected() { $('#selected_seen').text(selected.seen + 's ago'); } - if (selected.latitude === null) { + if (selected.position === null) { $('#selected_position').text('n/a'); } else { if (selected.seen_pos > 1) { - $('#selected_position').text(selected.latitude + ', ' + selected.longitude + " (" + selected.seen_pos + "s ago)"); + $('#selected_position').text(format_latlng(selected.position) + " (" + selected.seen_pos + "s ago)"); } else { - $('#selected_position').text(selected.latitude + ', ' + selected.longitude); + $('#selected_position').text(format_latlng(selected.position)); } } - - if (selected.sitedist !== null) { - var dist = selected.sitedist; - if (Metric) { - dist /= 1000; - } else { - dist /= 1852; - } - - dist = (Math.round((dist)*10)/10).toFixed(1); - - $('#selected_sitedist').text(dist + (Metric ? ' km' : ' NM')); - } else { - $('#selected_sitedist').text("n/a"); - } -} - -function trackShortName(track) { - var trackIndex = Math.floor((360 + track % 360 + 22.5) / 45) % 8; - return ["N","NE","E","SE","S","SW","W","NW"][trackIndex]; -} - -function trackLongName(track) { - var trackIndex = Math.floor((360 + track % 360 + 22.5) / 45) % 8; - return ["North","Northeast","East","Southeast","South","Southwest","West","Northwest"][trackIndex]; -} - -// Refeshes the larger table of all the planes - -function format_altitude(alt) { - if (alt === null) - return ""; - else if (alt === "ground") - return "ground"; - else if (Metric) - return Math.round(alt / 3.2828); - else - return Math.round(alt); -} - -function format_speed(speed) { - if (speed === null) - return ""; - else if (Metric) - return Math.round(speed * 1.852); - else - return Math.round(speed); -} - -function format_distance(dist) { - if (Metric) { - return (Math.round(dist/100) / 10).toFixed(1); - } else { - return (Math.round(dist/185.2) / 10).toFixed(1); - } + + $('#selected_sitedist').text(format_distance_long(selected.sitedist)); } +// Refreshes the larger table of all the planes function refreshTableInfo() { var show_squawk_warning = false; @@ -440,7 +459,7 @@ function refreshTableInfo() { TrackedAircraft++; var classes = "plane_table_row"; - if (tableplane.latitude !== null) + if (tableplane.position !== null) classes += " vPosition"; if (tableplane.icao == SelectedPlane) classes += " selected"; @@ -453,23 +472,14 @@ function refreshTableInfo() { // ICAO doesn't change tableplane.tr.cells[1].textContent = (tableplane.flight !== null ? tableplane.flight : ""); tableplane.tr.cells[2].textContent = (tableplane.squawk !== null ? tableplane.squawk : ""); - tableplane.tr.cells[3].textContent = format_altitude(tableplane.altitude); - tableplane.tr.cells[4].textContent = format_speed(tableplane.speed); + tableplane.tr.cells[3].textContent = format_altitude_brief(tableplane.altitude); + tableplane.tr.cells[4].textContent = format_speed_brief(tableplane.speed); - if (tableplane.latitude !== null) + if (tableplane.position !== null) ++TrackedAircraftPositions; - // Add distance column to table if site coordinates are provided - if (SitePosition !== null && tableplane.latitude !== null) { - var planeLatLon = new google.maps.LatLng(tableplane.latitude, tableplane.longitude); - var dist = google.maps.geometry.spherical.computeDistanceBetween (SitePosition, planeLatLon); - tableplane.tr.cells[5].textContent = format_distance(dist); - tableplane.sitedist = dist; - } else { - tableplane.tr.cells[5].textContent = ""; - } - - tableplane.tr.cells[6].textContent = (tableplane.track !== null ? tableplane.track : ""); + tableplane.tr.cells[5].textContent = format_distance_brief(tableplane.sitedist); + tableplane.tr.cells[6].textContent = format_track_brief(tableplane.track); tableplane.tr.cells[7].textContent = tableplane.messages; tableplane.tr.cells[8].textContent = tableplane.seen;