Downloads Formula 1™ circuit geometries from OpenStreetMap as GeoJSON files.
# Install uv (if needed)
curl -LsSf https://astral.sh/uv/install.sh | sh
# Clone and install
git clone https://github.com/mvoof/F1TrackDownloader.git
cd F1TrackDownloader
uv sync# Download all circuits
uv run main.py
# Check for updates only
uv run main.py --check-update
# Alternative: run as module
uv run -m f1_downloaderOutput files are saved to tracks_geojson/ directory.
f1_downloader/
├── __init__.py # Package exports
├── __main__.py # Entry: python -m f1_downloader
├── config.py # Configuration dataclass
├── models.py # Circuit, SearchResult, CacheEntry
├── cache.py # CircuitCache class
├── clients/ # API clients
│ ├── overpass.py # Overpass API (5 servers, failover)
│ ├── wikipedia.py # Wikipedia parser
│ ├── wikidata.py # Wikidata API
│ └── osm.py # OSM API
├── services.py # Search and processing logic
├── utils.py # Logging, atomic writes
└── cli.py # CLI interface
main.py # Entry point wrapper
Wikipedia → Wikidata → OpenStreetMap → GeoJSON
- Fetch circuit list from Wikipedia
- Find Wikidata ID (Q-ID) for each circuit name
- Find OSM relation using:
- Wikidata P402 property (direct link to OSM)
wikidata=Q*tag search in OSM- Direct name search in OSM
- Download geometry from Overpass API
- Save as GeoJSON
The script uses 5 Overpass API servers with automatic failover:
- overpass-api.de (Germany, main)
- kumi.systems (Global)
- maps.mail.ru (Russia)
- private.coffee (Global)
- osm.jp (Japan)
If one server fails, the next is tried automatically.
All discovered mappings are cached in circuit_mappings.json:
- First run: searches for all circuits, saves results
- Subsequent runs: uses cached IDs, much faster
- Cache includes OSM ID, Wikidata ID, and search method
Some circuits can't be found automatically because:
- Different names in OSM
- Missing Wikidata links
- Circuit no longer exists
When a circuit is not found, it's automatically added to circuit_mappings.json with manual: true and a TODO comment.
Edit circuit_mappings.json. Minimal required fields:
"Autódromo Hermanos Rodríguez": {
"osm_id": 16251935,
"osm_type": "relation",
"manual": true
}Full example with all fields:
"Autódromo Hermanos Rodríguez": {
"osm_id": 16251935,
"osm_type": "relation",
"wikidata_id": "Q173099",
"manual": true,
"comment": "Found via Mexican Grand Prix search"
}| Field | Required | Description |
|---|---|---|
osm_id |
Yes | OSM element ID (number) or null if doesn't exist |
osm_type |
Yes | "relation" or "way" |
manual |
Yes | Set to true to prevent auto-updates |
wikidata_id |
No | Wikidata Q-ID (e.g., "Q173099") |
comment |
No | Notes for yourself |
search_method |
No | Auto-filled: how it was found |
search_name |
No | Auto-filled: which name matched |
verified_at |
No | Auto-filled: timestamp |
osm_version |
No | Auto-filled: for update tracking |
- Go to openstreetmap.org
- Search for the circuit name or browse the map
- Click on the track (look for
leisure=trackorhighway=raceway) - Check URL:
openstreetmap.org/relation/16251935→ ID is16251935, type isrelation - Or:
openstreetmap.org/way/123456→ ID is123456, type isway
For demolished or unmapped circuits, set osm_id to null:
"Ain-Diab Circuit": {
"osm_id": null,
"manual": true,
"comment": "Circuit demolished, not in OSM"
}Each circuit is saved as a GeoJSON FeatureCollection:
{
"type": "FeatureCollection",
"properties": {
"name": "Silverstone Circuit",
"_osm_id": 2783447,
"_osm_version": 15
},
"features": [
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [[...], [...]]
},
"properties": {
"role": "outer",
"ref": 123456
}
}
]
}Check the output message:
Not in OSM (Wikidata: Q123)→ Circuit exists in Wikidata but not linked to OSMNot found in Wikidata→ Need to add manually tocircuit_mappings.json
Also you can manualy check tags on OSM like highway=raceway or sport=motor and check track name.
The script automatically retries with different servers. If all fail:
- Check your internet connection
- Wait a few minutes (servers may be overloaded)
- Try again later
Delete the circuit entry from circuit_mappings.json or set manual: false to force re-search.
This repository is unofficial and is not associated in any way with the Formula 1 companies. F1, FORMULA ONE, FORMULA 1, FIA FORMULA ONE WORLD CHAMPIONSHIP, GRAND PRIX, and related marks are trademarks of Formula One Licensing B.V.
Formula 1™ circuits data are not official, and they are not approved nor endorsed by Formula One Licensing B.V.
This project is licensed under the MIT License - see the LICENSE file for details.
This tool uses data from:
- Wikipedia - Content is available under the CC BY-SA license
- OpenStreetMap - Data is available under the Open Database License (ODbL)
Please respect the respective licenses when using the downloaded data.