Tile Serving¶
Yoro Maps can download and serve map tiles offline, stored in MBTiles format inside the .yoromaps database.
How tiles work¶
Map tiles are small PNG images that cover the world at different zoom levels. At zoom 0, the entire world is one tile. At zoom 12, there are millions of tiles. Yoro Maps downloads only the tiles within a country's bounding box and stores them in the tiles table.
The tiles table uses the MBTiles specification with TMS (flipped Y) coordinate scheme.
Download tiles during build¶
CLI¶
# Build with tiles (default zoom 6-12)
yoromaps download ML --output mali.yoromaps --tiles
# Custom zoom range
yoromaps download ML --output mali.yoromaps --tiles --zoom-min 8 --zoom-max 14
Python¶
Tile download size
Higher zoom levels = exponentially more tiles. Zoom 14 for a large country like Mali can be 500+ MB and take hours to download. Start with zoom 12 and increase if needed.
Download tiles separately¶
You can add tiles to an existing .yoromaps database:
from yoromaps.db import open_db
from yoromaps.tiles import download_tiles
from yoromaps.countries import COUNTRIES
conn = open_db("mali.yoromaps")
country = COUNTRIES["ML"]
n = download_tiles(
conn,
bbox=country.bbox,
zoom_min=6,
zoom_max=12,
tile_url="https://tile.openstreetmap.org/{z}/{x}/{y}.png",
progress=lambda msg, cur, tot: print(f"{msg}: {cur}/{tot}"),
)
print(f"Downloaded {n} tiles")
Custom tile providers¶
The default tile source is OpenStreetMap. You can use any XYZ tile server by changing the URL template:
from yoromaps.tiles import download_tiles
# OpenStreetMap (default)
download_tiles(conn, bbox, tile_url="https://tile.openstreetmap.org/{z}/{x}/{y}.png")
# OpenTopoMap
download_tiles(conn, bbox, tile_url="https://tile.opentopomap.org/{z}/{x}/{y}.png")
# Stamen Terrain (Stadia Maps)
download_tiles(conn, bbox, tile_url="https://tiles.stadiamaps.com/tiles/stamen_terrain/{z}/{x}/{y}.png")
Note
Respect tile server usage policies. OpenStreetMap requires a valid User-Agent header (yoromaps sets one automatically) and limits bulk downloads. For large-scale use, consider running your own tile server.
Serve tiles from Django¶
With the Django integration configured, tiles are served at:
See the Django Integration guide for setup details.
Serve tiles from Python¶
You can retrieve tiles directly from the database:
from yoromaps.db import open_db
from yoromaps.tiles import get_tile
conn = open_db("mali.yoromaps")
# Get a tile (XYZ scheme — the function handles TMS conversion internally)
tile_data = get_tile(conn, z=10, x=512, y=512)
if tile_data:
with open("tile.png", "wb") as f:
f.write(tile_data)
Check tile count¶
from yoromaps.db import open_db
from yoromaps.tiles import tile_count
conn = open_db("mali.yoromaps")
print(f"Tiles in database: {tile_count(conn)}")
Or from the CLI:
Rate limiting¶
The tile downloader includes built-in rate limiting (50ms between requests) and sets a proper User-Agent header. Tiles that already exist in the database are skipped, so you can safely re-run the download to fill in missing tiles.
Zoom level guide¶
| Zoom | Coverage | Tiles per country | Use case |
|---|---|---|---|
| 6 | Region overview | ~50 | Country-level view |
| 8 | City overview | ~500 | Regional navigation |
| 10 | Neighborhood | ~5,000 | City navigation |
| 12 | Street level | ~50,000 | Street-level detail |
| 14 | Building level | ~500,000 | High detail |
Exact counts depend on the country's geographic area.