/* Copyright (c) 2023-forever Douglas Malnati. All rights reserved. See the /faq/tos page for details. (If this generated header is stamped on a file which is a 3rd party file or under a different license or copyright, then ignore this copyright statement and use that file's terms.) */ import * as utl from '/js/Utl.js'; import { Base } from './Base.js'; import { TabularData } from '../../../../js/TabularData.js'; export class WsprSearchUiFlightStatsController extends Base { constructor(cfg) { super(); this.cfg = cfg; this.ok = this.cfg.container; if (this.ok) { this.ui = this.#MakeUI(); this.cfg.container.appendChild(this.ui); } } SetDebug(tf) { super.SetDebug(tf); this.t.SetCcGlobal(tf); } OnEvent(evt) { if (this.ok) { switch (evt.type) { case "DATA_TABLE_RAW_READY": this.#OnDataTableRawReady(evt); break; } } } #OnDataTableRawReady(evt) { this.t.Reset(); this.t.Event(`WsprSearchUiFlightStatsController::OnDataTableRawReady Start`); // clear existing child nodes this.cfg.container.innerHTML = ""; // get handle to data let td = evt.tabularDataReadOnly; // calculate distance stats let distKm = 0; let distMi = 0; td.ForEach((row) => { distKm += td.Get(row, "DistKm"); distMi += td.Get(row, "DistMi"); }); // calculate spot stats let spotCount = td.GetDataTable().length - 1; // calculate duration stats let durationStr = ""; if (td.Length() > 1) { let dtFirst = td.Get(td.Length() - 1, "DateTimeLocal"); let dtLast = td.Get(0, "DateTimeLocal"); let msFirst = utl.ParseTimeToMs(dtFirst); let msLast = utl.ParseTimeToMs(dtLast); let msDiff = msLast - msFirst; durationStr = utl.MsToDurationStrDaysHoursMinutes(msDiff); } // calculate eastward laps around world using resolved location let lapCount = this.#CalculateEastwardLapCount(td); // create summary let status = ` Flight duration: ${durationStr}

Laps around world: ${utl.Commas(lapCount)}

Distance Traveled Km: ${utl.Commas(Math.round(distKm))}
Distance Traveled Mi: ${utl.Commas(Math.round(distMi))}

Spots: ${utl.Commas(spotCount)} `; // update UI this.ui.innerHTML = status; // replace with new this.cfg.container.appendChild(this.ui); this.t.Event(`WsprSearchUiFlightStatsController::OnDataTableRawReady End`); } #MakeUI() { this.ui = document.createElement('div'); return this.ui; } #CalculateEastwardLapCount(td) { let lonList = []; // Table is newest-first, so iterate oldest -> newest. for (let idx = td.Length() - 1; idx >= 0; --idx) { let lon = td.Get(idx, "Lng"); if (lon == undefined || lon == null || lon === "") { continue; } lon = Number(lon); if (Number.isFinite(lon)) { lonList.push(lon); } } if (lonList.length < 2) { return 0; } // Unwrap longitude so east/west movement is continuous across +/-180. let unwrappedLonList = [lonList[0]]; for (let i = 1; i < lonList.length; ++i) { let prevRaw = lonList[i - 1]; let curRaw = lonList[i]; let delta = curRaw - prevRaw; if (delta > 180) { delta -= 360; } if (delta < -180) { delta += 360; } let nextUnwrapped = unwrappedLonList[unwrappedLonList.length - 1] + delta; unwrappedLonList.push(nextUnwrapped); } let startLon = unwrappedLonList[0]; let lapCount = 0; // Count only eastward full wraps past start + 360n. for (let i = 1; i < unwrappedLonList.length; ++i) { let prevRel = unwrappedLonList[i - 1] - startLon; let curRel = unwrappedLonList[i] - startLon; while (prevRel < (lapCount + 1) * 360 && curRel >= (lapCount + 1) * 360) { ++lapCount; } } return lapCount; } }