-
-
Save eskriett/6038468 to your computer and use it in GitHub Desktop.
| #!/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() |
This code is run successfully with not any error, but image does'nt download?
when put the latitude x and longitude y.?
@Anjali1808 I had the same error. Hope someone can help me on this. Thanks!
@kregmi I have the same issue. Did you resolve it? Thanks!
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.
Hello everyone
The current script gets 256x256 pixel size of tile whenever calls API.
How can I get 512x512 pixel size of tile?
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.

@kregmi @Hamedyp @Louck @u4ece10128 Did you find the solution for your queries? I am running into the same trouble. Please help me to get rid of the error message - "Could not generate the image - try adjusting the zoom level and checking your coordinates".