Skip to content

Commit

Permalink
Added MBTiles output option for tilestache-seed
Browse files Browse the repository at this point in the history
  • Loading branch information
migurski committed Jul 4, 2011
1 parent 5cb19cf commit 277a592
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 10 deletions.
49 changes: 49 additions & 0 deletions TileStache/MBTiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ def tileset_exists(filename):

# this always works
db = _connect(filename)
db.text_factory = bytes

try:
db.execute('SELECT name, value FROM metadata LIMIT 1')
Expand All @@ -115,6 +116,7 @@ def get_tile(filename, coord):
If the tile does not exist, None is returned for the content.
"""
db = _connect(filename)
db.text_factory = bytes

formats = {'png': 'image/png', 'jpg': 'image/jpeg', None: None}
format = db.execute("SELECT value FROM metadata WHERE name='format'").fetchone()
Expand All @@ -128,6 +130,19 @@ def get_tile(filename, coord):

return mime_type, content

def put_tile(filename, coord, content):
"""
"""
db = _connect(filename)
db.text_factory = bytes

tile_row = (2**coord.zoom - 1) - coord.row # Hello, Paul Ramsey.
q = 'REPLACE INTO tiles (zoom_level, tile_column, tile_row, tile_data) VALUES (?, ?, ?, ?)'
db.execute(q, (coord.zoom, coord.column, tile_row, content))

db.commit()
db.close()

class Provider:
""" MBTiles provider.
Expand Down Expand Up @@ -170,3 +185,37 @@ def save(self, out, format):
raise Exception('Requested format "%s" does not match tileset format "%s"' % (format, self.format))

out.write(self.content)

class Cache:
""" Cache provider for writing to MBTiles files.
This class is not exposed as a normal cache provider for TileStache,
because MBTiles has restrictions on file formats that aren't quite
compatible with some of the looser assumptions made by TileStache.
Instead, this cache provider is provided for use with the script
tilestache-seed.py, which can be called with --to-mbtiles option
to write cached tiles to a new tileset.
"""
def __init__(self, filename, format, name):
"""
"""
self.filename = filename

if not tileset_exists(filename):
create_tileset(filename, name, 'baselayer', '0', '', format.lower())

def lock(self, layer, coord, format):
return

def unlock(self, layer, coord, format):
return

def read(self, layer, coord, format):
""" Return raw tile content from tileset.
"""
return get_tile(self.filename, coord)[1]

def save(self, body, layer, coord, format):
""" Write raw tile content to tileset.
"""
put_tile(self.filename, coord, body)
3 changes: 3 additions & 0 deletions man/tilestache-seed.1
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ Optional output directory for tiles, to override configured cache with the equiv

More information in http://tilestache.org/doc/#caches.
.TP
.B \-\-to\-mbtiles
Optional output file for tiles, will be created as an MBTiles 1.1 tileset. See http://mbtiles.org for more information.
.TP
.B \-x, \-\-ignore-cached
Re-render every tile, whether it is in the cache already or not.
.SH SEE ALSO
Expand Down
35 changes: 25 additions & 10 deletions scripts/tilestache-seed.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,9 @@
except ImportError:
from simplejson import dump as json_dump

from TileStache import parseConfigfile, getTile
from TileStache.Core import KnownUnknown
from TileStache.Caches import Disk

from ModestMaps.Core import Coordinate
from ModestMaps.Geo import Location
#
# Most imports can be found below, after the --include-path option is known.
#

parser = OptionParser(usage="""%prog [options] [zoom...]
Expand Down Expand Up @@ -66,6 +63,9 @@
parser.add_option('-d', '--output-directory', dest='outputdirectory',
help='Optional output directory for tiles, to override configured cache with the equivalent of: {"name": "Disk", "path": <output directory>, "dirs": "portable", "gzip": []}. More information in http://tilestache.org/doc/#caches.')

parser.add_option('--to-mbtiles', dest='mbtiles_output',
help='Optional output file for tiles, will be created as an MBTiles 1.1 tileset. See http://mbtiles.org for more information.')

parser.add_option('-x', '--ignore-cached', action='store_true', dest='ignore_cached',
help='Re-render every tile, whether it is in the cache already or not.')

Expand Down Expand Up @@ -104,10 +104,17 @@ def generateCoordinates(ul, lr, zooms, padding):
options, zooms = parser.parse_args()

if options.include:

for p in options.include.split(':'):
path.insert(0, p)

from TileStache import parseConfigfile, getTile
from TileStache.Core import KnownUnknown
from TileStache.Caches import Disk, Multi
from TileStache import MBTiles

from ModestMaps.Core import Coordinate
from ModestMaps.Geo import Location

try:
if options.config is None:
raise KnownUnknown('Missing required configuration (--config) parameter.')
Expand All @@ -116,9 +123,6 @@ def generateCoordinates(ul, lr, zooms, padding):
raise KnownUnknown('Missing required layer (--layer) parameter.')

config = parseConfigfile(options.config)

if options.outputdirectory:
config.cache = Disk(options.outputdirectory, dirs='portable', gzip=[])

if options.layer not in config.layers:
raise KnownUnknown('"%s" is not a layer I know about. Here are some that I do know about: %s.' % (options.layer, ', '.join(sorted(config.layers.keys()))))
Expand All @@ -128,6 +132,17 @@ def generateCoordinates(ul, lr, zooms, padding):
verbose = options.verbose
extension = options.extension
progressfile = options.progressfile

if options.outputdirectory and options.mbtiles_output:
cache1 = Disk(options.outputdirectory, dirs='portable', gzip=[])
cache2 = MBTiles.Cache(options.mbtiles_output, extension, options.layer)
config.cache = Multi([cache1, cache2])

elif options.outputdirectory:
config.cache = Disk(options.outputdirectory, dirs='portable', gzip=[])

elif options.mbtiles_output:
config.cache = MBTiles.Cache(options.mbtiles_output, extension, options.layer)

lat1, lon1, lat2, lon2 = options.bbox
south, west = min(lat1, lat2), min(lon1, lon2)
Expand Down

0 comments on commit 277a592

Please sign in to comment.