|
1 | 1 | # pylint: disable=unused-argument
|
2 | 2 | """Provide utility functions"""
|
| 3 | +import os |
3 | 4 | from os import path as op
|
4 | 5 | from urllib.parse import urlparse, parse_qs
|
5 | 6 |
|
6 |
| -from mercantile import bounds |
| 7 | +from mercantile import bounds, Tile, children |
7 | 8 | from PIL import Image
|
| 9 | +import io |
8 | 10 | import numpy as np
|
9 | 11 | import requests
|
10 | 12 | import rasterio
|
11 | 13 | from rasterio.crs import CRS
|
12 | 14 | from rasterio.warp import transform, transform_bounds
|
| 15 | +from rasterio.windows import Window |
13 | 16 |
|
14 | 17 | WGS84_CRS = CRS.from_epsg(4326)
|
15 | 18 |
|
| 19 | +class SafeDict(dict): |
| 20 | + def __missing__(self, key): |
| 21 | + return '{' + key + '}' |
| 22 | + |
16 | 23 | def url(tile, imagery):
|
17 | 24 | """Return a tile url provided an imagery template and a tile"""
|
18 | 25 | return imagery.replace('{x}', tile[0]).replace('{y}', tile[1]).replace('{z}', tile[2])
|
@@ -40,11 +47,50 @@ def download_tile_tms(tile, imagery, folder, kwargs):
|
40 | 47 |
|
41 | 48 | image_format = get_image_format(imagery, kwargs)
|
42 | 49 |
|
| 50 | + if os.environ.get('ACCESS_TOKEN'): |
| 51 | + token = os.environ.get('ACCESS_TOKEN') |
| 52 | + imagery = imagery.format_map(SafeDict(ACCESS_TOKEN=token)) |
| 53 | + |
43 | 54 | r = requests.get(url(tile.split('-'), imagery),
|
44 | 55 | auth=kwargs.get('http_auth'))
|
45 | 56 | tile_img = op.join(folder, '{}{}'.format(tile, image_format))
|
46 |
| - with open(tile_img, 'wb')as w: |
47 |
| - w.write(r.content) |
| 57 | + tile = tile.split('-') |
| 58 | + |
| 59 | + over_zoom = kwargs.get('over_zoom') |
| 60 | + if over_zoom: |
| 61 | + new_zoom = over_zoom + kwargs.get('zoom') |
| 62 | + # get children |
| 63 | + child_tiles = children(int(tile[0]), int(tile[1]), int(tile[2]), zoom=new_zoom) |
| 64 | + child_tiles.sort() |
| 65 | + |
| 66 | + new_dim = 256 * (2 * over_zoom) |
| 67 | + |
| 68 | + w_lst = [] |
| 69 | + for i in range (2 * over_zoom): |
| 70 | + for j in range(2 * over_zoom): |
| 71 | + window = Window(i * 256, j * 256, 256, 256) |
| 72 | + w_lst.append(window) |
| 73 | + |
| 74 | + # request children |
| 75 | + with rasterio.open(tile_img, 'w', driver='jpeg', height=new_dim, |
| 76 | + width=new_dim, count=3, dtype=rasterio.uint8) as w: |
| 77 | + for num, t in enumerate(child_tiles): |
| 78 | + t = [str(t[0]), str(t[1]), str(t[2])] |
| 79 | + r = requests.get(url(t, imagery), |
| 80 | + auth=kwargs.get('http_auth')) |
| 81 | + img = np.array(Image.open(io.BytesIO(r.content)), dtype=np.uint8) |
| 82 | + try: |
| 83 | + img = img.reshape((256, 256, 3)) # 4 channels returned from some endpoints, but not all |
| 84 | + except ValueError: |
| 85 | + img = img.reshape((256, 256, 4)) |
| 86 | + img = img[:, :, :3] |
| 87 | + img = np.rollaxis(img, 2, 0) |
| 88 | + w.write(img, window=w_lst[num]) |
| 89 | + else: |
| 90 | + r = requests.get(url(tile, imagery), |
| 91 | + auth=kwargs.get('http_auth')) |
| 92 | + with open(tile_img, 'wb')as w: |
| 93 | + w.write(r.content) |
48 | 94 | return tile_img
|
49 | 95 |
|
50 | 96 | def get_tile_tif(tile, imagery, folder, kwargs):
|
|
0 commit comments