APRS position reports were rendering their raw symbol character in a bordered box, because the stylesheet had sprite rules (background-size: 384px 192px) for a sheet that was never added to the repo.
What changed
Vendored rev H of hessu/aprs-symbols: the primary, alternate and overlay 24px sheets plus their retina variants, embedded and served under /vendor with immutable cache headers.
Rendering moved to a shared aprsSymbolSprite() helper used by the APRS list, the HF APRS list and the map markers. / and \ select a sheet; any other table identifier is an overlay character stacked on top of the alternate symbol, per the APRS spec. Codes outside 0x21..0x7E keep the old character box.
Sheet URLs stay in CSS so a min-resolution: 2dppx query swaps in the retina sheets; only the cell offset is inline.
Licensing
The symbol set carries no single license — individual symbols are variously vectorizations of the original WA8LMF bitmaps with unknown terms, new CC BY-SA work by OH7LZB, public-domain or CC sources, and a few brand logos owned by their companies. It is recorded as LicenseRef-APRS-Symbols with the upstream per-symbol catalogue copied verbatim into LICENSES/, plus the attribution pointer upstream asks for in the README.
Testing
tests/aprs-symbols.test.mjs pins the cell indexing, the three table modes, overlay layer order, the fallback, and that the stylesheet serves all six sheets locally at the sprite geometry.
A Rust test parses each embedded PNG's IHDR, so a re-vendored sheet at a different size can't silently shift every symbol onto a neighbouring icon.
cargo test -p trx-frontend-http (56), cargo clippy -p trx-frontend-http --all-targets, frontend typecheck / build / lint / test (39) all clean.
Rendered in headless Chromium at 2x against the real stylesheet and sheets: /> a car, /- a house, /_ a WX circle, /& an igate diamond, \n a red triangle, and the overlays S> / 7# / An carrying their character on the alternate symbol.
Not included
trx-aprs only extracts symbol_table / symbol_code for Position packets, so Mic-E, Object and Item reports still render no symbol. They carry symbols too, in different field positions — left for a follow-up.
APRS position reports were rendering their raw symbol character in a bordered box, because the stylesheet had sprite rules (`background-size: 384px 192px`) for a sheet that was never added to the repo.
## What changed
- **Vendored** rev H of [hessu/aprs-symbols](https://github.com/hessu/aprs-symbols): the primary, alternate and overlay 24px sheets plus their retina variants, embedded and served under `/vendor` with immutable cache headers.
- **Rendering** moved to a shared `aprsSymbolSprite()` helper used by the APRS list, the HF APRS list and the map markers. `/` and `\` select a sheet; any other table identifier is an overlay character stacked on top of the alternate symbol, per the APRS spec. Codes outside `0x21..0x7E` keep the old character box.
- Sheet URLs stay in CSS so a `min-resolution: 2dppx` query swaps in the retina sheets; only the cell offset is inline.
## Licensing
The symbol set carries no single license — individual symbols are variously vectorizations of the original WA8LMF bitmaps with unknown terms, new CC BY-SA work by OH7LZB, public-domain or CC sources, and a few brand logos owned by their companies. It is recorded as `LicenseRef-APRS-Symbols` with the upstream per-symbol catalogue copied verbatim into `LICENSES/`, plus the attribution pointer upstream asks for in the README.
## Testing
- `tests/aprs-symbols.test.mjs` pins the cell indexing, the three table modes, overlay layer order, the fallback, and that the stylesheet serves all six sheets locally at the sprite geometry.
- A Rust test parses each embedded PNG's IHDR, so a re-vendored sheet at a different size can't silently shift every symbol onto a neighbouring icon.
- `cargo test -p trx-frontend-http` (56), `cargo clippy -p trx-frontend-http --all-targets`, frontend `typecheck` / `build` / `lint` / `test` (39) all clean.
- Rendered in headless Chromium at 2x against the real stylesheet and sheets: `/>` a car, `/-` a house, `/_` a WX circle, `/&` an igate diamond, `\n` a red triangle, and the overlays `S>` / `7#` / `An` carrying their character on the alternate symbol.
## Not included
`trx-aprs` only extracts `symbol_table` / `symbol_code` for `Position` packets, so Mic-E, Object and Item reports still render no symbol. They carry symbols too, in different field positions — left for a follow-up.
The web UI had no symbol graphics at all, so a position report rendered
its raw symbol character in a bordered box. Vendor rev H of the
hessu/aprs-symbols set: three 24px sheets (primary, alternate, and the
overlay characters) plus their retina variants.
The set carries no single license. Individual symbols are variously
vectorizations of the original WA8LMF bitmaps with unknown terms, new
CC BY-SA work by OH7LZB, public-domain or CC sources, and a handful of
brand logos owned by their companies. Record that as
LicenseRef-APRS-Symbols with the upstream per-symbol catalogue copied
verbatim, and carry the attribution pointer upstream asks for.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018huL1ELyr86yVqfAabtioA
Signed-off-by: Stan Grams <sjg@haxx.space>
Embed the six sheets alongside the other vendored assets and serve them
under /vendor with the same immutable cache headers.
The browser computes a symbol's cell from a 16x6 grid of 24px cells, so
a re-vendored sheet at any other size would shift every station onto a
neighbouring icon -- wrong on every packet, and invisible unless you
know which glyph to expect. Pin the geometry by parsing each embedded
PNG's IHDR in a test.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018huL1ELyr86yVqfAabtioA
Signed-off-by: Stan Grams <sjg@haxx.space>
Resolve a table/code pair to a sprite cell in aprs-shared, and use it
from both the packet lists and the map markers, which had each been
printing the raw symbol character in a bordered box.
A table identifier of / or \ selects the primary or alternate sheet
directly. Anything else is an overlay character, which the APRS spec
draws on top of the alternate symbol -- so those stack the overlay sheet
over the alternate one rather than picking a sheet. Codes outside
0x21..0x7E have no cell and keep the old character box.
The sheet URLs stay in the stylesheet so a min-resolution query can swap
in the retina sheets; only the cell offset is computed and set inline.
Map markers share the helper through the plugin chunk, so the map stays
free of any remote symbol fetch.
Verified in a browser against the real stylesheet and sheets: /> is a
car, /_ a WX circle, /& an igate diamond, \n a red triangle, and the
overlays S> and 7# carry their character on the alternate symbol.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018huL1ELyr86yVqfAabtioA
Signed-off-by: Stan Grams <sjg@haxx.space>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
APRS position reports were rendering their raw symbol character in a bordered box, because the stylesheet had sprite rules (
background-size: 384px 192px) for a sheet that was never added to the repo.What changed
/vendorwith immutable cache headers.aprsSymbolSprite()helper used by the APRS list, the HF APRS list and the map markers./and\select a sheet; any other table identifier is an overlay character stacked on top of the alternate symbol, per the APRS spec. Codes outside0x21..0x7Ekeep the old character box.min-resolution: 2dppxquery swaps in the retina sheets; only the cell offset is inline.Licensing
The symbol set carries no single license — individual symbols are variously vectorizations of the original WA8LMF bitmaps with unknown terms, new CC BY-SA work by OH7LZB, public-domain or CC sources, and a few brand logos owned by their companies. It is recorded as
LicenseRef-APRS-Symbolswith the upstream per-symbol catalogue copied verbatim intoLICENSES/, plus the attribution pointer upstream asks for in the README.Testing
tests/aprs-symbols.test.mjspins the cell indexing, the three table modes, overlay layer order, the fallback, and that the stylesheet serves all six sheets locally at the sprite geometry.cargo test -p trx-frontend-http(56),cargo clippy -p trx-frontend-http --all-targets, frontendtypecheck/build/lint/test(39) all clean./>a car,/-a house,/_a WX circle,/&an igate diamond,\na red triangle, and the overlaysS>/7#/Ancarrying their character on the alternate symbol.Not included
trx-aprsonly extractssymbol_table/symbol_codeforPositionpackets, so Mic-E, Object and Item reports still render no symbol. They carry symbols too, in different field positions — left for a follow-up.597ba031f3to5b7dd493d4