Public transport map across Great Britain and Ireland
  • Python 86.1%
  • HTML 10.9%
  • JavaScript 1.5%
  • Shell 0.5%
  • Dockerfile 0.4%
  • Other 0.6%
Find a file
benmandrew 0e2f664ffb
feat(viewer): narrow the left panels and thin the key's ticks to fit
The two panels on the left were 272px of a screen whose subject is underneath
them. The stack goes to 216px and the key to 150px, which is the first panel
here to be narrower than the stack it sits in: nothing in it is prose -- eight
mode names, a bar each and one row of ticks -- so the width it needs is the
width of the widest of those and not the width of the panel above.

The header is the same height at the new width rather than taller, because the
title column now takes the whole row and the buttons take the next one. The
110px floor `base.css` puts on that column is what a 272px panel wanted: there
the row held the title and three of the four buttons and wrapped the fourth
alone, which is a ragged two rows where this is a tidy one plus one. The
placeholder loses "Filter by", which the input's own label still says and which
did not fit.

Six ticks reading 3 to 1000+ are 107px of text and want a bar of 270 to stand
clear of each other -- wider than the key needs for anything else in it, and on
a 150px panel "300" and "1000+" print on top of each other. So `thinTicks`
drops every second one, then every third, until what is left stands clear: 3,
100 and 1000+ on the desktop panel, all six on a phone, where the key is the
width of the screen. Both ends are kept whatever the step, because they are the
range, and that is the one thing a bar with no numbers under it cannot say.

Measured rather than counted, because how many fit is the reader's font size as
much as the panel's width. Thinning from the left was the first try and it
packs the labels at the low end and leaves a hole before the last, which reads
as a fault rather than as a scale. A `ResizeObserver` is what runs it again: the
key folds away at some widths, a fold has no width to measure against, and the
call sites for the fold, the window and a phone turning would be three and would
go on being three.
2026-09-03 01:46:54 +01:00
.github/workflows ci(lint): check the markdown's links with lychee 2026-08-17 00:29:14 +01:00
.vscode feat(map): share one paint contract between Python and JavaScript 2026-08-16 22:25:21 +01:00
deploy feat(snap): add a snap stage to give shaped rail OSM way ids 2026-08-16 19:22:50 +01:00
docs feat(basemap): replace CARTO raster tiles with a self-hosted vector basemap 2026-09-01 17:08:23 +01:00
scripts fix(basemap): mute the sea in both flavours 2026-09-03 01:38:03 +01:00
tests fix(basemap): paint the roam margin as ground and hold the map in it 2026-09-03 01:39:11 +01:00
wayfare feat(basemap): replace CARTO raster tiles with a self-hosted vector basemap 2026-09-01 17:08:23 +01:00
web feat(viewer): narrow the left panels and thin the key's ticks to fit 2026-09-03 01:46:54 +01:00
.dockerignore fix(ci): keep docker build context and cache scoped correctly 2026-08-07 11:59:20 +01:00
.env.example docs(env): document WAYFARE_ART 2026-08-08 16:32:45 +01:00
.envrc feat(dev): add a nix flake as the only dev environment 2026-08-07 14:37:23 +01:00
.gitignore ci: gate the coverage badge on the report the test step writes 2026-08-16 19:50:13 +01:00
.hadolint.yaml ci(lint): add biome, actionlint and hadolint; widen ruff selection 2026-08-17 00:19:57 +01:00
.taplo.toml feat(map): share one paint contract between Python and JavaScript 2026-08-16 22:25:21 +01:00
biome.jsonc feat(basemap): replace CARTO raster tiles with a self-hosted vector basemap 2026-09-01 17:08:23 +01:00
CLAUDE.md docs: cut the docs down to decisions, drop dated measurements 2026-08-18 00:26:43 +01:00
docker-compose.yml docs: close the gaps a cross-check found in the rewritten set 2026-08-15 22:59:46 +01:00
Dockerfile ci(lint): add biome, actionlint and hadolint; widen ruff selection 2026-08-17 00:19:57 +01:00
flake.lock feat(dev): add a nix flake as the only dev environment 2026-08-07 14:37:23 +01:00
flake.nix ci(lint): check the markdown's links with lychee 2026-08-17 00:29:14 +01:00
pyproject.toml ci(lint): add biome, actionlint and hadolint; widen ruff selection 2026-08-17 00:19:57 +01:00
README.md docs: cut the docs down to decisions, drop dated measurements 2026-08-18 00:26:43 +01:00

Wayfare

Coverage

Every service across Ireland and southern Britain, from Kerry to Lowestoft, drawn from the three published archives: road in blue through yellow by journeys a day, rail in orange, ferry in crimson

Wayfare builds an aggregate dataset of public transport routes across Great Britain and Ireland. It produces a PMTiles archive, a tiled hierarchical map file, behind an interactive map where hovering a road lists the services on it.

Quick start

Wales is 41 MB zipped and exercises every stage, which makes it a better first run than the national bundle. WAYFARE_REGION and WAYFARE_OSM_URL must describe the same area.

$ cat > .env <<'EOF'
WAYFARE_REGION=wales
WAYFARE_OSM_URL=https://download.geofabrik.de/europe/united-kingdom/wales-latest.osm.pbf
EOF
$ direnv allow                      # or: nix develop
$ docker compose up -d valhalla     # builds its graph before it answers anything

$ wayfare acquire --region wales    # resolves its own extract URL from --region
$ wayfare patterns
$ wayfare match                     # the long one
$ wayfare aggregate
$ wayfare publish
$ wayfare status
$ wayfare serve                     # viewer on http://localhost:8099

On a server

$ docker compose up -d valhalla     # first start builds the graph
$ docker compose run --rm pipeline  # every stage, acquire through publish
$ docker compose up -d web          # viewer and renderer on :8099

pipeline runs wayfare all, which is safe to interrupt and re-run, since every stage skips work already done. It runs the same stages in the same order as deploy/refresh.sh, which is for incremental updates on a schedule.

Data sources and licences

Source Covers Licence
DfT Bus Open Data Service (BODS) GTFS Great Britain Open Government Licence (OGL) v3.0
NaPTAN stop register Great Britain OGL v3.0
National Transport Authority (NTA) GTFS, published as Transport for Ireland Republic of Ireland Creative Commons Attribution (CC BY) 4.0
Translink TransXChange timetables and MapInfo route geometry, via OpenDataNI Northern Ireland OGL v3.0
Geofabrik OpenStreetMap extracts all three Open Database License (ODbL)

Further reading

  • docs/pipeline.md — the nine stages, storage, clustering, tiles.
  • docs/data.md — the feeds, their traps, mode filtering, coverage gaps, attribution.
  • docs/deploy.md — the scheduled refresh, and the publish gate that guards it.