diff --git a/html/early.js b/html/early.js index 39c25bc..6dafd79 100644 --- a/html/early.js +++ b/html/early.js @@ -77,11 +77,11 @@ try { if (search.has('L3Harris') || search.has('l3harris')) l3harris = true; - if (search.has('replay')) { + if (search.has('replay') || replay) { replay = { ts: (new Date().getTime() - 3600 * 1000), ival: 60 * 1000, - speed: 5, + speed: 20, defer: $.Deferred(), }; let xhrOverride = new XMLHttpRequest(); @@ -97,14 +97,13 @@ try { let req = $.ajax({ url: URL, method: 'GET', - num: i, xhr: function() { return xhrOverride; } }); req.done(function (responseData) { replay.data = responseData; - replay.defer.resolve(); + replay.defer.resolve(replay.data); }); req.fail(function(jqxhr, status, error) { replay.data = null; @@ -168,7 +167,7 @@ try { } } catch (error) { - console.log(error); + console.error(error); } function zDateString(date) { diff --git a/html/script.js b/html/script.js index d5a75c0..e428425 100644 --- a/html/script.js +++ b/html/script.js @@ -1226,10 +1226,8 @@ function startPage() { if (!heatmap) $("#loader").addClass("hidden"); - if (replay) { - initReplay(replay.data); - play(); // kick off first play - } + if (replay) + replay.defer.done(initReplay); geoMag = geoMagFactory(cof2Obj()); @@ -1861,9 +1859,9 @@ function reaper(all) { if (plane == null) continue; plane.seen = now - plane.last_message_time; - if ( (!plane.selected || SelectedAllPlanes) - && (all || plane.seen > 300) - && (plane.dataSource != 'adsc' || plane.seen > jaeroTimeout) + if ( all || ((!plane.selected || SelectedAllPlanes) + && plane.seen > 300 + && (plane.dataSource != 'adsc' || plane.seen > jaeroTimeout)) ) { // Reap it. //console.log("Removed " + plane.icao); @@ -3862,7 +3860,7 @@ function checkRefresh() { if (showTrace) return; - if (triggerMapRefresh || refreshZoom != zoom || center[0] != refreshLon || center[1] != refreshLat) { + if (triggerMapRefresh || zoom != refreshZoom || center[0] != refreshLon || center[1] != refreshLat) { const ts = new Date().getTime(); const elapsed = Math.abs(ts - lastRefresh); @@ -4928,7 +4926,10 @@ function getTrace(newPlane, hex, options) { SelectedPlane = newPlane; } + let endStamp = traceOpts.endStamp; traceOpts = options; + if (replay) + traceOpts.endStamp = endStamp; if (showTrace) { traceRate += 3; @@ -5248,6 +5249,13 @@ function drawHeatmap() { $("#loader").addClass("hidden"); } +function currentExtent(factor) { + let size = OLMap.getSize(); + if (factor != null) + size = [size[0] * factor, size[1] * factor]; + return myExtent(OLMap.getView().calculateExtent(size)); +} + function initReplay(data) { if (!data) { console.log("initReplay: no data!"); @@ -5257,54 +5265,132 @@ function initReplay(data) { console.log("Invalid heatmap file (byteLength)"); return; } - points = new Int32Array(data); + let points = new Int32Array(data); + let pointsU = new Uint32Array(data); + let pointsU8 = new Uint8Array(data); let found = 0; + replay.slices = []; for (let i = 0; i < points.length; i += 4) { if (points[i] == 0xe7f7c9d) { found = 1; - break; + replay.slices.push(i); } } if (!found) { console.log("Invalid heatmap file (magic number)"); replay.points = null; + replay.pointsU = null; + replay.pointsU8 = null; return; } replay.points = points; + replay.pointsU = pointsU; + replay.pointsU8 = pointsU8; + + play(0); // kick off first play } -function play() { +function play(index) { if (!replay) return; - ZoomLvl = OLMap.getView().getZoom(); - let center = ol.proj.toLonLat(OLMap.getView().getCenter()); - localStorage['CenterLon'] = CenterLon = center[0]; - localStorage['CenterLat'] = CenterLat = center[1]; - clearTimeout(refreshId); refreshId = setTimeout(play, replay.ival / replay.speed); if (showTrace) return; + if (index == null) { + index = replay.index + 1; + } + if (index >= replay.slices.length) { + index = 0; + reaper(true); + refreshFilter(); + } + replay.index = index; + + + let points = replay.points; + let i = replay.slices[index]; + + console.log('index: ' + index + ', i: ' + i); + last = now; + now = replay.pointsU[i + 2] / 1000 + replay.pointsU[i + 1] * 4294967.296; - let acs = []; + traceOpts.endStamp = now; + + replay.ival = (replay.pointsU[i + 3] & 65535); + + i += 4; + + let ext = currentExtent(1.4); + ext.maxLat *= 1e6; + ext.maxLon *= 1e6; + ext.minLat *= 1e6; + ext.minLon *= 1e6; + for (; i < points.length && points[i] != 0xe7f7c9d; i += 4) { + let lat = points[i + 1]; + let lon = points[i + 2]; + let pos = [lon, lat]; + if (lat >= 1073741824) { + let ac = {seen:0, seen_pos:0,}; + ac.hex = (points[i] & ((1<<24) - 1)).toString(16).padStart(6, '0'); + ac.hex = (points[i] & (1<<24)) ? ('~' + ac.hex) : ac.hex; + ac.flight = ""; + if (replay.pointsU8[4 * (i + 2)] != 0) { + for (let j = 0; j < 8; j++) { + ac.flight += String.fromCharCode(replay.pointsU8[4 * (i + 2) + j]); + } + } + processAircraft(ac, false, false); + continue; + } + if (!inView(pos, ext)) { + continue; + } + + lat /= 1e6; + lon /= 1e6; + pos = [lon, lat]; + + let hex = (points[i] & ((1<<24) - 1)).toString(16).padStart(6, '0'); + hex = (points[i] & (1<<24)) ? ('~' + hex) : hex; + + + let alt = points[i + 3] & 65535; + if (alt & 32768) + alt |= -65536; + if (alt == -123) + alt = 'ground'; + else + alt *= 25; + + let gs = points[i + 3] >> 16; + if (gs == -1) + gs = null; + else + gs /= 10; - for (let j=0; j < acs.length; j++) { if (icaoFilter && !icaoFilter.includes(hex)) continue; - if (!onlyMilitary || plane.military) - plane.updateData(now, last, ac, init); - else - plane.last_message_time = now - ac.seen; + let ac = { + seen: 0, + seen_pos: 0, + hex: hex, + lat: lat, + lon: lon, + alt_baro: alt, + gs: gs, + }; + processAircraft(ac, false, false); } - TAR.planeMan.refresh(); - refreshSelected(); - refreshHighlighted(); + checkMovement(); + triggerMapRefresh = 1; + checkRefresh(); } function updateIconCache() {