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)
|