Last active
April 4, 2018 17:45
-
-
Save danthedaniel/dad4407ce35e7b03eb8e7d3af3df0688 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import requests | |
from multiprocessing.dummy import Pool | |
from io import BytesIO | |
from PIL import Image | |
from tqdm import tqdm | |
from itertools import product | |
# URL format | |
TILE_URL = "http://maps.izurvive.com/maps/CH-Top/1.10.5/tiles/{z}/{x}/{y}.png" | |
# Zoom level to map x/y size in tiles | |
ZOOM_LEVELS = { | |
1: 1, | |
2: 3, | |
3: 7, | |
4: 15, | |
5: 30, | |
6: 61 | |
} | |
def get_tile(zoom, x, y): | |
"""Get one tile from iZurvive.""" | |
response = requests.get(TILE_URL.format(z=zoom, x=x, y=y)) | |
return ((x, y), Image.open(BytesIO(response.content))) | |
def tile_mapper(args): | |
"""This would have been an anonymous function in a language that respects | |
functional programming...""" | |
pbar, *args = args | |
ret = get_tile(*args) | |
pbar.update(1) | |
return ret | |
def get_map(zoom, n_requests): | |
"""Get an entire map for a given zoom level.""" | |
tile_range = range(ZOOM_LEVELS[zoom] + 1) | |
n_tiles = len(tile_range) | |
total = n_tiles * n_tiles | |
pool = Pool(n_requests) | |
with tqdm(desc="Downloading Tiles", total=total, unit="tile") as pbar: | |
# Construct a generator yielding argument tuples for the mapping func | |
args = ((pbar, zoom, x, y) for x, y in product(tile_range, tile_range)) | |
# Asyncronously map the arguments to tile images | |
tiles = pool.map(tile_mapper, args) | |
tile_size = tiles[0][1].size # Assumes all tiles are the same size | |
dimensions = (tile_size[0] * n_tiles, tile_size[1] * n_tiles) | |
full_map = Image.new("RGB", dimensions) | |
for location, tile in tqdm(tiles, desc="Combining Tiles", total=total, unit="tile"): | |
# The upper-left pixel coordinates for the tile | |
box = ( | |
location[0] * tile_size[0], | |
tile_size[1] * (n_tiles - location[1]) | |
) | |
full_map.paste(tile, box) | |
return full_map | |
chernarus = get_map(zoom=4, n_requests=10) | |
print("Saving File...") | |
chernarus.save("chernarus.png") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment