[Tilecache] Virtual Earth compatible TC-cache
Steven M. Ottens
steven at minst.net
Fri Feb 8 11:01:44 EST 2008
Hi all,
For those lost souls who want to create a cache which is directly
compatible with the virtual earth client I've attached a modified
disk.py, renamed to VE.py. It is written for TC 2.01 and should be put
in the <tilecache>/Cache folder.
Some information on the VE compatible cache structure:
http://msdn2.microsoft.com/en-us/library/bb259689.aspx
This VE cache is a flat file structure, which means that you need a
filesystem that can handle thousands of files in a directory. To be
honest the only reason why you would want to do this is so you can
directly add a dataset in virtualearth using the new
VETileSourceSpecification
and have the files available in a web-accessible directory. The next
step will be to add a VE layer so you can use tilecache to dynamically
generate the VE-tiles.
The reason why you want to create VE-specific tiles is to be able to
view them in 3D (inside the VE viewer).
Regards,
Steven
-------------- next part --------------
# BSD Licensed, Copyright (c) 2006-2007 MetaCarta, Inc.
from TileCache.Cache import Cache
import sys, os, time
class VE (Cache):
def __init__ (self, base = None, umask = '002', **kwargs):
Cache.__init__(self, **kwargs)
self.basedir = base
self.umask = int(umask, 0)
if sys.platform.startswith("java"):
from java.io import File
self.file_module = File
self.platform = "jython"
else:
self.platform = "cpython"
if not self.access(base, 'read'):
self.makedirs(base)
def makedirs(self, path):
old_umask = os.umask(self.umask)
os.makedirs(path)
os.umask(old_umask)
def access(self, path, type='read'):
if self.platform == "jython":
if type == "read":
return self.file_module(path).canRead()
else:
return self.file_module(path).canWrite()
else:
if type =="read":
return os.access(path, os.R_OK)
else:
return os.access(path, os.W_OK)
def getKey (self, tile):
components = ( self.basedir,
tile.layer.name,
"%s.%s" % (self.quad(tile),tile.layer.extension)
)
filename = os.path.join( *components )
return filename
def quad (self, tile):
quadKey = ''
for i in range (tile.z, 0, -1):
digit = 0
mask = 1 << (i -1 )
if (tile.x & mask) != 0:
digit=digit+1
if (tile.y & mask) !=0:
digit=digit+2
quadKey = quadKey + str(digit)
return quadKey
def get (self, tile):
filename = self.getKey(tile)
if self.access(filename, 'read'):
tile.data = file(filename, "rb").read()
return tile.data
else:
return None
def set (self, tile, data):
if self.readonly: return data
filename = self.getKey(tile)
dirname = os.path.dirname(filename)
if not self.access(dirname, 'write'):
self.makedirs(dirname)
tmpfile = filename + ".%d.tmp" % os.getpid()
old_umask = os.umask(self.umask)
output = file(tmpfile, "wb")
output.write(data)
output.close()
os.umask( old_umask );
try:
os.rename(tmpfile, filename)
except OSError:
os.unlink(filename)
os.rename(tmpfile, filename)
tile.data = data
return data
def delete (self, tile):
filename = self.getKey(tile)
if self.access(filename, 'read'):
os.unlink(filename)
def attemptLock (self, tile):
name = self.getLockName(tile)
try:
self.makedirs(name)
return True
except OSError:
pass
try:
st = os.stat(name)
if st.st_ctime + self.stale < time.time():
warnings.warn("removing stale lock %s" % name)
# remove stale lock
self.unlock()
self.makedirs(name)
return True
except OSError:
pass
return False
def unlock (self, tile):
name = self.getLockName(tile)
try:
os.rmdir(name)
except OSError, E:
print >>sys.stderr, "unlock %s failed: %s" % (name, str(E))
More information about the Tilecache
mailing list