Haroenv/wwi-paris-bombing

Interactive map + timeline of the WWI bombardments of Paris and its suburbs (1914–1918)

★ 0Forks 0HTMLGitHub ↗Compare

Project website ↗

README

Bombardments of Paris, 1914–1918 — interactive map

An interactive MapLibre GL map + timeline of every recorded bomb and shell impact on Paris and its suburbs during the First World War.

Open index.html in a browser (keep the images/ folder alongside it). The event data is embedded in the HTML; only the basemap tiles (OpenFreeMap) and the MapLibre library (unpkg CDN) need a network connection.

Repository layout

Published site — the only files GitHub Pages serves (everything the browser fetches):

Path What
index.html The built visualization (event data embedded inline).
images/ 46 cached photographs the popups/gallery display.

Source you edit:

Path What
index.template.html The page source (HTML/CSS/JS) with /*__DATA__*/ placeholders. Edit this, not index.html.
parse.py, fetch_insee.py, geocode.py, fetch_images.py, build_html.py The data pipeline (see below).
README.md This file.

Generated data — committed so the site can be rebuilt without re-fetching everything; do not hand-edit (regenerate via the scripts):

Path Produced by
page_wikitext.json raw Wikipedia source (initial download)
events.json parse.py
insee.json fetch_insee.py
events.geo.json geocode.py
credits.json fetch_images.py

Not committed (see .gitignore): __pycache__/, geo_in.csv/geo_out.csv (geocoder scratch), .claude/, .DS_Store.

Which scripts run, and when

The Python scripts are a build-time pipeline that fetches from external services (Wikipedia, the Base Adresse Nationale, geo.api.gouv.fr, Wikimedia Commons). They are not run by the website or by the deploy workflow — run them locally only when you want to refresh the data, then commit the regenerated index.html + images/. The published site is pure static HTML/JS + images.

Publishing (GitHub Pages)

.github/workflows/deploy.yml deploys on every push to main: it stages just index.html + images/ and publishes them via GitHub Pages (it does not run the Python pipeline). To update the live site, rebuild locally, commit, and push.

Features

  • 820 impacts plotted, coloured by weapon type (aircraft / Zeppelin / long-range gun).
  • Vector basemap (OpenFreeMap, no API key) re-tinted to a period parchment palette.
  • Impacts sized by casualties; a gold ring marks those with a photograph.
  • Circle size scaled by casualties.
  • Paris Gun firing positions, time-linked (with the long-range-gun layer): the timeline names the active firing position as it moves over 1918 — Forest of Saint-Gobain (~113 km) → Beaumont-en-Beine (~109 km) → north of Château-Thierry (~91 km) — with a red trajectory line to Paris. "View firing area" zooms out to show all three positions at true regional scale.
  • Timeline with a play button (scrub or animate through the war), in cumulative or 7-day window mode.
  • Filter by weapon type; live killed/wounded stats.
  • Click any impact for date, address, casualties, the original French note, and per-event source links (the contemporary newspaper article, plus the Wikipedia table).
  • Photographs: events with a damage photo (or a present-day commemorative plaque) are marked with a gold ring; the popup shows the captioned image(s) — historical damage photo plus, where one exists, the modern plaque at that address — click to enlarge in a lightbox. The Sources drawer also has a Weapons & context gallery (Taube, Gotha, Pariser Kanon, shell diagram, and the historical Paris Gun shell-impact map).
  • A Sources & method drawer listing the authoritative collections behind the data.

Sources

Wikipedia compiles three layers of documentation, all surfaced in the app:

Data pipeline (reproducible)

  1. page_wikitext.json — raw wikitext of the French Wikipedia article, fetched via the MediaWiki API.
  2. python3 parse.py → events.json — parses the recapitulative table (date, weapon type, address, place, comment, casualties).
  3. python3 fetch_insee.py → insee.json — resolves each commune to its INSEE code and official centre via geo.api.gouv.fr (Île-de-France only, with alias handling for quartiers).
  4. python3 geocode.py → events.geo.json — geocodes addresses via the French Base Adresse Nationale bulk API. The commune is applied as a strict INSEE citycode filter (arrondissements by postcode), so a street name can never match a same-named street in another town. Each result is validated (right area + plausible street name); anything unconfirmed falls back to the commune / arrondissement centre.
  5. python3 fetch_images.py → images/ + credits.json — downloads every image used (damage photos, plaques, context illustrations) from Wikimedia Commons at 1280 px, and records each one's licence + author for attribution.
  6. python3 build_html.py → index.html — embeds the data, credits and image paths.

Rebuild everything: python3 parse.py && python3 fetch_insee.py && python3 geocode.py && python3 fetch_images.py && python3 build_html.py

Images & licensing

Images are cached locally in images/ so the map works offline (only the basemap tiles need a network). Licences (from Commons): ~33 public domain, a few CC0 / "no restrictions", and several CC BY-SA (the modern plaque photos and a handful of illustrations). The CC images carry their author + licence in the lightbox and a short credit under the popup thumbnail; every image also links to its Commons file page. Redistribution is permitted under these licences provided that attribution is shown, which it is. images/ (~16 MB) ships alongside index.html.

Data caveats

  • Casualties are parsed from free-text French notes. Totals: 285 killed, 755 wounded across the table. Many minor impacts list no casualties.
  • Locations: 678 of 820 resolved to exact street addresses (geocoded within the correct commune via its INSEE code); 142 fell back to the area centre (shown with a ⚠ note in the popup) — renamed/demolished streets, intersections, and landmarks that can't be confirmed to a single point.
  • The deadliest single event is correctly the Saint-Gervais church shelling (29 March 1918, 92 killed).
  • Source data is as complete/accurate as the Wikipedia table; it is the most granular public list of these events.

Contributors

Haroenv

Issues