Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for parallel tile downloads and control of cache #217

Merged
merged 6 commits into from
Jun 12, 2023
32 changes: 22 additions & 10 deletions contextily/tile.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import rasterio as rio
from PIL import Image
from joblib import Memory as _Memory
from joblib import Parallel, delayed
from rasterio.transform import from_origin
from rasterio.io import MemoryFile
from rasterio.vrt import WarpedVRT
Expand Down Expand Up @@ -74,6 +75,7 @@
ll=False,
wait=0,
max_retries=2,
num_parallel_tile_downloads=16,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
num_parallel_tile_downloads=16,
n_connections=16,

Something shorter like this would be preferable.

):
"""
Take bounding box and zoom, and write tiles into a raster file in
Expand Down Expand Up @@ -113,6 +115,9 @@
[Optional. Default: 2]
total number of rejected requests allowed before contextily
will stop trying to fetch more tiles from a rate-limited API.
num_parallel_tile_downloads: int
[Optional. Default: 16]
number of parallel tile downloads.

Returns
-------
Expand All @@ -126,7 +131,9 @@
w, s = _sm2ll(w, s)
e, n = _sm2ll(e, n)
# Download
Z, ext = bounds2img(w, s, e, n, zoom=zoom, source=source, ll=True)
Z, ext = bounds2img(w, s, e, n, zoom=zoom, source=source, ll=True,
num_parallel_tile_downloads=num_parallel_tile_downloads)

# Write
# ---
h, w, b = Z.shape
Expand Down Expand Up @@ -155,7 +162,7 @@


def bounds2img(
w, s, e, n, zoom="auto", source=None, ll=False, wait=0, max_retries=2
w, s, e, n, zoom="auto", source=None, ll=False, wait=0, max_retries=2, num_parallel_tile_downloads=16
):
"""
Take bounding box and zoom and return an image with all the tiles
Expand Down Expand Up @@ -193,6 +200,9 @@
[Optional. Default: 2]
total number of rejected requests allowed before contextily
will stop trying to fetch more tiles from a rate-limited API.
num_parallel_tile_downloads: int
[Optional. Default: 16]
number of parallel tile downloads.

Returns
-------
Expand All @@ -214,14 +224,16 @@
zoom = _calculate_zoom(w, s, e, n)
zoom = _validate_zoom(zoom, provider, auto=auto_zoom)
# download and merge tiles
tiles = []
arrays = []
for t in mt.tiles(w, s, e, n, [zoom]):
x, y, z = t.x, t.y, t.z
tile_url = provider.build_url(x=x, y=y, z=z)
image = _fetch_tile(tile_url, wait, max_retries)
tiles.append(t)
arrays.append(image)
max_num_parallel_tile_downloads = 32
if num_parallel_tile_downloads < 1 or num_parallel_tile_downloads > max_num_parallel_tile_downloads:
raise ValueError(

Check warning on line 229 in contextily/tile.py

View check run for this annotation

Codecov / codecov/patch

contextily/tile.py#L229

Added line #L229 was not covered by tests
f"num_parallel_tile_downloads must be between 1 and {max_num_parallel_tile_downloads}"
)
tiles = list(mt.tiles(w, s, e, n, [zoom]))
tile_urls = [provider.build_url(x=tile.x, y=tile.y, z=tile.z) for tile in tiles]
arrays = \
Parallel(n_jobs=num_parallel_tile_downloads)(
delayed(_fetch_tile)(tile_url, wait, max_retries) for tile_url in tile_urls)
merged, extent = _merge_tiles(tiles, arrays)
# lon/lat extent --> Spheric Mercator
west, south, east, north = extent
Expand Down