aboutsummaryrefslogtreecommitdiff
blob: 1a745d44d2467f4017ea9adc6ac6aa887ce608c3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/python
#  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; version 2 of the License.
#
#  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.
#
#  (c) 2009 Sven Rebhan <odinshorse@googlemail.com>
#

import os
import sys
import math
import time
import string
import urllib

# Convert degree into radians
def deg2Rad(deg):
	return (deg * math.pi / 180.0)

# That's easy as the longtitude is devided into 2^zoom stripes
def getTileX(lat, lon, zoom):
	return int((lon + 180.0)/360.0 * 2**zoom)

# Here we need to project the latitute onto the map to get the correct y
def getTileY(lat, lon, zoom):
	radlat = deg2Rad(lat)
	return int((1.0 - math.log(math.tan(radlat) + 1.0 / math.cos(radlat)) / math.pi) / 2.0 * 2**zoom)

def getTileUrlSuffix(x, y, zoom):
	return "%d/%d/%d.png" % (zoom, x, y)

def downloadTile(basepath, baseurl, tilesuffix):
	# Download the tile if it doesn't exist already
	if not os.path.exists(os.path.join(basepath,tilesuffix)):
		tilefile = urllib.urlopen(baseurl+"/"+tilesuffix)
		destfile = open(os.path.join(basepath,tilesuffix), 'w')
		destfile.write(tilefile.read())
		tilefile.close()
		destfile.close()
	

###############################################################################
# MAIN
###############################################################################
if __name__ == '__main__':
	if(len(sys.argv) < 5):
		print "Usage: osmget <startpos lat,lon> <stoppos lat,lon> <zoom start[:stop]> <destpath> [sleep in ms]"
		exit(1)

	# Parse the command line options
	startpos  = string.split(sys.argv[1], ',')
	stoppos   = string.split(sys.argv[2], ',')
	zoomrange = string.split(sys.argv[3], ':')
	destpath  = sys.argv[4]
	sleeptime = 0.0
	if len(sys.argv) > 5:
		sleeptime = float(sys.argv[5]) / 1000.0
	
	print "Downloading tiles to %s (sleeping %5.3fms in between)"%(destpath, sleeptime)
	
	# Split the given value ranges into start and stop value
	startzoom = int(zoomrange[0])
	if len(zoomrange) > 1:
		stopzoom = int(zoomrange[1])
	else:
		stopzoom = startzoom
	
	startpos_lat = float(startpos[0])
	startpos_lon = float(startpos[1])
	stoppos_lat  = float(stoppos[0])
	stoppos_lon  = float(stoppos[1])

	# Count the number of tiles
	startx = getTileX(startpos_lat, startpos_lon, startzoom)
	starty = getTileY(startpos_lat, startpos_lon, startzoom)
	stopx  = getTileX(stoppos_lat, stoppos_lon, startzoom)
	stopy  = getTileY(stoppos_lat, stoppos_lon, startzoom)
	total  = 0
	for zoom in range(0, stopzoom-startzoom+1):
		total += 4**zoom
	
	total *= (stopx - startx + 1)
	total *= (stopy - starty + 1)

	# Loop over the tiles. The slowest loop should be the on the zoom
	# level, the middle is on the x, the fastest on y.
	count = 0
	for zoom in range(startzoom, stopzoom+1):
		# Calculate the bounding box of the given coords
		startx = getTileX(startpos_lat, startpos_lon, zoom)
		starty = getTileY(startpos_lat, startpos_lon, zoom)
		stopx  = getTileX(stoppos_lat, stoppos_lon, zoom)
		stopy  = getTileY(stoppos_lat, stoppos_lon, zoom)

		for x in range(startx, stopx+1):
			# Create the destination dir if it doesn't exist
			basepath = os.path.join(destpath, str(zoom), str(x))
			if not os.path.exists(basepath):
				os.makedirs(basepath)
			
			for y in range(starty, stopy+1):
				percent = float(count) / float(total) * 100.0
				count = count + 1
				print "Downloading tile %5d / %d zoom level %d (%3.1f%%)\r" %(count, total, zoom, percent),
				sys.stdout.flush()
				urlsuffix = getTileUrlSuffix(x, y, zoom)
				downloadTile(destpath,
					     "http://tile.openstreetmap.org",
					     urlsuffix)
				if sleeptime > 0.0:
					time.sleep(sleeptime)