A window on the sky, and flags on the routes

The terminal board says what is overhead.  This says where: a real map
with the aircraft moving on it as the frames arrive, and beside each one a
box carrying everything known about the flight -- type and registration,
who operates it, where it came from and where it is going, height with a
rate of climb, speed and heading, how far away and on what bearing, its
position, how many frames it has sent and how long since the last one.

Qt is asked for and not required.  Four bindings are tried, the module
imports on a machine with none of them, and asking for the window without
one gets the instructions rather than a traceback -- before the receiver
is opened, since nothing is gained by taking the dongle for a window that
cannot be drawn.

In the menu, "listen now" is now "passive capture" with a realtime
display beside it.  Closing the window leaves exactly the files pressing
control-C leaves, because listen and watch share one read loop and one
finishing step; the receiver runs on its own thread, so a slow repaint
cannot cost a frame and a slow tile fetch cannot stall the picture.

The animation's labels grew to match: flight level and speed, type and
registration, and both ends of the route, each with a small flag of the
country its airport is in.  The flags are a table rather than a network --
twelve pixels by eight, where a flag is the arrangement that makes one
recognisable rather than a rendering of the real thing -- and a country
not in the table is named by its two letters, since a flag that is nearly
another country's is worse than none.  Where a route arrives as bare
codes the country comes from the ICAO prefix.

Four things found on the way.  The window ignored --seconds, so "listen
for ten minutes" meant something different with a window open; it closes
itself now.  The register was being asked twice per aircraft, once for
labels and once for airport positions.  Cached routes had no country in
them, so the first real redraw drew no flags at all -- routes are
versioned now.  And past fourteen aircraft on one frame the labels go
back to the callsign, the height and the speed, because five lines beside
each of three hundred aircraft is a page of overlapping text with a map
somewhere behind it.

Long names are folded rather than allowed to stretch a box, breaking at
the arrow of a route so the two ends stay whole; and the animation's
label placement gained the same ring search the window uses, having only
ever tried four spots.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016PsWPTweCT6pwxKngvVxcg
This commit is contained in:
The Dust Council 2026-09-04 13:38:47 -07:00
parent e50d43d6e2
commit df080f6571
21 changed files with 2848 additions and 145 deletions

View file

@ -1,5 +1,5 @@
.\" Generated by packaging/make-man.py -- do not edit by hand.
.TH BANDSAUNTER 1 "2026-09-04" "bandsaunter 2026-09-04_02" "User Commands"
.TH BANDSAUNTER 1 "2026-09-04" "bandsaunter 2026-09-04_04" "User Commands"
.SH NAME
bandsaunter \- scan, record and identify radio signals with an RTL-SDR
.SH SYNOPSIS
@ -1315,6 +1315,38 @@ an hour, kilometres with km/h \[em] so that one picture never carries two
different miles. The log always holds knots, because that is what the aircraft
broadcast: the recording stays the thing that arrived and the conversion
happens at the moment of showing it to somebody.
.SS A window, while it happens
.B \-\-window
opens a window instead of drawing a table in the terminal: a real map with the
aircraft moving on it as the frames arrive, and beside each one a box giving
its type and registration, who operates it, where it came from and where it is
going \[em] each end with its country's flag \[em] its height and rate of climb,
its speed and heading, how far away it is
and on what bearing, its position, how many frames it has sent and how long
ago the last one was. The boxes are placed so that they cover neither each
other nor another aircraft, and long names are folded rather than allowed to
stretch one \[em] a route between two airports under their full names runs to
sixty characters, and breaks at the arrow so that the two ends of the flight
stay whole.
.PP
.B d
cycles how much each box says, for a busy sky;
.B t
turns the trails off,
.B g
the map underneath,
.B +
and
.B \-
change the range and
.B q
closes it. Closing the window leaves exactly the files a passive capture
leaves, because it is the same code with a different thing watching it: the
receiver runs on its own thread, so a slow repaint cannot cost a frame.
.PP
Qt is asked for and not required \[em] PyQt6, PyQt5, PySide6 and PySide2 are
all tried. Without any of them this window is the only thing lost, and the
program says how to get one rather than failing.
.SS From the menus
Running
.B bandsaunter
@ -1325,8 +1357,10 @@ does all of this without a command line. Every option is listed on one screen
with a line saying what it does;
.BI ? N
explains one at length, including the flag it corresponds to,
.B l
listens,
.B p
starts a passive capture,
.B r
opens the window,
.B m
draws a map from any log in the recordings directory, and
.B s
@ -1380,6 +1414,16 @@ where ffmpeg is installed, or a
for the whole evening in one picture. Altitude is the colour, low warm to high
cold. The GIF is written from first principles \[em] a palette, an LZW stream
and frame differencing \[em] so nothing but numpy is needed to draw one.
.PP
Beside each aircraft goes its flight level and speed, its type and
registration, and the two ends of its route, each with a small flag of the
country the airport is in. The flags are twelve pixels by eight and come from
a table rather than a network: at that size a flag is the arrangement that
makes one recognisable rather than a rendering of the real thing. A country
not in the table is named by its two letters instead, since a flag that is
nearly another country's is worse than none. Where a route arrives as nothing
but a pair of airport codes the country comes from the code, the first letter
or two of an ICAO code being a region.
.SS How far the map reaches
The picture is framed on the receiver rather than on whatever was heard. An
aerial reaches a hundred miles on a good day and a position that decoded