gridtracker/package.nw/lib/pota.js

408 wiersze
11 KiB
JavaScript
Czysty Zwykły widok Historia

2022-02-05 15:54:14 +00:00
// GridTracker Copyright © 2022 GridTracker.org
// All rights reserved.
// See LICENSE for more information.
2022-09-11 01:05:25 +00:00
var g_pota = {
2022-09-19 02:06:49 +00:00
parks: {},
2022-09-22 22:47:43 +00:00
locations: {},
2022-09-19 02:06:49 +00:00
parksTimeout: null,
callSchedule: {},
parkSchedule: {},
2022-09-11 01:05:25 +00:00
scheduleTimeout: null,
2022-09-19 02:06:49 +00:00
callSpots: {},
2022-09-23 02:02:10 +00:00
parkSpots: {},
2022-09-19 02:06:49 +00:00
spotsTimeout: null,
mapParks: {}
2022-09-11 01:05:25 +00:00
};
2022-02-05 15:54:14 +00:00
2022-09-14 01:13:16 +00:00
var g_defaultPark = {
2022-09-19 02:06:49 +00:00
feature: null
2022-09-14 01:13:16 +00:00
}
2022-09-19 02:06:49 +00:00
var g_gtParkIconActive = new ol.style.Icon({
src: "./img/pota_icon_active.png",
anchorYUnits: "pixels",
anchorXUnits: "pixels",
anchor: [10, 19]
});
var g_gtParkIconInactive = new ol.style.Icon({
src: "./img/pota_icon_inactive.png",
anchorYUnits: "pixels",
anchorXUnits: "pixels",
anchor: [10, 19]
});
2022-09-11 01:05:25 +00:00
function initPota()
{
potaImg.style.filter = g_potaEnabled == 1 ? "" : "grayscale(1)";
2022-09-19 02:06:49 +00:00
getPotaParks();
2022-09-11 01:05:25 +00:00
}
function togglePota()
{
g_potaEnabled ^= 1;
g_appSettings.potaEnabled = g_potaEnabled;
potaImg.style.filter = g_potaEnabled == 1 ? "" : "grayscale(1)";
saveAppSettings();
if (g_potaEnabled == 1)
{
2022-09-19 02:06:49 +00:00
getPotaParks();
}
else
{
g_layerSources.pota.clear();
g_pota.mapParks = {};
}
}
2022-09-23 02:02:10 +00:00
function redrawParks()
2022-09-19 02:06:49 +00:00
{
2022-09-23 02:02:10 +00:00
if (g_potaEnabled == 1)
2022-09-21 22:46:27 +00:00
{
2022-09-23 02:02:10 +00:00
g_layerSources.pota.clear();
g_pota.mapParks = {};
makeParkFeatures();
2022-09-21 22:46:27 +00:00
}
2022-09-19 02:06:49 +00:00
}
2022-09-23 02:02:10 +00:00
function makeParkFeatures()
2022-09-19 02:06:49 +00:00
{
try
{
2022-09-23 02:02:10 +00:00
for (const park in g_pota.parkSpots)
2022-09-11 01:05:25 +00:00
{
2022-09-23 02:02:10 +00:00
if (park in g_pota.parks)
2022-09-19 02:06:49 +00:00
{
2022-09-23 02:02:10 +00:00
let parkObj = Object.assign({}, g_defaultPark);
for (const i in g_pota.parkSpots[park])
{
let report = g_pota.parkSpots[park][i];
if (parkObj.feature == null && (g_appSettings.gtBandFilter.length == 0 || (g_appSettings.gtBandFilter == "auto" ? myBand == report.band : g_appSettings.gtBandFilter == report.band)) && validateMapMode(report.mode))
{
parkObj.feature = iconFeature(ol.proj.fromLonLat([Number(g_pota.parks[park].longitude), Number(g_pota.parks[park].latitude)]), g_gtParkIconActive, 1);
parkObj.feature.key = park;
parkObj.feature.size = 22;
g_pota.mapParks[park] = parkObj;
g_layerSources.pota.addFeature(parkObj.feature);
break;
}
}
2022-09-19 02:06:49 +00:00
}
2022-09-11 01:05:25 +00:00
}
}
catch (e)
2022-09-14 01:13:16 +00:00
{
2022-09-19 02:06:49 +00:00
console.log("exception: makeParkFeature " + park);
console.log(e.message);
2022-09-14 01:13:16 +00:00
}
2022-09-11 01:05:25 +00:00
}
2022-09-19 02:06:49 +00:00
function processPotaParks(buffer)
2022-02-05 21:55:25 +00:00
{
if (g_potaEnabled == 1)
2022-02-05 21:55:25 +00:00
{
try
2022-09-21 22:46:27 +00:00
{
2022-09-22 22:47:43 +00:00
let data = JSON.parse(buffer);
let newParks = data.parks;
for (const park in newParks)
2022-09-21 22:46:27 +00:00
{
let locations = newParks[park].locationDesc.split(",");
for (const i in locations)
2022-09-21 22:46:27 +00:00
{
2022-09-22 22:47:43 +00:00
if (locations[i] in data.locations)
{
2022-09-22 22:47:43 +00:00
locations[i] = data.locations[locations[i]];
}
2022-09-21 22:46:27 +00:00
}
newParks[park].locationDesc = locations.join(", ");
2022-09-21 22:46:27 +00:00
}
g_pota.parks = newParks;
2022-09-22 22:55:11 +00:00
g_pota.locations = data.locations;
getPotaSchedule();
getPotaSpots();
}
catch (e)
{
// can't write, somethings broke
console.log("Failed to load parks!");
console.log(e.message);
}
2022-02-05 21:55:25 +00:00
}
}
2022-09-19 02:06:49 +00:00
function getPotaParks()
2022-02-05 15:54:14 +00:00
{
2022-09-19 02:06:49 +00:00
if (g_pota.parksTimeout)
2022-09-11 01:05:25 +00:00
{
2022-09-19 02:06:49 +00:00
clearTimeout(g_pota.parksTimeout);
2022-09-11 01:05:25 +00:00
g_pota.spotsTimeout = null;
}
2022-09-11 01:05:25 +00:00
if (g_mapSettings.offlineMode == false && g_potaEnabled == 1)
2022-02-05 21:55:25 +00:00
{
getBuffer(
"https://storage.googleapis.com/gt_app/pota.json?cb=" + Date.now(),
2022-09-19 02:06:49 +00:00
processPotaParks,
2022-02-05 21:55:25 +00:00
null,
"https",
443
2022-02-05 21:55:25 +00:00
);
}
2022-09-11 01:05:25 +00:00
2022-09-19 02:06:49 +00:00
g_pota.parksTimeout = setTimeout(getPotaParks, 86400000)
}
function uniqueArrayFromArray(input)
{
let unique = [];
2022-09-20 01:09:13 +00:00
input.forEach((c) =>
{
2022-09-20 01:09:13 +00:00
if (!unique.includes(c))
{
unique.push(c);
2022-09-19 02:06:49 +00:00
}
});
return unique;
2022-02-05 15:54:14 +00:00
}
2022-09-11 01:05:25 +00:00
function processPotaSpots(buffer)
{
if (g_potaEnabled == 1)
{
try
2022-09-19 02:06:49 +00:00
{
let spots = JSON.parse(buffer);
g_pota.callSpots = {};
g_pota.parkSpots = {};
for (const spot in spots)
2022-09-19 02:06:49 +00:00
{
if (spots[spot].reference in g_pota.parks)
{
spots[spot].spotTime = Date.parse(spots[spot].spotTime + "Z");
spots[spot].expire = (spots[spot].expire * 1000) + spots[spot].spotTime;
spots[spot].frequency = parseInt(spots[spot].frequency) / 1000;
2022-09-23 02:02:10 +00:00
spots[spot].band = spots[spot].frequency.formatBand();
(g_pota.callSpots[spots[spot].activator] = g_pota.callSpots[spots[spot].activator] || []).push(spots[spot].reference);
(g_pota.parkSpots[spots[spot].reference] = g_pota.parkSpots[spots[spot].reference] || []).push(spots[spot]);
}
else
{
console.log("PotaSpots: unknown park id: " + spots[spot].reference);
}
2022-09-19 02:06:49 +00:00
}
// Sanity dedupe checks
for (const spot in g_pota.callSpots)
2022-09-19 02:06:49 +00:00
{
g_pota.callSpots[spot] = uniqueArrayFromArray(g_pota.callSpots[spot]);
}
for (const spot in g_pota.parkSpots)
{
g_pota.parkSpots[spot] = uniqueArrayFromArray(g_pota.parkSpots[spot]);
2022-09-19 02:06:49 +00:00
}
2022-09-23 02:02:10 +00:00
redrawParks();
2022-09-11 01:05:25 +00:00
}
catch (e)
2022-09-19 02:06:49 +00:00
{
// can't write, somethings broke
2022-09-19 02:06:49 +00:00
}
}
}
function getPotaSpots()
2022-02-05 15:54:14 +00:00
{
2022-09-11 01:05:25 +00:00
if (g_pota.spotsTimeout)
{
clearTimeout(g_pota.spotsTimeout);
g_pota.spotsTimeout = null;
}
2022-09-11 01:05:25 +00:00
if (g_mapSettings.offlineMode == false && g_potaEnabled == 1)
{
getBuffer(
"https://api.pota.app/spot/activator",
2022-09-11 01:05:25 +00:00
processPotaSpots,
null,
"https",
443
);
2022-09-11 01:05:25 +00:00
}
2022-09-11 01:05:25 +00:00
g_pota.spotsTimeout = setTimeout(getPotaSpots, 300000);
}
function processPotaSchedule(buffer)
{
if (g_potaEnabled == 1)
2022-09-11 01:05:25 +00:00
{
try
2022-09-11 01:05:25 +00:00
{
let schedules = JSON.parse(buffer);
g_pota.callSchedule = {};
g_pota.parkSchedule = {};
for (const i in schedules)
2022-09-11 01:05:25 +00:00
{
let newObj = {};
newObj.id = schedules[i].reference;
newObj.start = Date.parse(schedules[i].startDate + "T" + schedules[i].startTime + "Z");
newObj.end = Date.parse(schedules[i].endDate + "T" + schedules[i].endTime + "Z");
newObj.frequencies = schedules[i].frequencies;
newObj.comments = schedules[i].comments;
if (Date.now() < newObj.end)
2022-09-19 02:06:49 +00:00
{
if (newObj.id in g_pota.parks)
{
(g_pota.callSchedule[schedules[i].activator] = g_pota.callSchedule[schedules[i].activator] || []).push(newObj);
newObj = Object.assign({}, newObj);
newObj.id = schedules[i].activator;
(g_pota.parkSchedule[schedules[i].reference] = g_pota.parkSchedule[schedules[i].reference] || []).push(newObj);
}
else
{
console.log("PotaSchedule: unknown park id: " + newObj.id);
}
2022-09-19 02:06:49 +00:00
}
// else it is expired and no longer relevant
2022-09-11 01:05:25 +00:00
}
// Sanity dedupe checks
for (const key in g_pota.callSchedule)
{
g_pota.callSchedule[key] = uniqueArrayFromArray(g_pota.callSchedule[key]);
}
for (const key in g_pota.parkSchedule)
{
g_pota.parkSchedule[key] = uniqueArrayFromArray(g_pota.parkSchedule[key]);
}
2022-09-19 02:06:49 +00:00
}
catch (e)
2022-09-19 02:06:49 +00:00
{
// can't write, somethings broke
2022-09-19 02:06:49 +00:00
}
2022-09-11 01:05:25 +00:00
}
}
function getPotaSchedule()
{
2022-09-11 20:18:00 +00:00
if (g_pota.scheduleTimeout)
2022-09-11 01:05:25 +00:00
{
clearTimeout(g_pota.scheduleTimeout);
g_pota.scheduleTimeout = null;
}
2022-09-11 01:05:25 +00:00
if (g_mapSettings.offlineMode == false && g_potaEnabled == 1)
{
getBuffer(
"https://api.pota.app/activation",
processPotaSchedule,
null,
"https",
443
);
}
2022-09-11 01:05:25 +00:00
g_pota.scheduleTimeout = setTimeout(getPotaSchedule, 900000);
2022-02-05 15:54:14 +00:00
}
2022-09-11 01:05:25 +00:00
function sendPotaSpot()
2022-02-05 15:54:14 +00:00
{
// if Pota spotting enabled, and we have enough info, send a spot to Pota
}
2022-09-21 22:46:27 +00:00
var g_lastPark = null;
function mouseOverPark(feature)
{
if (g_lastPark && g_lastPark == feature)
{
mouseParkMove();
return;
}
g_lastPark = feature;
createParkTipTable(feature);
var positionInfo = myParktip.getBoundingClientRect();
2022-09-21 22:56:20 +00:00
myParktip.style.left = getMouseX() - positionInfo.width / 2 + "px";
myParktip.style.top = getMouseY() - positionInfo.height - 22 + "px";
2022-09-21 22:46:27 +00:00
myParktip.style.zIndex = 499;
myParktip.style.display = "block";
}
function mouseOutPark(mouseEvent)
{
g_lastPark = null;
myParktip.style.zIndex = -1;
}
function mouseParkMove()
{
var positionInfo = myParktip.getBoundingClientRect();
2022-09-21 22:56:20 +00:00
myParktip.style.left = getMouseX() - positionInfo.width / 2 + "px";
myParktip.style.top = getMouseY() - positionInfo.height - 22 + "px";
2022-09-21 22:46:27 +00:00
}
function createParkTipTable(toolElement)
{
let worker = "";
let key = toolElement.key;
let parkObj = g_pota.mapParks[key];
let now = Date.now();
worker += "<div style='background-color:#000;color:lightgreen;font-weight:bold;font-size:12px;border:1px solid gray;margin:0px' class='roundBorder'>" +
key +
" : <font color='cyan'>" + g_pota.parks[key].name + "" +
" (<font color='yellow'>" + g_dxccToAltName[Number(g_pota.parks[key].entityId)] + "</font>)" +
2022-09-22 22:47:43 +00:00
"</font></br><font color='lightblue'>" + g_pota.parks[key].locationDesc + "</font></div>";
2022-09-21 22:46:27 +00:00
2022-09-23 02:02:10 +00:00
worker += "<table id='potaSpotsTable' class='darkTable' style='margin: 0 auto;'>";
worker += "<tr><th>Activator</th><th>Spotter</th><th>Freq</th><th>Mode</th><th>Count</th><th>When</th><th>Source</th><th>Comment</th></tr>";
for (const i in g_pota.parkSpots[key])
2022-09-21 22:46:27 +00:00
{
2022-09-23 02:02:10 +00:00
worker += "<tr>";
worker += "<td style='color:yellow'>" + g_pota.parkSpots[key][i].activator + "</td>";
worker += "<td style='color:cyan'>" + ((g_pota.parkSpots[key][i].spotter == g_pota.parkSpots[key][i].activator) ? "Self" : g_pota.parkSpots[key][i].spotter) + "</td>";
worker += "<td style='color:lightgreen' >" + g_pota.parkSpots[key][i].frequency.formatMhz(3, 3) + " <font color='yellow'>(" + g_pota.parkSpots[key][i].band + ")</font></td>";
worker += "<td style='color:orange'>" + g_pota.parkSpots[key][i].mode + "</td>";
worker += "<td>" + g_pota.parkSpots[key][i].count + "</td>";
worker += "<td style='color:lightblue' >" + parseInt((now - g_pota.parkSpots[key][i].spotTime) / 1000).toDHMS() + "</td>";
worker += "<td>" + g_pota.parkSpots[key][i].source + "</td>";
worker += "<td>" + g_pota.parkSpots[key][i].comments + "</td>";
worker += "</tr>";
2022-09-21 22:46:27 +00:00
}
2022-09-23 02:02:10 +00:00
worker += "</table>";
2022-09-21 22:46:27 +00:00
2022-09-23 02:02:10 +00:00
/*
buffer += "<div style='background-color:#000;color:#fff;font-size:12px;border:1px solid gray;margin:1px' class='roundBorder'>Activations (scheduled)"
buffer += "<table id='potaScheduleTable' class='darkTable' style='margin: 0 auto;'>";
buffer += "<tr><th>Activator</th><th>Start</th><th>End</th><th>Frequencies</th><th>Comment</th></tr>";
2022-09-21 22:46:27 +00:00
for (const i in g_pota.parkSchedule[key])
{
let start = g_pota.parkSchedule[key][i].start;
let end = g_pota.parkSchedule[key][i].end;
2022-09-22 23:07:32 +00:00
if (now < end)
{
buffer += "<tr>";
buffer += "<td style='color:yellow'>" + g_pota.parkSchedule[key][i].id + "</td>";
buffer += "<td style='color:lightblue'>" + ((now >= start) ? "<font color='white'>Now</font>" : (userTimeString(start) + "</br><font color='lightgreen'>T- " + Number(start - now).msToDHMS() + "</font>")) + "</td>";
buffer += "<td style='color:lightblue'>" + (userTimeString(end) + "</br><font color='orange'>T- " + Number(end - now).msToDHMS() + "</font>") + "</td>";
buffer += "<td style='color:lightgreen'>" + g_pota.parkSchedule[key][i].frequencies + "</td>";
buffer += "<td>" + g_pota.parkSchedule[key][i].comments.substr(0, 40) + "</td>";
buffer += "</tr>";
active++;
2022-09-22 23:07:32 +00:00
}
2022-09-21 22:46:27 +00:00
}
2022-09-23 02:02:10 +00:00
*/
2022-09-21 22:46:27 +00:00
myParktip.innerHTML = worker;
return 1;
}