Download & Build¶
This guide covers how to download OSM data and build .yoromaps files.
How it works¶
The build process:
- Download — Fetches the latest
.osm.pbffile from Geofabrik for the chosen country. - Extract — Parses the PBF in two passes using pyosmium: first collecting highway ways and node references, then resolving node coordinates.
- Build graph — Inserts nodes (intersections) and edges (road segments) into the SQLite database, with distance and estimated travel time.
- Tiles (optional) — Downloads map tiles from OpenStreetMap tile servers and stores them in MBTiles format.
CLI usage¶
Basic build¶
With tiles¶
Custom zoom range¶
Using an existing PBF file¶
If you already have a PBF file (e.g., downloaded manually from Geofabrik):
List available countries¶
Python API¶
Basic build¶
With tiles and progress¶
from yoromaps.download import build
def on_progress(message, current, total):
if total > 0:
print(f"{message}: {current / total * 100:.0f}%")
else:
print(message)
build(
"ML",
"mali.yoromaps",
include_tiles=True,
zoom_min=6,
zoom_max=14,
progress=on_progress,
)
Using an existing PBF¶
from yoromaps.download import build
build("ML", "mali.yoromaps", pbf_path="/data/mali-latest.osm.pbf")
Download PBF only¶
from yoromaps.download import download_pbf
pbf_path = download_pbf("ML", "/tmp/downloads")
print(f"Downloaded to: {pbf_path}")
Road types¶
The extractor recognizes these OSM highway types, with estimated speeds used for routing duration:
| Highway type | Speed (km/h) |
|---|---|
| motorway | 110 |
| motorway_link | 60 |
| trunk | 90 |
| trunk_link | 50 |
| primary | 70 |
| primary_link | 40 |
| secondary | 60 |
| secondary_link | 35 |
| tertiary | 50 |
| tertiary_link | 30 |
| residential | 30 |
| unclassified | 40 |
| living_street | 20 |
| service | 20 |
| track | 15 |
| path | 5 |
One-way streets are respected: if an OSM way has oneway=yes, only a forward edge is created.
Updating an existing database¶
After the initial download, use update to refresh the road graph with the latest OSM data. Only re-downloads if Geofabrik has published a newer PBF file.
CLI¶
# First time: re-downloads (no previous date stored)
yoromaps update mali.yoromaps
# Second time: skips if nothing changed
yoromaps update mali.yoromaps
# → "Already up to date" — instant, no download
# Custom PBF cache directory
yoromaps update mali.yoromaps --cache-dir /data/pbf-cache
Python API¶
import yoromaps
result = yoromaps.update("mali.yoromaps")
if result["updated"]:
print(f"Updated: {result['nodes']:,} nodes, {result['edges']:,} edges")
print(f"Previous: {result['previous_date']}")
print(f"New: {result['new_date']}")
else:
print(f"Already up to date (since {result['previous_date']})")
What happens during an update¶
- Checks
osm_update_datein the database metadata - Sends HTTP
If-Modified-Sinceto Geofabrik — if the PBF hasn't changed, stops immediately (no download) - If newer data exists, downloads the new PBF
- Clears the road graph (nodes + edges tables)
- Re-extracts from the new PBF
- Preserves all POI data and tiles — only the road graph is rebuilt
Automate updates
Set up a cron job or Django management command to run yoromaps.update() weekly:
# management/commands/update_maps.py
from django.core.management.base import BaseCommand
import yoromaps
class Command(BaseCommand):
def handle(self, **options):
result = yoromaps.update("/data/mali.yoromaps")
if result["updated"]:
self.stdout.write(f"Updated: {result['nodes']:,} nodes")
else:
self.stdout.write("Already up to date")
File sizes¶
Tested file sizes (road graph only, no tiles):
| Country | PBF size | Nodes | Edges | .yoromaps size | Build time |
|---|---|---|---|---|---|
| Togo | 59 MB | 2.2M | 2.3M | 436 MB | ~55s |
| Mali | 163 MB | 6.4M | 6.7M | 1.3 GB | ~145s |
Adding tiles at zoom 6-14 adds 200-500 MB depending on the country area.
Note
File sizes depend on OSM data completeness. Countries with more mapped roads produce larger databases.