# GB railway stations through time, v1

Every railway station Great Britain has had, living and closed:
**9,663 dated stations** (3,011 open today), each with an
opening year, a closing year where it has gone, coordinates, and a
per-date record of where that date came from, plus the
population-weighted distance-to-nearest-station percentiles per year
that the chart draws.

## Scope

Every railway station **except trams**: National Rail, London
Underground, the metros (Tyne and Wear, DLR, Glasgow Subway), airport
transit, monorails and funiculars, heritage and miniature lines, and
the closed stations of all of them. The `system` column says which
(national-rail 8,513, heritage 542, london-underground 276, metro 127, industrial 80).
**If you want heavy rail only, filter `system == 'national-rail'`.**

Great Britain means the island and its offshore islands, **not** the
Crown Dependencies: Northern Ireland and the Isle of Man are excluded.

Open National Rail stations come to 2,618 rows and
**2,612 distinct CRS codes**. Checked against DfT NaPTAN directly
(`check_naptan_coverage.py`, joining NaPTAN's ATCO code to CRS through
CORPUS, so no name matching is involved), **coverage of the live
network is complete**: of 2,635 active NaPTAN rail stations, 2,603 are
open here, 18 more are second codes for a station we already have open
(high and low level platforms), and 7 are stations NaPTAN still lists
as active that closed years ago (Wedgwood, Barlaston, Teesside
Airport, IBM). 7 remain (Bristol Brabazon Rail Station, Frosterley Rail Station, Porthmadog Harbour Ffestiniog Railway Station, Southease - Piddinghoe Road, Southsea Hoverport, Stanhope Rail Station, Wolsingham Rail Station), and they are not
a coverage gap either: Frosterley, Stanhope, Wolsingham and Porthmadog
Harbour are heritage railways, Southsea Hoverport is not a railway
station, Southease holds a second code, and Bristol Brabazon is a 2026
opening. These counts are recomputed at every publish
(`check_naptan_coverage.py`).

## Where the dates come from

Each date carries its own basis in `opened_src` / `closed_src` /
`reopened_src`, and its own source URL in `opened_source` /
`closed_source` / `reopened_source`. A `+` in a basis means "year from
the first source, precision from the second".

| basis | openings | closures |
|---|---|---|
| `distribution-est` | 0 | 81 |
| `manual` | 287 | 230 |
| `osm` | 6 | 3 |
| `quick` | 8,308 | 5,620 |
| `segment-est` | 265 | 128 |
| `unknown` | 0 | 173 |
| `wikidata` | 248 | 72 |
| `wikidata+prose` | 4 | 0 |
| `wikidata+wikipedia` | 467 | 20 |
| `wikipedia` | 54 | 626 |
| `wikipedia+category` | 10 | 5 |
| `wikipedia+prose` | 8 | 8 |
| `wikipedia-category` | 3 | 40 |
| `wikipedia-list` | 0 | 20 |
| `wikipedia-prose` | 3 | 7 |

Of 6,652 closed stations (rows not open today; a further
381 open stations carry a past closure and a reopening),
**6,270 (94.3%) carry a
station-level closure record**. 93% of openings and 93% of closures
carry a month or a day, not just a year.

One source outranks every automatic tier, and two bases are estimates
that should never be read as facts about an individual station:

- **`quick`**: Michael Quick, *Railway Passenger Stations in Great
  Britain: a Chronology*, version 5.05 (2023); each date links to the
  page of the PDF it comes from.
  "op" is the first day fare-paying passengers were carried on a
  timetabled train, "clo" the first day services did not run, the same
  convention as this table. The Chronology is a source: its dates are
  cited, page by page, and neither the PDF nor its text is
  redistributed. Quick excludes preserved lines, so heritage stations
  never take dates from it.
- **`segment-est`**, the station inherits the opening or closing year
  of the route-history segment it sits on. Right for the great cull
  years, wrong where a station outlived or predeceased its line. The
  `*_source` field names TWO separate doubts, because they are
  different questions:

  * **association**, is the station really on that segment? Distance
    decides, and it is bimodal: p50 36 m, p75 58 m, then p90 222 m.
    Beyond 100 m the string says "association uncertain" (72 openings,
    38 closures). Moor Road inherits from an UNNAMED segment 157 m away.
  * **date quality**, is the segment's OWN date sourced, or itself an
    estimate? An inherited date resting on an estimate is an estimate
    of an estimate (53 openings, 21 closures).

  Only 11 openings carry both. Neither is refused: for those rows it is
  the best answer available, and refusing would drop real places out of
  the table. They say so instead.
- **`distribution-est`**, no closure record anywhere; a year drawn
  deterministically from the closure distribution of stations opened
  within ±15 years. Right in aggregate, wrong per station. Capped at
  1975, so it cannot invent a modern closure.

**`unknown`** means the station is not open today, no source records a
closure, and imputing one would have been implausible. The year is
deliberately null rather than fabricated.

## How much of this is checked

Dates are held by up to six sources: Quick's Chronology, the Wikipedia
infobox event ladder, the article prose, the `opened in YYYY` /
`closed in YYYY` categories, Wikipedia's closed-station lists, and
Wikidata. They are separately held, not independent: Wikidata imports
from Wikipedia, the four Wikipedia readings come from the same editors,
and Wikipedia articles cite Quick and Butt for their dates. So
corroboration below measures agreement between records, not
independent confirmation; most dates are corroborated in that sense. Recomputed at every publish over every row
with a Wikidata id; a source "holds" a year when it gives one for the
row, and a date is corroborated when two or more sources give the year
the table carries:

| | openings | closures |
|---|---|---|
| corroborated: two or more sources give the year | **85.6%** | **85.9%** |
| one source only holds a year | 2.4% | 4.8% |
| sources held years but fewer than two give ours | 7.7% | 4.5% |
| modelled, nothing to check against | 2.7% | 3.0% |
| no source holds a year (hand entry, OSM, no Wikidata id) | 1.6% | 1.7% |

Where two sources both hold a year, they agree with each other
**88.2%** of the time on openings and
**88.1%** on closures. Most of the closure
gap is convention, not error: Wikipedia's `closed in` category tends
to the FINAL closure while this file records closure to passengers.

Separately, on 2026-09-01 a random sample of 25 rows was put beside
each station's article and adjudicated by hand by the same researcher
who built the table (so a check, not an independent audit): 23 clean, one arguable
(a station opened under one name and renamed later, so the year depends
which name you are dating) and one wrong, an article covering two
stations whose bare infobox fields straddled the pair. Both are fixed
and cited.

## Conventions

- **A closure is a closure to PASSENGERS.** "Closed to passengers 1958,
  goods until 1964" is 1958. Wikidata's own P3999 often holds the goods
  year and is corrected against the article where it does.
- **`public_passenger` is about the row's dated life, not the line's
  status today.** Pickering served the public network 1845-1965 and is
  `public_passenger=1` for those years even though its line is
  preserved now; its closure year ends its public life without help.
  A station is excluded (438 rows) only when it had no public life
  to record, a preservation-era station opened after its line's public
  closure, or an adjudicated goods depot, mail platform, private halt,
  tourist operation or never-opened site. `pp_basis` says which.
- **`duplicate_of` marks a station present twice** (18 rows), two
  OSM objects for one place. **Filter on it whenever you count
  stations.**

## The percentiles file

`station_distance_percentiles.csv`: for each year, the distance from
where people live to the nearest station then open, population-
weighted percentiles (p50/p75/p90/p95/p99), in miles and km.

It counts **public passenger stations only**, which is what the
external validation row counts. It also skips a station that is not
open today and carries no closure year: its span is unknown, and
treating a null closure as "never closed" would keep it in the modern
count.

Two deliberate conventions, stated plainly:

- **Today's population, every year.** People are weighted by the
  2021/2022 census output-area centroids (ONS + NRS, OGL v3) in 1850 as
  much as in 2026. The question answered is "how far would TODAY'S
  population have been from a station in year Y", not "how far were the
  people of year Y".

  **That bias has now been measured, and it is not a uniform offset.**
  A parallel workstream has built a year-native population surface and
  run both weightings over this same station table. Median distance in
  miles, the people of the year against today's people:

  | year | contemporary | today's (this file) |
  |---|---|---|
  | 1851 | 1.72 | 1.52 |
  | 1881 | 0.81 | 0.83 |
  | 1891 | 0.71 | 0.76 |
  | 1911 | 0.55 | 0.69 |
  | 1921 | 0.56 | 0.69 |
  | 1961 | 0.76 | 0.81 |

  These rows are read at publish time from the population workstream's
  `distance_percentiles.csv`, which is the series the site charts;
  the contemporary column there is Great Britain in every census year,
  and its error bands are in that file. They cross over around
  1881. Before then the people of the time were
  FURTHER from their own network than today's population would be,
  because the early network served towns and modern settlement has
  since grown around it; after it, the reverse. **So this file flatters
  the Victorian years and penalises the interwar peak.** This file
  remains the present-day check: its final year is the external
  validation row below, and it is the only series here that can be
  compared with a NaPTAN-based measurement.
- **Straight-line distance**, not travel distance.

Latest year (2026): p50 1.0 mi,
p90 4.03 mi. The external validation row is computed at
every publish by `naptan_distance_check.py` from DfT NaPTAN's active
rail stops and the same population centroids, no station of ours
involved (`naptan_distance_check.json`, inputs pinned by hash, run
2026-09-13): median **1.05 mi**, p90
**4.05 mi** over 2,639
stops. NaPTAN's scope is not this table's: it carries heritage-line
stations and not London Underground or the metros. Dropping the
10 stops this table marks heritage or not
public passenger (the like-series variant) gives
1.06 / 4.08;
the Underground and metro difference is not recoverable from NaPTAN.

## gb_stations.csv schema

- `station_id`, Wikidata QID where known, else the OSM object id
- `name`, `lat`, `lon` (EPSG:4326), `easting`, `northing` (EPSG:27700)
- `position_src`, `osm` or `wikidata`, whichever placed the station;
  `wikipedia` for a station with no Wikidata coordinate, placed from
  its own article's `{coord}` (or a line article's);
  `village-centre` for the few stations that neither holds, named in
  a closed-station list and placed at the centre of their village
  (Wikidata's coordinate for the settlement). Those rows are the
  village's position, not the station's: fine for a distance-to-
  nearest-station surface at parish scale, wrong by up to a mile
  for anything finer. `between-stations` for a station Quick's
  Chronology places between two named neighbours we hold and nothing
  else locates: the midpoint of the two, so wrong by up to half their
  spacing.
  Worth having: both coordinate errors found by auditing this table
  came from Wikidata, copied out of the article's own `{coord}`.
- `opened`, `closed`, `reopened`, years; `closed` empty = still open.
  **`closed` is closure to PASSENGERS**, which is what a question about
  public transport access needs. Most closed British stations shut in
  stages, so it is often not the day the site fell silent: Quainton
  Road lost its passengers on 4 March 1963 and its goods service on
  4 July 1966.
- `closed_final`, `closed_final_date`, `closed_final_kind`,
  `closed_final_src`, `closed_final_source`, the LAST closure the
  article records, when it is later than the passenger one. Populated
  for 1,710 of 6,652 closed stations; empty means no source records a
  later event, not that none happened. `closed_final_kind` says what
  ended, `goods` (797), `complete` (446), `workmen` (18, miners' and
  school trains outliving the service) or `other` (449, a closure whose
  traffic the text does not name). A temporary or wartime closure is
  never used. **Use `closed` for access questions and `closed_final`
  for "when did the railway stop coming here".**
- `opened_date`, `closed_date`, `reopened_date`, the same events as
  precise as the SOURCE is: `1862-06-02`, `1928-07` or `1862`, never
  padded
- `open_today`, 1/0, in service on any system in scope
- `heritage`, 1 if the station sits on a heritage line **today**; see
  `public_passenger` for whether it had a public life
- `public_passenger`, `pp_basis`, see Conventions
- `duplicate_of`, the row this one repeats, empty if unique
- `system`, `access`, `function` and their `*_basis` columns , 
  `system` is evidenced and usable; `access` and `function` are mostly
  `default`, meaning "nothing said otherwise", and the basis column
  says so on every row. Do not read their totals as findings.
- `lines_within_100m`, `nearest_line`, `nearest_line_m`
- `kind`, station | halt
- `opened_src` / `closed_src` / `reopened_src`, the basis table above
- `opened_source` / `closed_source` / `reopened_source`, the URL
- `crs`, `osm_id`, `wikidata`, joins to other datasets

## Known limitations

- **Stations are missing, and not slightly.** Checked against
  Wikipedia's own closed-station lists (5,326 names): after matching
  every name, old name and partial name we hold, **220 stations
  those lists name are absent from this table**, and the lists cover
  only some counties, so the true figure is higher. There is no
  independent national count of every station that ever existed to set
  a ceiling on it, so this figure is a floor with no upper bound. It reconciles with
  no independent national count: closures of public stations in the
  Beeching years 1963-70 come to 1,783 here, against 2,363
  stations listed for closure in the 1963 report (Beeching, *The
  Reshaping of British Railways*, 1963, p. 97), which is a proposal, not
  an outcome, so the two are not comparable. These were stations people
  could walk to, so their absence biases historical distances LONG,
  most in the 1850s-80s and 1930s where the missing cluster. They are
  missing because neither OSM nor Wikidata holds a position for them;
  most have no Wikipedia article either. The names are in
  `missing_from_lists.json` in the build directory.
  A further 95 of the listed names are in the table at
  village-centre precision and 23 at a coordinate taken from a line
  article (see `position_src`); the rest have no settlement to stand in
  for them, or a name too ambiguous to place.
- Reopening dates are honoured only where a dated later opening exists;
  closure-then-silence on an open station is treated as a records
  artefact, matching the route-history convention.
- 65 dates are contested between an article's infobox and its own
  category, and are not guessed, the table keeps the majority reading
  (`contested_dates.tsv`).
- Four Tanfield Railway stations carry the 1725 wagonway date, which is
  wrong; no source gives their real opening. They are
  `public_passenger=0`.
- `segment-est` inherits from the route-history dataset, where a
  RENAMED route carries the renaming year. Guarded against here, but it
  is why a handful of inherited openings look modern.

Licence: ODbL (positions from OSM); dates CC0/CC BY-SA per source.
Attribute "Mind the Gates railway atlas / © OpenStreetMap
contributors".
