/* 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 { SpotMapAsyncLoader } from './SpotMapAsyncLoader.js'; import { TabularData } from '../../../../js/TabularData.js'; import { WSPREncoded } from '/js/WSPREncoded.js'; import { WsprSearchUiDataTableVisibility } from './WsprSearchUiDataTableVisibility.js'; import { WsprSearchUiDataTableColumnOrder } from './WsprSearchUiDataTableColumnOrder.js'; export class WsprSearchUiMapController extends Base { constructor(cfg) { super(); this.cfg = cfg; this.td = null; this.mapDataToken = 0; this.showEmptyMapRequested = false; this.showControlHelpRequested = false; this.ok = this.cfg.container; // map gets async loaded this.mapModule = null; this.map = null; SpotMapAsyncLoader.SetOnLoadCallback((module) => { this.mapModule = module; this.map = new this.mapModule.SpotMap({ container: this.ui, }); this.map.SetDebug(this.debug); if (this.showEmptyMapRequested) { this.map.SetSpotList([]); this.showEmptyMapRequested = false; } else if (this.td) { this.ScheduleMapData(); } if (this.showControlHelpRequested) { this.map.ShowControlHelpDialog(); this.showControlHelpRequested = false; } }); 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; case "DATA_TABLE_VISIBILITY_CHANGED": this.OnDataTableVisibilityChanged(evt); break; case "SHOW_EMPTY_MAP": this.OnShowEmptyMap(evt); break; case "SHOW_MAP_CONTROL_HELP": this.OnShowMapControlHelp(evt); break; } } } OnDataTableRawReady(evt) { // cache data this.td = evt.tabularDataReadOnly; // check if we can map immediately if (this.mapModule != null) { this.ScheduleMapData(); } } OnDataTableVisibilityChanged(evt) { if (this.td && this.mapModule != null) { this.ScheduleMapData(); } } OnShowEmptyMap(evt) { this.td = null; if (this.map) { this.map.SetSpotList([]); } else { this.showEmptyMapRequested = true; } } OnShowMapControlHelp(evt) { if (this.map) { this.map.ShowControlHelpDialog(); } else { this.showControlHelpRequested = true; } } ScheduleMapData() { let token = ++this.mapDataToken; let run = () => { if (token != this.mapDataToken) { return; } this.MapData(); }; if (window.requestIdleCallback) { window.requestIdleCallback(() => { window.requestAnimationFrame(run); }, { timeout: 250 }); } else { window.setTimeout(() => { window.requestAnimationFrame(run); }, 0); } } MapData() { this.t.Reset(); this.t.Event(`WsprSearchUiMapController::MapData Start`); let spotList = []; if (this.td.Idx("Lat") != undefined && this.td.Idx("Lng") != undefined) { this.td.ForEach(row => { let metaData = this.td.GetRowMetaData(row); let locationSource = metaData?.overlap?.resolved?.sourceByFamily?.location ?? null; let latResolved = this.td.Idx("Lat") != undefined ? this.td.Get(row, "Lat") : null; let lngResolved = this.td.Idx("Lng") != undefined ? this.td.Get(row, "Lng") : null; let lat = null; let lng = null; if (latResolved != null && lngResolved != null) { lat = latResolved; lng = lngResolved; } if (lat != null && lng != null) { // get a list of all the reporting stations let seenDataList = []; for (let msg of metaData.slotMsgList) { if (msg) { for (let rxRecord of msg.rxRecordList) { let [lat, lng] = WSPREncoded.DecodeMaidenheadToDeg(rxRecord.rxGrid); let seenData = { sign: rxRecord.callsign, lat, lng, grid: rxRecord.rxGrid, }; seenDataList.push(seenData); } } } // send along a cut-down version of the data available let tdSpot = new TabularData(this.td.MakeDataTableFromRow(row)); let popupVisibleColSet = new Set([ ...WsprSearchUiDataTableVisibility.GetVisibleColumnsForStorageKey("dateTimeVisible"), ...WsprSearchUiDataTableVisibility.GetVisibleColumnsForStorageKey("resolvedVisible"), ]); let popupColList = tdSpot.GetHeaderList().filter(col => popupVisibleColSet.has(col)); tdSpot.SetColumnOrder(popupColList); WsprSearchUiDataTableColumnOrder.Apply(tdSpot); tdSpot.DeleteEmptyColumns(); let spot = new this.mapModule.Spot({ lat: lat, lng: lng, grid: null, accuracy: (locationSource == "HRL" || locationSource == "EBT") ? "veryHigh" : (locationSource == "BT") ? "high" : "low", dtLocal: tdSpot.Get(0, "DateTimeLocal"), td: tdSpot, seenDataList: seenDataList, }); spotList.push(spot); } }, true); } // hand off even an empty spot list this.map.SetSpotList(spotList); this.t.Event(`WsprSearchUiMapController::MapData End`); } MakeUI() { let ui = document.createElement("div"); ui.style.boxSizing = "border-box"; ui.style.border = "1px solid black"; ui.style.width = "1210px"; ui.style.height = "550px"; ui.style.resize = "both"; ui.style.overflow = "hidden"; return ui; } }