From 5cc04d4ca8c6023e33784f040d931957fcd56683 Mon Sep 17 00:00:00 2001 From: Matthias Wirth Date: Sat, 27 Jul 2019 15:19:17 +0200 Subject: [PATCH 1/2] SkyView: Fix aircraft trail handling Make aircraft trail handling more consistent and the code hopefully easier to understand. Fix position comparison (comparing array references does not work). When initially loading the SkyView webpage, there are sometimes gaps in the aircraft trails when the trail transitions from estimated/dotted to known/solid track. Fix elastic band style to handle estimated segments properly. --- public_html/planeObject.js | 46 +++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/public_html/planeObject.js b/public_html/planeObject.js index 6e81ffd..7f5bb81 100644 --- a/public_html/planeObject.js +++ b/public_html/planeObject.js @@ -44,6 +44,7 @@ function PlaneObject(icao) { this.version = null; this.prev_position = null; + this.prev_position_time = null; this.position = null; this.position_from_mlat = false this.sitedist = null; @@ -138,26 +139,29 @@ PlaneObject.prototype.isFiltered = function() { PlaneObject.prototype.updateTrack = function(estimate_time) { if (!this.position) return false; - if (this.position == this.prev_position) + if (this.prev_position && this.position[0] == this.prev_position[0] && this.position[1] == this.prev_position[1]) return false; var projHere = ol.proj.fromLonLat(this.position); var projPrev; + var prev_time; if (this.prev_position === null) { projPrev = projHere; + prev_time = this.last_position_time; } else { projPrev = ol.proj.fromLonLat(this.prev_position); + prev_time = this.prev_position_time; } this.prev_position = this.position; + this.prev_position_time = this.last_position_time; if (this.track_linesegs.length == 0) { // Brand new track //console.log(this.icao + " new track"); var newseg = { fixed: new ol.geom.LineString([projHere]), feature: null, - head_update: this.last_position_time, - tail_update: this.last_position_time, + update_time: this.last_position_time, estimated: false, ground: (this.altitude === "ground"), altitude: this.altitude @@ -168,7 +172,7 @@ PlaneObject.prototype.updateTrack = function(estimate_time) { } var lastseg = this.track_linesegs[this.track_linesegs.length - 1]; - var elapsed = (this.last_position_time - lastseg.head_update); + var elapsed = (this.last_position_time - prev_time); var est_track = (elapsed > estimate_time); var ground_track = (this.altitude === "ground"); @@ -179,16 +183,16 @@ PlaneObject.prototype.updateTrack = function(estimate_time) { // >5s gap in data, create a new estimated segment //console.log(this.icao + " switching to estimated"); lastseg.fixed.appendCoordinate(projPrev); - this.track_linesegs.push({ fixed: new ol.geom.LineString([projPrev, projHere]), + this.track_linesegs.push({ fixed: new ol.geom.LineString([projPrev]), feature: null, - head_update: this.last_position_time, + update_time: prev_time, altitude: 0, estimated: true }); this.history_size += 2; } else { // Keep appending to the existing dashed line; keep every point lastseg.fixed.appendCoordinate(projPrev); - lastseg.head_update = this.last_position_time; + lastseg.update_time = prev_time; this.history_size++; } @@ -198,16 +202,16 @@ PlaneObject.prototype.updateTrack = function(estimate_time) { if (lastseg.estimated) { // We are back to good data (we got two points close in time), switch back to // solid lines. + lastseg.fixed.appendCoordinate(projPrev); lastseg = { fixed: new ol.geom.LineString([projPrev]), feature: null, - head_update: this.last_position_time, - tail_update: this.last_position_time, + update_time: prev_time, estimated: false, ground: (this.altitude === "ground"), altitude: this.altitude }; this.track_linesegs.push(lastseg); - this.history_size ++; - // continue + this.history_size += 2; + return true; } if ( (lastseg.ground && this.altitude !== "ground") || @@ -218,29 +222,27 @@ PlaneObject.prototype.updateTrack = function(estimate_time) { // FIXME needs reimplementing post-google lastseg.fixed.appendCoordinate(projPrev); - this.track_linesegs.push({ fixed: new ol.geom.LineString([projPrev, projHere]), + this.track_linesegs.push({ fixed: new ol.geom.LineString([projPrev]), feature: null, - head_update: this.last_position_time, - tail_update: this.last_position_time, + update_time: prev_time, estimated: false, altitude: this.altitude, ground: (this.altitude === "ground") }); - this.history_size += 3; + this.history_size += 2; 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) { + if (prev_time - lastseg.update_time >= 5) { // enough time has elapsed; retain the last point and add a new one //console.log(this.icao + " retain last point"); - lastseg.fixed.appendCoordinate(projHere); - lastseg.tail_update = lastseg.head_update; + lastseg.fixed.appendCoordinate(projPrev); + lastseg.update_time = prev_time; this.history_size ++; } - lastseg.head_update = this.last_position_time; return true; }; @@ -657,7 +659,11 @@ PlaneObject.prototype.updateLines = function() { var lastfixed = lastseg.fixed.getCoordinateAt(1.0); var geom = new ol.geom.LineString([lastfixed, ol.proj.fromLonLat(this.position)]); this.elastic_feature = new ol.Feature(geom); - this.elastic_feature.setStyle(this.altitudeLines(lastseg.altitude)); + if (lastseg.estimated) { + this.elastic_feature.setStyle(estimateStyle); + } else { + this.elastic_feature.setStyle(this.altitudeLines(lastseg.altitude)); + } if (oldElastic < 0) { PlaneTrailFeatures.push(this.elastic_feature); From 207ca0c401ffba6d3bea2648303d29e3c83843bf Mon Sep 17 00:00:00 2001 From: Matthias Wirth Date: Sat, 27 Jul 2019 17:50:41 +0200 Subject: [PATCH 2/2] SkyView: Unify stale check for loading the history When loading the history, the check for stale aircraft tracks is done differently. This results in lots of dotted/stale track after opening the web page. Improve this by using the same 5 second timeout stale criterion to postions loaded from history. Add an additional check to better detect stale tracks when loading history positions that are spaced 30 seconds apart. --- public_html/planeObject.js | 21 ++++++++++++++++----- public_html/script.js | 2 +- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/public_html/planeObject.js b/public_html/planeObject.js index 7f5bb81..1a171bc 100644 --- a/public_html/planeObject.js +++ b/public_html/planeObject.js @@ -136,7 +136,7 @@ PlaneObject.prototype.isFiltered = function() { // 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(estimate_time) { +PlaneObject.prototype.updateTrack = function(receiver_timestamp, last_timestamp) { if (!this.position) return false; if (this.prev_position && this.position[0] == this.prev_position[0] && this.position[1] == this.prev_position[1]) @@ -172,9 +172,20 @@ PlaneObject.prototype.updateTrack = function(estimate_time) { } var lastseg = this.track_linesegs[this.track_linesegs.length - 1]; - var elapsed = (this.last_position_time - prev_time); - - var est_track = (elapsed > estimate_time); + + // Determine if track data are intermittent/stale + // Time difference between two position updates should not be much + // greater than the difference between data inputs + // MLAT data are given some more leeway + + var time_difference = (this.last_position_time - prev_time) - (receiver_timestamp - last_timestamp); + var stale_timeout = (this.position_from_mlat ? 30 : 5); + var est_track = (time_difference > stale_timeout); + + // Also check if the position was already stale when it was exported by dump1090 + // Makes stale check more accurate for history points spaced 30 seconds apart + est_track = est_track || ((receiver_timestamp - this.last_position_time) > stale_timeout); + var ground_track = (this.altitude === "ground"); if (est_track) { @@ -557,7 +568,7 @@ PlaneObject.prototype.updateTick = function(receiver_timestamp, last_timestamp) } else { if (this.position !== null && (this.selected || this.seen_pos < 60)) { this.visible = true; - if (this.updateTrack(receiver_timestamp - last_timestamp + (this.position_from_mlat ? 30 : 5))) { + if (this.updateTrack(receiver_timestamp, last_timestamp)) { this.updateLines(); this.updateMarker(true); } else { diff --git a/public_html/script.js b/public_html/script.js index ad372f1..df90681 100644 --- a/public_html/script.js +++ b/public_html/script.js @@ -444,7 +444,7 @@ function end_load_history() { console.log("Updating tracks at: " + now); for (var i = 0; i < PlanesOrdered.length; ++i) { var plane = PlanesOrdered[i]; - plane.updateTrack((now - last) + 1); + plane.updateTrack(now, last); } last = now;