DEAD·RECKONING
← back to the map

Methodology

DEAD RECKONING is an instrument, not an accusation. It measures where aircraft report degraded navigation integrity, aggregates that signal over space and time, and shows it with its uncertainty attached. This page explains exactly what the signal is, how it is computed, and, just as important, what it cannot tell you.

What NIC is

Every ADS-B–equipped aircraft broadcasts a Navigation Integrity Category (NIC), an integer from 0 to 11, alongside its position. NIC states how tightly the aircraft's own navigation system can bound the error on the position it is transmitting. It is paired with a radius of containment (rc, in metres). High NIC means a small, trustworthy containment radius; low NIC means a large one.

When GNSS (GPS, Galileo, GLONASS, BeiDou) is jammed or spoofed, receivers lose the ability to bound their error, and NIC falls, often all the way to 0 ("integrity unknown"). Many aircraft in one area reporting low NIC at the same time is the fingerprint of interference in that airspace. Our sample day shows the containment ladder cleanly:

NIC11109876543
median rc (m)82575186371926185237047408

The inference rule

Interference is inferred from multiple proximate aircraft, never a single report. The pipeline:

  1. Streams a full UTC day of open ADS-B traces from adsb.lol.
  2. Keeps only airborne positions that carry a NIC value (ground positions and non-positional records are dropped).
  3. Bins each position into an H3 resolution-4 hex (~1,770 km² per cell).
  4. For each aircraft in each hex, marks it degraded if the majority of its NIC reports there are nic ≤ 6 (containment radius ≳ 1 km).
  5. Computes each hex's bad_ratio = degraded aircraft ÷ unique aircraft.
The unit of "degraded" is the aircraft, not the report. One aircraft lingering with poor reception cannot make a hex look jammed; the signal only rises when many distinct aircraft agree.

Thresholds & their sensitivity

The degraded threshold nic ≤ 6 is chosen because NIC 6 corresponds to a containment radius of roughly 1 km, the point at which a position is too loose to trust for navigation. NIC 7 and above (rc < ~370 m) are treated as healthy.

Design decision: nic = 0 counts as degraded. On the reference day the degraded signal is dominated by nic = 0 reports (~85% of all degraded points): aircraft dropped to "integrity unknown," which is the expected physical signature of a receiver under interference that can no longer bound its own error. Excluding it would throw away the strongest evidence of GPS denial, so it is folded in deliberately. Spatially this behaves as a real signal should: it concentrates in known interference zones (Baltic/Kaliningrad up to 1.0) and is near-absent over a quiet control (central US ~0.10 max). Sensitivity (kept on the record): the degraded-point fraction is 5.98% including nic = 0 vs 0.87% excluding it. Sample-day figures, so the map is largely a nic = 0 density surface, and you should read it as one. A per-hex strict view (1 ≤ nic ≤ 6) is a planned toggle to show that band directly. All thresholds live in a single config file and are versioned with the data.

Confidence & the honesty rule

Every hex ships with its unique-aircraft count and a confidence tier: high (≥10 aircraft), medium (5–9), and insufficient (<5). Hexes below the minimum-aircraft floor are never rendered as a value or a confident color. On the map they appear as a dim diagonal hatch (the Low-sample cells toggle). This is the whole point of the instrument: you can always tell "no interference" from "no coverage."

That distinction only works if coverage is visible: a dark cell could mean "watched and calm" or "nobody was looking." So measured-but-quiet airspace draws a faint watched-airspace carpet (the Quiet coverage toggle, on by default). It is a whisper that never competes with a real bloom, but it turns the black background into an honest three-state reading: quiet (watched, calm), degraded (the signal), hatched (too few aircraft to judge).

The sensor-desert paradox

There is a fourth state, and it is the most important caveat in the whole instrument. We measure interference where civil aircraft fly, which is systematically not the airspace that is closed or avoided. When airspace is closed or widely avoided the sky empties and the sensors leave with the traffic, so the worst jamming can sit inside a dark zone that means "nobody was looking," not "all clear." We see the edges of such airspace, not its interior. The overlay describes the instrument's blindness (an airspace-status fact), not the reasons behind it.

The Airspace context overlay (on by default) keeps that honest. A violet dashed outline with a faint wash (a hue never used for signal) marks airspace that is closed to civil aviation (e.g. Ukraine, since Feb 2022), of reduced coverage (e.g. Russia, widely avoided and thin on volunteer receivers), or a known test area (US ranges where GPS testing is recurring and announced). Each zone card leads with the regulatory fact and its source; click a zone to read it. So the fourth reading is outlined: the instrument is blind here, and that blindness is itself information. Zone outlines are drawn from Natural Earth boundaries as context, not precise airspace geometry.

Not every dark cell is a zone. Oceanic and remote-region darkness reflects terrestrial ADS-B receiver range (roughly 250 nm offshore before line-of-sight runs out) and volunteer-receiver sparsity, not airspace status. The traffic-density Coverage view is the honest instrument for where the sensors are; the zone layer is reserved for regulatory / conflict causes only. A dark ocean is a coverage fact, not a closed zone.

A worked example: same signal, three meanings

The instrument's core lesson is that the reading is not the analysis. On any given day, three places can look similar on the map and mean entirely different things, which is why context lives in the region profiles, not the color scale.

This is the whole thesis in one comparison: an instrument shows you where integrity degrades; deciding what it means is analysis, done with sources, never asserted by the map.

Validation

Two checks keep this honest:

Internal (quantified). On the reference day, known chronic zones light up as expected while a deliberate control stays dark:

Zonecells ≥5 aircraftmax degraded ratio
Kaliningrad / Baltic1211.00
Eastern Med / Cyprus1810.67
Central US (quiet control)2120.10

Signal and background separate cleanly; the method isn't lighting up everywhere aircraft fly.

External (independent reference). The persistent hotspots this archive surfaces (the Baltic/Kaliningrad corridor and the eastern Mediterranean) are the same regions independently mapped as chronic GNSS-interference zones by live trackers such as GPSJam and Flightradar24. Those tools show current conditions; you can compare any date directly on GPSJam. A dated side-by-side cross-check for 2026-07-13 found agreement on every major hot zone: Baltic/Kaliningrad, the Black Sea western rim through Istanbul and eastern Turkey, Moscow-area spots, and the eastern Mediterranean. That held despite the two projects drawing on different feeder networks (adsb.lol vs ADS-B Exchange). Two independent pipelines agreeing on the same date is strong corroboration; the writeup and caveats are in docs/validation/2026-07-13. It is visual corroboration between two ADS-B-derived estimates, not validation against ground truth.

Baselines & anomaly

Chronic zones are interesting; change is more interesting. For each hex we compute a rolling baseline (mean and standard deviation of bad_ratio over up to 28 qualifying days) and express each day as a z-score: how many standard deviations above its own normal the hex sits. The default map view is this anomaly score; a toggle shows the raw ratio. A hex needs at least 7 qualifying days of history before it earns a baseline, so early in the archive many hexes show raw values only. The baseline uses the window of available days around each date, which suits a retrospective archive rather than a real-time alarm.

What this instrument cannot see

Verification & quality

The instrument is built to be checked, not trusted on faith.

The external cross-check against independent instruments is covered under Validation above.

Reading the map honestly (design semantics)

The color choices are part of the method, not decoration. A few rules make the map trustworthy:

Time, data & licensing

Everything is UTC; the source dumps are UTC days. Source flight data © adsb.lol feeders and partners, published under the Open Database License (ODbL) 1.0. Our per-day aggregates are a derivative database, also published under ODbL; only aggregates are retained; raw traces are deleted after processing. The project code is MIT. Basemap © OpenStreetMap contributors via OpenFreeMap.

← back to the map