×

Discussion Board

Page 1 of 2 12 LastLast
Results 1 to 15 of 24
  1. #1
    Super Contributor
    Join Date
    Mar 2003
    Posts
    580

    Retrieveing map tiles in python

    Does it exist any python code snippet which shows how to download map tiles from googlemaps, virtualearth, yahoo or any other map provider?
    I can only find perl scripts, but I don't understand perl!

  2. #2
    Registered User
    Join Date
    Jan 2007
    Posts
    13

    Re: Retrieveing map tiles in python

    Hi cassioli,

    Try this example mobymaps.py (from book Mobile Python: Rapid Prototyping of Applications on the Mobile Platform)

    http://www.mobilenin.com/mobilepytho...87-mopymaps.py

    enjoy

    eMO

  3. #3
    Super Contributor
    Join Date
    Mar 2003
    Posts
    580

    Re: Retrieveing map tiles in python

    thank you very much, that's just what I was looking for!

  4. #4
    Registered User
    Join Date
    Nov 2006
    Posts
    568

    Re: Retrieveing map tiles in python

    Try this. It's not the most sophisticated way, but it works with Google Maps.

    Code:
    from math import pi, sin, cos, log, exp, atan, floor
    
    # Constants used for degree to radian conversion, and vice-versa.
    DTOR = pi / 180.
    RTOD = 180. / pi
    TILE_SIZE = 256
    
    class GoogleZoom(object):
    	def __init__(self, num_zoom=18, tilesize=TILE_SIZE):
    		# Google's tilesize is 256x256, square tiles are assumed.
    		self.tilesize = tilesize
    		
    		# Initializing arrays to hold the parameters for each
    		#  one of the zoom levels.
    		self.degpp = [] # Degrees per pixel
    		self.radpp = [] # Radians per pixel
    		self.npix  = [] # 1/2 the number of pixels for a tile at the given zoom level
    		
    		# Incrementing through the zoom levels and populating the
    		#  parameter arrays.
    		z = tilesize # The number of pixels per zoom level.
    		for i in xrange(num_zoom):
    			# Getting the degrees and radians per pixel, and the 1/2 the number of
    			#  for every zoom level.
    			self.degpp.append(z / 360.) # degrees per pixel
    			self.radpp.append(z / (2 * pi)) # radians per pixl
    			self.npix.append(z / 2) # number of pixels to center of tile
    
    			# Multiplying `z` by 2 for the next iteration.
    			z *= 2
    
    		
    	def lonlat_to_pixel(self, lat, lon, zoom):
    		# Calculating the pixel x coordinate by multiplying the longitude
    		#  value with with the number of degrees/pixel at the given
    		#  zoom level.
    		px_x = round(self.npix[zoom] + (lon * self.degpp[zoom]))
    
    		# Creating the factor, and ensuring that 1 or -1 is not passed in as the 
    		#  base to the logarithm.  Here's why:
    		#   if fac = -1, we'll get log(0) which is undefined; 
    		#   if fac =  1, our logarithm base will be divided by 0, also undefined.
    		fac = min(max(sin(DTOR * lat), -0.9999), 0.9999)
    
    		# Calculating the pixel y coordinate.
    		px_y = round(self.npix[zoom] + (0.5 * log((1 + fac)/(1 - fac)) * (-1.0 * self.radpp[zoom])))
    		
    		# Returning the pixel x, y to the caller of the function.
    		return (px_x, px_y)
    	
    	def get_tile_url(self, px_x, px_y, zoom):
    		# Determine Google tile URL  
    		tile_x = floor(px_x / TILE_SIZE)
    		tile_y = floor(px_y / TILE_SIZE)
    		
    		return "http://mt.google.com/mt?x=%d&y=%d&zoom=%d" % (tile_x, tile_y, 17-zoom)
    Instantiate a GoogleZoom object, get x,y with lon_lat_to_pixel and get the URL with get_tile_url.

    NOTE: You are violating the Google T&C

    Regards

  5. #5
    Super Contributor
    Join Date
    Mar 2003
    Posts
    580

    Re: Retrieveing map tiles in python

    Quote Originally Posted by neil.young View Post
    Try this. [...]

    NOTE: You are violating the Google T&C

    Regards
    Thanks for good and very commented code!
    But how can avoid violating Google licence terms? Is their program for PDAs the only one officially authorized to use their maps?!? Are MGMaps and 8motions/j2memap violating T&C too?!?

  6. #6
    Registered User
    Join Date
    Nov 2006
    Posts
    568

    Re: Retrieveing map tiles in python

    You should follow the discussions in the MGMaps-Forum concerning this. MGMaps has been "asked" kindly by Google to not continue using their API the way they did before. MGMaps has dropped support for Google Maps and continues with Microsoft and Yahoo only.

    Indeed, the T&C just talk about and allow the usage from a web based entity.

    Have a look and decide by yourself. I doubt that Google will strike against everybody everywhere. I just wanted to note, that there is a potential pitfall.

    Regards

  7. #7
    Regular Contributor
    Join Date
    Mar 2007
    Posts
    153

    Re: Retrieveing map tiles in python

    Hi,
    is it possible to display an exact geo position on the downloaded map to show e.g. my position?

  8. #8
    Registered User
    Join Date
    Nov 2006
    Posts
    568

    Re: Retrieveing map tiles in python

    If you are using the code above you'll always get just 1 tile for a geo code. You'll find your point there, but it's generally not centered. From the latSo you have

    a) to do some math in order to find out, what tiles around you have to draw aditionally in order to build up a bitmap (of variable size) and cut an area out so that your coordinate is centered. The floor part of x,y is always the x,y coordinate to be queried at google. The ceil part multiplied with 256 is always the position of your geocode within the tile

    b) To draw some flag or circle is up to you. You have a bitmap, draw on it.

    Regards

  9. #9
    Regular Contributor
    Join Date
    Mar 2007
    Posts
    153

    Re: Retrieveing map tiles in python

    Is it possible to give a geo coordinate to the map server instead of an adress?

    Thx

  10. #10
    Registered User
    Join Date
    Nov 2006
    Posts
    568

    Re: Retrieveing map tiles in python

    It seems to be possible. You should just open up your browser, move to Google Maps, and move to a location. Have Wireshark running in the background and see what happens.

    I haven't investigated in this API, but found some other probably usefull hints. Written down at

    http://freenet-homepage.de/neilyoung/index.html

    HTH

  11. #11
    Regular Contributor
    Join Date
    Mar 2007
    Posts
    153

    Re: Retrieveing map tiles in python

    Thx neil.young,
    I tried and it works with geo coordinates.

    example:
    http://maps.google.com/maps?f=q&hl=d...432,+10.533072

  12. #12
    Registered User
    Join Date
    Nov 2006
    Posts
    568

    Re: Retrieveing map tiles in python

    No, I doubt that. You will have difficulities if using this URL outside your browser, e.g. in a python script. I bet you can't deal with the stuff returned by google, because you know nothing about the inner structure. This is up to the diverse GM JavaScript files, making the map visible to you in a browser.

    The hardcore way is to get the tiles by x,y and build the map by yourself.

    Regards

  13. #13
    Registered User
    Join Date
    Feb 2008
    Posts
    6

    Re: Retrieveing map tiles in python

    Quote Originally Posted by neil.young View Post
    If you are using the code above you'll always get just 1 tile for a geo code. You'll find your point there, but it's generally not centered. From the latSo you have

    a) to do some math in order to find out, what tiles around you have to draw aditionally in order to build up a bitmap (of variable size) and cut an area out so that your coordinate is centered. The floor part of x,y is always the x,y coordinate to be queried at google. The ceil part multiplied with 256 is always the position of your geocode within the tile

    b) To draw some flag or circle is up to you. You have a bitmap, draw on it.

    Regards
    Hi Neil,

    can you please demonstrate how to get x,y pixel coordinates inside a tile given latitude and longitude and zoom level?
    eg. latitude = -36.856257 longitude = 174.765058 and zoom = 0

    Cheers!

    James

  14. #14
    Registered User
    Join Date
    Nov 2006
    Posts
    568

    Re: Retrieveing map tiles in python

    Hi James,

    as I said above:

    Code:
    Instantiate a GoogleZoom object, get x,y with lon_lat_to_pixel and get the URL with get_tile_url.
    BTW: Zoom level 0 is rather simple: There is just one tile available for that level, hence the tile coords are x=0, y=0. I think, you mean the largest zoom level 17, so the 3 liner is as follows:

    gz = GoogleZoom()
    (x, y) = gz.lonlat_to_pixel(-36.856257, 174.765058, 17)
    print gz.get_tile_url(x, y, 17)

    After that open your browser with the URL printed. And please let me know, if the result doesn't match your expectations.

    EDIT: I'm currently reviewing your post and just seeing your real question (sorry, it's early in the morning here over...) I'm in a rush, but return to you ASAP.


    Regards

  15. #15
    Registered User
    Join Date
    Nov 2006
    Posts
    568

    Re: Retrieveing map tiles in python

    So James,

    your post gave me the opportunity to make some reworks and complete my series of articles at http://maps.alphadex.de (topic "Get a map") with a Python sample. As already stated above, the algorithm wasn't mine and wasn't sophisticated enough , because it does not explain anything. But the results compared with my algorithm are of course the same. Please visit my site in order to get a detailed explanation of all this.

    So I rewrote a C# sample in Python, which now answers your initial question. And to be more specific: The sample coordinate you provided is somewhere in a triangle formed by Airedale St. and Symonds St.

    Here is a "more sophisticated" approach, because it makes the Mercator roots more transparent:

    Code:
    from math import pi, sin, log
    
    # Python sample. How to ask Google for map tiles?
    
    # This script is published under GPL (included below)
    #
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 3 of the License, or
    # (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program.  If not, see <http://www.gnu.org/licenses/>.
    #
    
    
    
    # Constants used for degree to radian conversion, and vice-versa.
    DTOR = pi / 180.
    RTOD = 180. / pi
    TILE_SIZE = 256
    
    class GoogleZoom(object):
    	def locationCoord(self, lat, lon, zoom):
    		# Per se earth coordinates are -90° <= lat <= +90° and -180° <= lon <= 180° 
    		# Mercator is NOT applicable for abs(lat) > 85.0511287798066 degrees 
    		if (abs(lat) > 85.0511287798066):
    			raise "Invalid latitude"
    		# latitude (deg) -> latitude (rad) 
    		sin_phi = sin(float(lat) * DTOR)
    		# Use Mercator to calculate x and normalize this to -1 <= x <= +1 by division by 180.
    		# The center of the map is lambda_0 = 0, hence x = lat. 
    		norm_x = lon / 180.
    		# Use Mercator to calculate y and normalize this to -1 <= y <= +1 by division by PI. 
    		# According to Mercator y is defined in the range of -PI <= y <= PI only 
    		norm_y = (0.5 * log((1 + sin_phi) / (1 - sin_phi))) / pi
    		# Apply the normalized point coordinations to any application (here the coordinates of 
    		# a 256*256 image holding that point in a thought grid with origin 0,0 top/left)
    		col = pow(2, zoom) * ((norm_x + 1) / 2);
    		row = pow(2, zoom) * ((1 - norm_y) / 2);
    		return (col, row, zoom);
    Here is how to use it:

    # Main
    gz = GoogleZoom()
    col, row, zoom = gz.locationCoord(-36.856257, 174.765058, 17)
    print "Google Tile URL: http://mt.google.com/mt?x=%d&y=%d&zoom=%d" % (col, row, 17-zoom)
    print "X coordinate within the tile =", (col - long(col)) * TILE_SIZE
    print "Y coordinate within the tile =", (row - long(row)) * 256


    Enjoy and let me know

Similar Threads

  1. Please help installing Python libraries on S60
    By ericroijen in forum Symbian
    Replies: 11
    Last Post: 2009-07-18, 10:43
  2. [announce] PyUIQ. Python for UIQ 2.1 and 3.x
    By OscarBernabeu in forum Symbian
    Replies: 35
    Last Post: 2008-01-17, 09:12
  3. Replies: 1
    Last Post: 2008-01-08, 09:58
  4. Replies: 11
    Last Post: 2007-10-03, 19:46
  5. Replies: 3
    Last Post: 2007-03-13, 06:50

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •