From d9a496cfaf59c43c3afde40b81aa79d1f6a23b37 Mon Sep 17 00:00:00 2001 From: Stanislaw Grams Date: Sun, 8 Feb 2026 21:49:04 +0100 Subject: [PATCH] [feat](trx-frontend-http): use APRS symbol icons on map markers Show the proper APRS symbol sprite icon on map markers instead of generic green circles. Falls back to a green circle marker when no symbol info is available. Co-Authored-By: Claude Opus 4.6 Signed-off-by: Stanislaw Grams --- .../trx-frontend-http/assets/web/app.js | 32 ++++++++++++++++--- .../assets/web/plugins/aprs.js | 2 +- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js index 41a8113..11162ba 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/app.js @@ -669,17 +669,39 @@ function initAprsMap() { } } -window.aprsMapAddStation = function(call, lat, lon, info) { +function aprsSymbolIcon(symbolTable, symbolCode) { + if (!symbolTable || !symbolCode) return null; + const sheet = symbolTable === "/" ? 0 : 1; + const code = symbolCode.charCodeAt(0) - 33; + const col = code % 16; + const row = Math.floor(code / 16); + const bgX = -(col * 24); + const bgY = -(row * 24); + const url = `https://raw.githubusercontent.com/hessu/aprs-symbols/master/png/aprs-symbols-24-${sheet}.png`; + return L.divIcon({ + className: "", + html: `
`, + iconSize: [24, 24], + iconAnchor: [12, 12], + popupAnchor: [0, -12] + }); +} + +window.aprsMapAddStation = function(call, lat, lon, info, symbolTable, symbolCode) { if (!aprsMap) initAprsMap(); if (!aprsMap) return; + const popupContent = `${call}
${info}`; const existing = stationMarkers.get(call); if (existing) { existing.setLatLng([lat, lon]); - existing.setPopupContent(`${call}
${info}`); + existing.setPopupContent(popupContent); } else { - const marker = L.circleMarker([lat, lon], { - radius: 6, color: "#00d17f", fillColor: "#00d17f", fillOpacity: 0.8 - }).addTo(aprsMap).bindPopup(`${call}
${info}`); + const icon = aprsSymbolIcon(symbolTable, symbolCode); + const marker = icon + ? L.marker([lat, lon], { icon }).addTo(aprsMap).bindPopup(popupContent) + : L.circleMarker([lat, lon], { + radius: 6, color: "#00d17f", fillColor: "#00d17f", fillOpacity: 0.8 + }).addTo(aprsMap).bindPopup(popupContent); stationMarkers.set(call, marker); } }; diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/aprs.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/aprs.js index 246d93f..7d5508d 100644 --- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/aprs.js +++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/aprs.js @@ -455,7 +455,7 @@ function addAprsPacket(pkt) { } row.innerHTML = `${ts}${symbolHtml}${pkt.srcCall}>${pkt.destCall}${pkt.path ? "," + pkt.path : ""}: ${pkt.info}${posHtml}${crcTag}`; if (pkt.lat != null && pkt.lon != null && window.aprsMapAddStation) { - window.aprsMapAddStation(pkt.srcCall, pkt.lat, pkt.lon, pkt.info); + window.aprsMapAddStation(pkt.srcCall, pkt.lat, pkt.lon, pkt.info, pkt.symbolTable, pkt.symbolCode); } aprsPacketsEl.prepend(row); while (aprsPacketsEl.children.length > APRS_MAX_PACKETS) {