-
-
Save farhadinima75/c3e73f8d7d9f8d2e452063e611fb9a8c to your computer and use it in GitHub Desktop.
| #!/usr/bin/python | |
| # GoogleMapDownloader.py | |
| # Created by Hayden Eskriett [http://eskriett.com] | |
| # Edited by Nima Farhadi | |
| # | |
| # 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/ | |
| from PIL import Image | |
| import math, shutil, requests, os | |
| class GoogleMapsLayers: | |
| ROADMAP = "v" | |
| TERRAIN = "p" | |
| ALTERED_ROADMAP = "r" | |
| SATELLITE = "s" | |
| TERRAIN_ONLY = "t" | |
| HYBRID = "y" | |
| 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, layer=GoogleMapsLayers.ROADMAP): | |
| """ | |
| 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 | |
| self._layer = layer | |
| 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', 8) | |
| tile_height = kwargs.get('tile_height', 8) | |
| # 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(-tile_width//2, tile_width//2): | |
| for y in range(-tile_height//2, tile_height//2): | |
| url = f'https://mt0.google.com/vt?lyrs={self._layer}&x=' + str(start_x + x) + \ | |
| '&y=' + str(start_y + y) + '&z=' + str(self._zoom) | |
| current_tile = str(x) + '-' + str(y) | |
| response = requests.get(url, stream=True) | |
| with open(current_tile, 'wb') as out_file: shutil.copyfileobj(response.raw, out_file) | |
| im = Image.open(current_tile) | |
| map_img.paste(im, ((x+tile_width//2) * 256, (y+tile_height//2) * 256)) | |
| os.remove(current_tile) | |
| print('Image size (pix): ', map_img.size) | |
| return map_img | |
| def main(): | |
| # Create a new instance of GoogleMap Downloader | |
| gmd = GoogleMapDownloader(51.5171, 0.1062, 13, GoogleMapsLayers.SATELLITE) | |
| 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() |
hi @ws0352
If you changed lat/lon value, try zoom level between 16-19. Some places don't have high-level resolution images.
And if the problem still exists, delete try/except to see the exact error.
And also, feel free for asking further questions.
Error I GOT
b'<title>Sorry...</title><style> body { font-family: verdana, arial, sans-serif; background-color: #fff; color: #000; }</style>
Sorry... |
We're sorry...
... but your computer or network may be sending automated queries. To protect our users, we can't process your request right now.
Hi @zeeshan7929
Can you tell me what parameters did you use (I mean, zoom level, tile size,...)?
How do we get to know the following information from the downloaded images :
1.) What is the spatail resolution of the image ?
2.) What date is the image captured ?
3.) Which satellite has been used to capture the image ?
Also, can we go back in time and download the images for the past years ?
Is it possible to return lat/lon coordinates grid for the image? 😄
I got the error msg below:
zoom level: 13
Input filename: 0000000678
(lat, long): 49.018233566207, 8.4454809774168
The tile coorindates are (4288, 2812)
Traceback (most recent call last):
File "/Users/goroyeh56/ROB590/getSatImg.py", line 204, in <module>
if __name__ == '__main__': main()
^^^^^^
File "/Users/goroyeh56/ROB590/getSatImg.py", line 197, in main
img = gmd.generateImage()
^^^^^^^^^^^^^^^^^^^
File "/Users/goroyeh56/ROB590/getSatImg.py", line 104, in generateImage
urllib.request.urlretrieve(url, current_tile)
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/urllib/request.py", line 241, in urlretrieve
with contextlib.closing(urlopen(url, data)) as fp:
^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/urllib/request.py", line 216, in urlopen
return opener.open(url, data, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/urllib/request.py", line 525, in open
response = meth(req, response)
^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/urllib/request.py", line 634, in http_response
response = self.parent.error(
^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/urllib/request.py", line 563, in error
return self._call_chain(*args)
^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/urllib/request.py", line 496, in _call_chain
result = func(*args)
^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/urllib/request.py", line 643, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 403: Forbidde
Anyone knows what is happening?
Could not generate the image - try adjusting the zoom level and checking your coordinates