-
-
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() |
@eskriett Hi there, I found your adaptation awesome ! it worked for me. I have a question: do you know any way you could turn off labels with this method of getting an image of google map from a url query? do you know any documentation about flags of url query of google maps?
Thank you!! Also @sebastianleonte!
Awesome, it worked right away. Thanks, @eskriett !
Hi, the code is awesome.!! But it's not centering the image. Any help is appreciated to make changes in centering the location to the center of the image generated
I want to execute the script but i don't get a result expected. Install the module image from PyPI
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
Requirement already satisfied: image in /usr/local/lib/python2.7/dist-packages (1.5.33)
Requirement already satisfied: pillow in /usr/local/lib/python2.7/dist-packages (from image) (6.2.2)
Requirement already satisfied: django in /usr/local/lib/python2.7/dist-packages (from image) (1.11.29)
Requirement already satisfied: six in /usr/local/lib/python2.7/dist-packages (from image) (1.12.0)
Requirement already satisfied: pytz in /usr/local/lib/python2.7/dist-packages (from django->image) (2019.2)
WARNING: You are using pip version 19.2.3, however version 20.3.4 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Requirement already satisfied: pip in /usr/local/lib/python3.7/site-packages (21.0.1)
Traceback (most recent call last):
File "GoogleMapDownloader.py", line 10, in <module>
import Image
ImportError: No module named Image
Linux 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64 GNU/Linux
Python 2.7.16
Hi @Villelmo, kindly take a look at my fork here: https://gist.github.com/sebastianleonte/617628973f88792cd097941220110233
I adapted it to be working with the libraries PIL and urllib. also to be executed with python3
Ready. I thought that program downloaded each image uploaded for different user at this location.
How i can implement this function in this code?. @sebastianleonte
Hi @Villelmo, so let me understand you, what you want is to download, given a location, photos uploaded by users about this location? Like the same way you can see on Google Maps when you search for a city, coffee shop... or whatever ??
Yes, exactly. But the code is excelent, is very useful.
@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".
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?
@Hamedyp @Louck @u4ece10128 Hi Guys, I am facing the same problem. I can download a few images and then get the error.
How did you guys solve this? Is there a better version of the code that someone can share to download aerial images from Google?
Is it a problem @tjdahlke mentioned that the Google is blocking access after certain number of downloads?
Any help will be highly appreciated. Thanks