Created
June 10, 2015 12:10
-
-
Save esemwy/75b9ef7fd042d4947745 to your computer and use it in GitHub Desktop.
Create 360 degree mosaic from Google Maps Street View data.
This file contains 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 python | |
# Based on http://stackoverflow.com/questions/17555345/creating-a-montage-of-pictures-in-python | |
from sys import path | |
# needed for some package installs, harmless otherwise | |
path.append('/usr/local/lib/python2.7/site-packages') | |
import argparse | |
import os | |
import sys | |
from time import strftime | |
import requests | |
from io import BytesIO | |
PIL_INSTALLED = True | |
try: | |
from PIL import Image | |
from PIL import ImageDraw | |
except: | |
PIL_INSTALLED = False | |
from subprocess import call | |
import re | |
# parameters | |
row_size = 13 | |
extension = '.png' | |
url = 'http://cbk0.google.com/cbk' | |
def generate_montage(files): | |
images = [ Image.open(file) for file in files ] | |
width = 0 | |
height = 0 | |
i = 0 | |
sum_x = max_y = 0 | |
width = max(image.size[1] for image in images)*row_size | |
height = max(image.size[0] for image in images)*len(images)/row_size | |
montage = Image.new(mode='RGBA', size=(width, height), color=(0,0,0,0)) | |
draw = ImageDraw.Draw(montage) | |
offset_x = offset_y = 0 | |
i = 0 | |
max_y = 0 | |
max_x = 0 | |
offset_x = 0 | |
for image in images: | |
montage.paste(image, (offset_x, offset_y)) | |
max_x = max(max_x, offset_x+image.size[0]) | |
if i % row_size == row_size-1: | |
offset_y += max_y | |
max_y = 0 | |
offset_x = 0 | |
else: | |
offset_x += image.size[0] | |
max_y = max(max_y, image.size[1]) | |
i += 1 | |
if i % row_size: | |
offset_y += max_y | |
filename = strftime("Montage %Y-%m-%d at %H.%M.%S"+extension) | |
# montage = montage.crop((0, 0, max_x, offset_y)) | |
montage.save(filename) | |
def generate_montage_magick(files): | |
filenames = [] | |
for i, file in enumerate(files): | |
name = '/tmp/cbk_{:02d}.jpg'.format(i) | |
open(name,'w').write(file.read()) | |
filenames.append(name) | |
filename = strftime("Montage %Y-%m-%d at %H.%M.%S"+extension) | |
params = ['montage', '-geometry', '+0+0', '-tile', '13x7']+filenames+[filename] | |
print ' '.join(params) | |
call(params) | |
def extractPanoid( mapsLink ): | |
fields = mapsLink.split( "!" ) | |
for f in fields: | |
if f.startswith('1s'): | |
return f[2:102] | |
return None | |
def downloadAll(mapsLink): | |
panoid = extractPanoid( mapsLink ) | |
files = [] | |
for y in xrange(0,7): | |
for x in xrange(0,13): | |
payload = { | |
'output' : 'tile', | |
'panoid' : panoid, | |
'zoom' : 4, | |
'x' : x, | |
'y' : y | |
} | |
r = requests.get(url, params=payload) | |
files.append(BytesIO(r.content)) | |
try: | |
if len(files) > 1: | |
if PIL_INSTALLED: | |
generate_montage(files) | |
else: | |
generate_montage_magick(files) | |
except Exception as e: | |
print e | |
def readFile(html): | |
pat = re.compile(r'src="([^"]+)"') | |
with open(html,'r') as fd: | |
text = fd.read() | |
files = [open(os.path.join(os.path.dirname(html),m),'r') for m in re.findall(pat,text)] | |
try: | |
if len(files) > 1: | |
if PIL_INSTALLED: | |
generate_montage(files) | |
else: | |
generate_montage_magick(files) | |
except Exception as e: | |
print e | |
def main(): | |
parser = argparse.ArgumentParser(description='Create Google Maps Mosaic.') | |
parser.add_argument('input', metavar='file-or-url', type=str, | |
help='File or URL') | |
parser.add_argument('--url', action='store_true', help='Use URL to download tiles') | |
args = parser.parse_args() | |
if args.url: | |
downloadAll(args.input) | |
else: | |
readFile(args.input) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment