Skip to content

Instantly share code, notes, and snippets.

@awhitty
Created December 25, 2015 01:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save awhitty/a9f22f5e08e8af28c816 to your computer and use it in GitHub Desktop.
Save awhitty/a9f22f5e08e8af28c816 to your computer and use it in GitHub Desktop.
# Downloads all the tiles at full resolution from a directory of Zoomify tiles.
# Requires `eventlet` for multithreaded HTTP requests
import eventlet
from eventlet.green import urllib2
from math import floor, ceil, pow
BASE_URL = "http://www.theatlantic.com/media/interactives/2015/11/colorado-satellite-photo/tiles/"
DOWNLOAD_DIR = "tiles/"
IMAGE_WIDTH = 10644.0
IMAGE_HEIGHT = 13305.0
ZOOM_LEVEL = 6
TILE_SIZE = 256.0
def getGridSize(width, height):
return (ceil(width / TILE_SIZE), ceil(height / TILE_SIZE))
def calcTiles():
width = IMAGE_WIDTH
height = IMAGE_HEIGHT
g_sizes = [getGridSize(width, height)]
while width > TILE_SIZE or height > TILE_SIZE:
width = width / 2
height = height / 2
g_sizes.append(getGridSize(width, height))
return g_sizes
GRID_SIZES = list(reversed(calcTiles()))
def getTileGroup(x, y):
# based on https://github.com/turban/Leaflet.Zoomify
zoom = ZOOM_LEVEL
num = 0
for i in range(0, zoom):
grid_size = GRID_SIZES[i]
num += grid_size[0]*grid_size[1]
num += y * GRID_SIZES[zoom][0] + x
return floor(num / 256)
# Quick TileGroup tests
# ---------------------
# print "%s should be %s -> %s" % (getTileGroup(16,33), 8, getTileGroup(16,33) == 8)
# print "%s should be %s -> %s" % (getTileGroup(28,28), 7, getTileGroup(28,28) == 7)
# print "%s should be %s -> %s" % (getTileGroup(0,0), 2, getTileGroup(0,0) == 2)
# print "%s should be %s -> %s" % (getTileGroup(41,40), 9, getTileGroup(41,40) == 9)
# print "%s should be %s -> %s" % (getTileGroup(40,49), 11, getTileGroup(40,49) == 11)
# print "%s should be %s -> %s" % (getTileGroup(39,43), 10, getTileGroup(39,43) == 10)
# print "%s should be %s -> %s" % (getTileGroup(0,31), 8, getTileGroup(0,31) == 8)
# print "%s should be %s -> %s" % (getTileGroup(1,31), 8, getTileGroup(1,31) == 8)
# print "%s should be %s -> %s" % (getTileGroup(2,37), 9, getTileGroup(2,37) == 9)
# print "%s should be %s -> %s" % (getTileGroup(3,31), 8, getTileGroup(3,31) == 8)
# print "%s should be %s -> %s" % (getTileGroup(3,37), 9, getTileGroup(3,37) == 9)
def getTileURL(x,y):
group = getTileGroup(x,y)
return "%sTileGroup%d/%s-%d-%d.jpg" % (BASE_URL, group, 6, x, y)
def getListOfURLs():
urls = []
for x in range(int(GRID_SIZES[6][0])):
for y in range(int(GRID_SIZES[6][1])):
urls.append({
'x': x,
'y': y,
'url': getTileURL(x,y)
})
return urls
def fetchImage(img):
return {
'body': urllib2.urlopen(img['url']).read(),
'img': img
}
urls = getListOfURLs()
pool = eventlet.GreenPool(size=16)
for response in pool.imap(fetchImage, urls):
body = response['body']
img = response['img']
f = open('%s%s-%s.jpg' % (DOWNLOAD_DIR, img['x'], img['y']), 'wb')
f.write(body)
f.close()
# Stitches together tiles grabbed by `tileget.py` to make a big image
# Requires PIL (use Pillow)
from math import floor
from PIL import Image
IMAGE_WIDTH = 10644
IMAGE_HEIGHT = 13305
TILE_SIZE = 256
DOWNLOAD_DIR = "tiles/"
newimg = Image.new('RGB', (IMAGE_WIDTH, IMAGE_HEIGHT))
for x in xrange(0, IMAGE_WIDTH, TILE_SIZE):
for y in xrange(0, IMAGE_HEIGHT, TILE_SIZE):
im = Image.open("%s%d-%d.jpg" % (DOWNLOAD_DIR, floor(x/TILE_SIZE), floor(y/TILE_SIZE)))
newimg.paste(im, (x, y))
newimg.save('stitched.jpg')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment