To use Web Map Tile Services (WMTS) offline, you must download the tiles from the server and store them locally. Using Cartopy utilities, you can retrieve tiles and store them in a NumPy binary format (.npy).
Warning: When caching high zoom levels, always specify x_bounds and y_bounds for your specific region of interest. Attempting to cache global extents at high zoom levels can lead to rate limiting or being banned from the tile provider due to the exponential increase in requests.
Example zoom level tile counts for global extents:
z=0: 1 tilez=5: 1,024 tilesz=10: 1,048,576 tilesz=15: 1,073,741,824 tiles
from pathlib import Path
import cartopy.crs as ccrs
import cartopy.io.img_tiles as cimgt
import numpy as np
from PIL import Image
from shapely import box
def cache_tiles(
tile_source,
max_target_z=1,
x_bounds=(-180, 180),
y_bounds=(-90, 90),
cache_dir="tiles",
):
"""Caches map tiles within specified bounds from a given tile source."""
if not isinstance(tile_source, cimgt.GoogleWTS):
tile_source = getattr(cimgt, tile_source)
tiles = tile_source(cache=cache_dir)
bbox = ccrs.GOOGLE_MERCATOR.transform_points(
ccrs.PlateCarree(), x=np.array(x_bounds), y=np.array(y_bounds)
)[:, :-1].flatten() # drop Z, then convert to x0, y0, x1, y1
target_domain = box(*bbox)
for target_z in range(max_target_z):
tiles.image_for_domain(target_domain, target_z)
return Path(cache_dir) / tile_source.__name__
# Example: Cache OpenStreetMaps tiles up to zoom level 6
cache_dir = cache_tiles("OSM", max_target_z=6)