Skip to content

Instantly share code, notes, and snippets.

@eskriett
Last active June 22, 2026 16:45
Show Gist options
  • Select an option

  • Save eskriett/6038468 to your computer and use it in GitHub Desktop.

Select an option

Save eskriett/6038468 to your computer and use it in GitHub Desktop.
A python script to download high resolution Google map images given a longitude, latitude and zoom level.
#!/usr/bin/python
# GoogleMapDownloader.py
# Created by Hayden Eskriett [http://eskriett.com]
#
# A script which when given a longitude, latitude and zoom level downloads a
# high resolution google map
# Find the associated blog post at: http://blog.eskriett.com/2013/07/19/downloading-google-maps/
import urllib
import Image
import os
import math
class GoogleMapDownloader:
"""
A class which generates high resolution google maps images given
a longitude, latitude and zoom level
"""
def __init__(self, lat, lng, zoom=12):
"""
GoogleMapDownloader Constructor
Args:
lat: The latitude of the location required
lng: The longitude of the location required
zoom: The zoom level of the location required, ranges from 0 - 23
defaults to 12
"""
self._lat = lat
self._lng = lng
self._zoom = zoom
def getXY(self):
"""
Generates an X,Y tile coordinate based on the latitude, longitude
and zoom level
Returns: An X,Y tile coordinate
"""
tile_size = 256
# Use a left shift to get the power of 2
# i.e. a zoom level of 2 will have 2^2 = 4 tiles
numTiles = 1 << self._zoom
# Find the x_point given the longitude
point_x = (tile_size/ 2 + self._lng * tile_size / 360.0) * numTiles // tile_size
# Convert the latitude to radians and take the sine
sin_y = math.sin(self._lat * (math.pi / 180.0))
# Calulate the y coorindate
point_y = ((tile_size / 2) + 0.5 * math.log((1+sin_y)/(1-sin_y)) * -(tile_size / (2 * math.pi))) * numTiles // tile_size
return int(point_x), int(point_y)
def generateImage(self, **kwargs):
"""
Generates an image by stitching a number of google map tiles together.
Args:
start_x: The top-left x-tile coordinate
start_y: The top-left y-tile coordinate
tile_width: The number of tiles wide the image should be -
defaults to 5
tile_height: The number of tiles high the image should be -
defaults to 5
Returns:
A high-resolution Goole Map image.
"""
start_x = kwargs.get('start_x', None)
start_y = kwargs.get('start_y', None)
tile_width = kwargs.get('tile_width', 5)
tile_height = kwargs.get('tile_height', 5)
# Check that we have x and y tile coordinates
if start_x == None or start_y == None :
start_x, start_y = self.getXY()
# Determine the size of the image
width, height = 256 * tile_width, 256 * tile_height
#Create a new image of the size require
map_img = Image.new('RGB', (width,height))
for x in range(0, tile_width):
for y in range(0, tile_height) :
url = 'https://mt0.google.com/vt?x='+str(start_x+x)+'&y='+str(start_y+y)+'&z='+str(self._zoom)
current_tile = str(x)+'-'+str(y)
urllib.urlretrieve(url, current_tile)
im = Image.open(current_tile)
map_img.paste(im, (x*256, y*256))
os.remove(current_tile)
return map_img
def main():
# Create a new instance of GoogleMap Downloader
gmd = GoogleMapDownloader(51.5171, 0.1062, 13)
print("The tile coorindates are {}".format(gmd.getXY()))
try:
# Get the high resolution image
img = gmd.generateImage()
except IOError:
print("Could not generate the image - try adjusting the zoom level and checking your coordinates")
else:
#Save the image to disk
img.save("high_resolution_image.png")
print("The map has successfully been created")
if __name__ == '__main__': main()
@Abdul-Basit31

Copy link
Copy Markdown

This code is run successfully with not any error, but image does'nt download?
when put the latitude x and longitude y.?

@GoroYeh56

Copy link
Copy Markdown

@Anjali1808 I had the same error. Hope someone can help me on this. Thanks!

@GoroYeh56

Copy link
Copy Markdown

@kregmi I have the same issue. Did you resolve it? Thanks!

@MaxVero

MaxVero commented Jan 8, 2024

Copy link
Copy Markdown

Hi ! I want just to ask in your opinion, if you dowload hundreds of images is there a problem with google license? I mean if i use in a research work and I'm the only one that have got that images. Thanks a lot.

@rose-jinyang

rose-jinyang commented Apr 10, 2024

Copy link
Copy Markdown

Hello everyone
The current script gets 256x256 pixel size of tile whenever calls API.
How can I get 512x512 pixel size of tile?

@nguyenbavinh89

Copy link
Copy Markdown

This is still a really useful example for understanding how Google Maps tile coordinates work under the hood.

What I like most about this script is that it doesn't just download an image — it demonstrates the entire process of converting latitude/longitude into tile coordinates and then stitching multiple map tiles into a larger high-resolution image. For anyone learning GIS, web mapping, or map tile systems, that's valuable knowledge.

That said, Google Maps has changed quite a bit since this script was originally published, so some users may run into issues with tile access, rate limits, or URL changes. The core tile math is still educational, but maintaining download scripts over time can become challenging.

For people who simply need to save publicly visible Google Maps imagery today without modifying Python code or dealing with tile stitching, I've found that tools such as Download Map Image can be a practical alternative. It handles the downloading process directly in the browser, which is convenient for non-developers.

Either way, this gist remains a great reference for understanding how map tiles are organized and assembled into larger images.
1-ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment