From OpenStreetMap Wiki
Jump to navigation Jump to search


This a script to download tiles in advance when planning to go somewhere and use BSGPSPDA or some other tool that needs tiles to be downloaded. The script really has no sanity checks so be careful on what values you pass to it.

Typical use is probably to download an overview with zoom level 10-12 and then zoom levels 13-17 only for a small area of specific interest.


#!/usr/bin/env python
  Author:     Jonas Svensson
  Program:    Fetch tiles for an area
  Date:       2007-10-17

  Description:  Calculates tilenumbers from an position (lat, lon, zoom)
                and downloads the tiles
                  into the appropriate directory structure
                  For now everything runs from the current directory
                  Also depends on the URLs always being the same format

		Run without arguments to show usage.
import urllib
import os
import math
import sys

baseurl = ""

# ---------------  no more config  ---------------------------

def pos2xy( lat, lon, zoomlevel):
  xtile = (lon+180)/360 * (2 ** zoomlevel)

  ytile = (1.0 - (math.log((math.tan(math.radians(lat))) + 1.0/(math.cos(math.radians(lat))))) / math.pi) / 2.0 * (2 ** zoomlevel)

  return (int(xtile), int(ytile))

def get_tile(zoomlevel, tilecolumn, tilefile):
    if not os.path.isdir(zoomlevel):
       print "Made directory " + zoomlevel
    tiledir = zoomlevel+os.path.sep+tilecolumn
    if not os.path.isdir(tiledir):
       print "Made directory " + tiledir
    fullfilename = tiledir+os.path.sep+tilefile+".png"
    if not os.path.isfile(fullfilename):
        line = baseurl + fullfilename
        urllib.urlretrieve(line, fullfilename)
        print "Downloaded tile " + fullfilename


if (len(sys.argv) == 7):
  minlat  = float(sys.argv[1])
  minlon  = float(sys.argv[2])
  maxlat  = float(sys.argv[3])
  maxlon  = float(sys.argv[4])
  minzoom = int(sys.argv[5])
  maxzoom = int(sys.argv[6])
  print "Usage: "
  print sys.argv[0] + " minlat minlon maxlat maxlon minzoom maxzoom"
  print "Position in degrees and zoomlevels 10-17"

if maxlat < minlat:
  print "max < minlat"
if maxlon < minlon:
  print "max < minlon"
if maxzoom < minzoom:
  print "max < minzoom"

for i in range(minzoom , maxzoom+1):
  xy = pos2xy(minlat,minlon, i)
  tile_minx = xy[0]
  tile_miny = xy[1]
  xy = pos2xy(maxlat,maxlon, i)
  tile_maxx = xy[0]
  tile_maxy = xy[1]

  if tile_maxy < tile_miny:
    tmpvar = tile_maxy
    tile_maxy = tile_miny
    tile_miny = tmpvar
  if tile_maxx < tile_minx:
    tmpvar = tile_maxx
    tile_maxx = tile_minx
    tile_minx = tmpvar

  for xi in range(tile_minx, tile_maxx):
    for yi in range(tile_miny, tile_maxy):
      get_tile(repr(i), repr(xi), repr(yi))