Guest User

Untitled

a guest
Apr 3rd, 2021
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.81 KB | None | 0 0
  1. #!/usr/bin/env python
  2. """
  3. Stitch together Google Maps images from lat, long coordinates
  4. Based on work by heltonbiker and BenElgar
  5. Changes:
  6. * updated for Python 3
  7. * added Google Maps API key (compliance with T&C, although can set to None)
  8. * handle http request exceptions
  9.  
  10. With contributions from Eric Toombs.
  11. Changes:
  12. * Dramatically simplified the maths.
  13. * Set a more reasonable default logo cutoff.
  14. * Added global constants for logo cutoff and max image size.
  15. * Translated a couple presumably Portuguese variable names to English.
  16. """
  17.  
  18. import requests
  19. from io import BytesIO
  20. from math import log, exp, tan, atan, ceil
  21. from PIL import Image
  22. import sys
  23.  
  24. # circumference/radius
  25. tau = 6.283185307179586
  26. # One degree in radians, i.e. in the units the machine uses to store angle,
  27. # which is always radians. For converting to and from degrees. See code for
  28. # usage demonstration.
  29. DEGREE = tau/360
  30.  
  31. ZOOM_OFFSET = 8
  32. GOOGLE_MAPS_API_KEY = None # set to 'your_API_key'
  33.  
  34. # Max width or height of a single image grabbed from Google.
  35. MAXSIZE = 640
  36. # For cutting off the logos at the bottom of each of the grabbed images. The
  37. # logo height in pixels is assumed to be less than this amount.
  38. LOGO_CUTOFF = 32
  39.  
  40.  
  41. def latlon2pixels(lat, lon, zoom):
  42. mx = lon
  43. my = log(tan((lat + tau/4)/2))
  44. res = 2**(zoom + ZOOM_OFFSET) / tau
  45. px = mx*res
  46. py = my*res
  47. return px, py
  48.  
  49. def pixels2latlon(px, py, zoom):
  50. res = 2**(zoom + ZOOM_OFFSET) / tau
  51. mx = px/res
  52. my = py/res
  53. lon = mx
  54. lat = 2*atan(exp(my)) - tau/4
  55. return lat, lon
  56.  
  57.  
  58. def get_maps_image(NW_lat_long, SE_lat_long, zoom=18):
  59.  
  60. ullat, ullon = NW_lat_long
  61. lrlat, lrlon = SE_lat_long
  62.  
  63. # convert all these coordinates to pixels
  64. ulx, uly = latlon2pixels(ullat, ullon, zoom)
  65. lrx, lry = latlon2pixels(lrlat, lrlon, zoom)
  66.  
  67. # calculate total pixel dimensions of final image
  68. dx, dy = lrx - ulx, uly - lry
  69.  
  70. # calculate rows and columns
  71. cols, rows = ceil(dx/MAXSIZE), ceil(dy/MAXSIZE)
  72.  
  73. # calculate pixel dimensions of each small image
  74. width = ceil(dx/cols)
  75. height = ceil(dy/rows)
  76. heightplus = height + LOGO_CUTOFF
  77.  
  78. # assemble the image from stitched
  79. final = Image.new('RGB', (int(dx), int(dy)))
  80. for x in range(cols):
  81. for y in range(rows):
  82. dxn = width * (0.5 + x)
  83. dyn = height * (0.5 + y)
  84. latn, lonn = pixels2latlon(
  85. ulx + dxn, uly - dyn - LOGO_CUTOFF/2, zoom)
  86. position = ','.join((str(latn/DEGREE), str(lonn/DEGREE)))
  87. print(x, y, position)
  88. urlparams = {
  89. 'center': position,
  90. 'zoom': str(zoom),
  91. 'size': '%dx%d' % (width, heightplus),
  92. 'maptype': 'satellite',
  93. 'sensor': 'false',
  94. 'scale': 1
  95. }
  96. if GOOGLE_MAPS_API_KEY is not None:
  97. urlparams['key'] = GOOGLE_MAPS_API_KEY
  98.  
  99. url = 'http://maps.google.com/maps/api/staticmap'
  100. try:
  101. response = requests.get(url, params=urlparams)
  102. response.raise_for_status()
  103. except requests.exceptions.RequestException as e:
  104. print(e)
  105. sys.exit(1)
  106.  
  107. im = Image.open(BytesIO(response.content))
  108. final.paste(im, (int(x*width), int(y*height)))
  109.  
  110. return final
  111.  
  112. ############################################
  113.  
  114. if __name__ == '__main__':
  115. # a neighbourhood in Lajeado, Brazil:
  116. NW_lat_long = (-29.44*DEGREE, -52.0*DEGREE)
  117. SE_lat_long = (-29.45*DEGREE, -51.98*DEGREE)
  118.  
  119. zoom = 18 # be careful not to get too many images!
  120.  
  121. result = get_maps_image(NW_lat_long, SE_lat_long, zoom=18)
  122. result.show()
Advertisement
Add Comment
Please, Sign In to add comment