[Tilecache] tilecache seed missing some tiles
Josh Livni
josh at umbrellaconsulting.com
Thu Jul 17 03:53:24 EDT 2008
I noticed yesterday that tilecache_seed does not render all tiles within
a specified bbox. After a look at the seed function, I saw a few reasons:
It uses range(A,B,M) to define the x and y loop for each zoom level
(where A is the left or bottom tile, B is the top or right tile, and M
is associated the metatile size). However, the output of range will
never go all the way to B, and in addition, may step short of it by an
extra amount if using metaSize > 1.
To solve this problem, my patch adds +metasize to the range (A, B +
metasize, M)
Next I realized that even so, sometimes edge tiles that span the border
of your bbox may not get rendered, due to the way getClosestCell is used
to decide which tiles A and B should be. However, it's possible, if
your bbox aligns exactly with a tile edge, all tiles get rendered. A
simple solution struck me as adding an optional 'padding' parameter,
which is the extra (1*padding) you see in the patch. Padding of zero
means it works as before; you may miss edge tiles. Values of 1 mean you
may get some tiles wholly outside your bbox, and higher values ensure
you will (the padding is in tiles, not units of your projection). The
default is 0.
Finally, it seems the 'base' parameter is not being used, I assume
because seed no longers goes out to a remote url, but uses the local
tilecache directly. Therefore my patch removes this now-useless (I
think?) parameter entirely, which will unfortunately have the
side-effect of breaking any shell scripts people have used to automate
seeding using tilecache_seed.py.
I hope this all seems reasonable .. please let me know if I seem to be
missing something.
-Josh
-------------- next part --------------
Index: TileCache/Client.py
===================================================================
--- TileCache/Client.py (revision 353)
+++ TileCache/Client.py (working copy)
@@ -69,8 +69,12 @@
def setBBox (self, box):
self.params["bbox"] = ",".join(map(str, box))
-def seed (svc, base, layer, levels = (0, 5), bbox = None):
+def seed (svc, layer, levels = (0, 5), bbox = None, padding = 0):
from Layer import Tile
+ try:
+ padding = int(padding)
+ except:
+ raise Exception('Your padding parameter is %s, but should be an integer' % padding)
if not bbox: bbox = layer.bbox
@@ -84,8 +88,8 @@
zcount = 0
metaSize = layer.getMetaSize(z)
ztiles = int(math.ceil(float(topright[1] - bottomleft[1]) / metaSize[0]) * math.ceil(float(topright[0] - bottomleft[0]) / metaSize[1]))
- for y in range(bottomleft[1], topright[1], metaSize[1]):
- for x in range(bottomleft[0], topright[0], metaSize[0]):
+ for y in range(bottomleft[1] - (1 * padding), topright[1] + metaSize[1] + (1 * padding), metaSize[1]):
+ for x in range(bottomleft[0] - (1 * padding), topright[0] + metaSize[0] + (1 * padding), metaSize[0]):
tileStart = time.time()
tile = Tile(layer,x,y,z)
bounds = tile.bounds()
@@ -99,19 +103,20 @@
def main ():
from Service import Service, cfgfiles
from Layer import Layer
- base = sys.argv[1]
svc = Service.load(*cfgfiles)
- layer = svc.layers[sys.argv[2]]
- if len(sys.argv) == 5:
- seed(svc, base, layer, map(int, sys.argv[3:]))
+ layer = svc.layers[sys.argv[1]]
+ if len(sys.argv) == 4:
+ seed(svc, layer, map(int, sys.argv[2:]))
+ elif len(sys.argv) == 5:
+ seed(svc, layer, map(int, sys.argv[2:4]), map(float, sys.argv[4].split(",")))
elif len(sys.argv) == 6:
- seed(svc, base, layer, map(int, sys.argv[3:5]), map(float, sys.argv[5].split(",")))
+ seed(svc, layer, map(int, sys.argv[2:4]), map(float, sys.argv[4].split(",")), sys.argv[5])
else:
for line in sys.stdin.readlines():
lat, lon, delta = map(float, line.split(","))
bbox = (lon - delta, lat - delta, lon + delta, lat + delta)
print "===> %s <===" % (bbox,)
- seed(svc, base, layer, (5, 17), bbox)
+ seed(svc, layer, (5, 17), bbox)
if __name__ == '__main__':
main()
Index: docs/README.txt
===================================================================
--- docs/README.txt (revision 353)
+++ docs/README.txt (working copy)
@@ -358,14 +358,11 @@
Usage
-----
- tilecache_seed.py <url> <layer> [<zoom start> <zoom stop> [<bbox>]]
+ tilecache_seed.py <layer> [<zoom start> <zoom stop> [<bbox>] [padding]]
Arguments
---------
- url
- http://example.com/yourdir/tilecache.cgi? or
- http://example.com/yourdir/tilecache.py
layer
same layer name that is in the tilecache.cfg
zoom start
@@ -374,6 +371,9 @@
Zoom level to end the process
bbox
The bounding box to seed
+ padding
+ Defaults to 0 (some edge tiles might be missing); a value of 1 ensures
+ all tiles will be created, but some tiles may be wholly outside your bbox
Seeding by center point and radius
----------------------------------
@@ -402,17 +402,17 @@
Examples
--------
-An example with zoom levels 5 through 12 would be like;
+An example with zoom levels 5 through 12 and ~2 extra tiles around each zoom level would be like:
::
- $ tilecache_seed.py "http://example.com/yourdir/tilecache.cgi?" Zip_Codes 5 12 "-118.12500,31.952162238,-116.015625,34.3071438563"
+ $ tilecache_seed.py Zip_Codes 5 12 "-118.12500,31.952162238,-116.015625,34.3071438563" 2
The bbox can be dropped and defaults to world lonlat(-180,-90,180,90):
::
- $ tilecache_seed.py "http://example.com/yourdir/tilecache.cgi?" Zip_Codes 0 9
+ $ tilecache_seed.py Zip_Codes 0 9
In center point/radius mode, the zoom level range is not specifiable from the
@@ -420,7 +420,7 @@
::
- $ tilecache_seed.py "http://example.com/yourdir/tilecache.cgi?" Zip_Codes
+ $ tilecache_seed.py Zip_Codes
-118.12500,31.952162238,0.05
-121.46327,32.345345645,0.08
<Ctrl+D>
More information about the Tilecache
mailing list