Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Print debugging info for an MBTiles files
#!/usr/bin/env python
from math import *
from optparse import OptionParser
import sqlite3 as sqlite
import os
# The following code is from http://svn.openstreetmap.org/applications/routing/pyroute/tilenames.py
def numTiles(z):
return(pow(2,z))
def sec(x):
return(1/cos(x))
def latEdges(y,z):
n = numTiles(z)
unit = 1 / n
relY1 = y * unit
relY2 = relY1 + unit
lat1 = mercatorToLat(pi * (1 - 2 * relY1))
lat2 = mercatorToLat(pi * (1 - 2 * relY2))
return(lat1,lat2)
def lonEdges(x,z):
n = numTiles(z)
unit = 360 / n
lon1 = -180 + x * unit
lon2 = lon1 + unit
return(lon1,lon2)
def mercatorToLat(mercatorY):
return(degrees(atan(sinh(mercatorY))))
#end of code from tilenames.py
def flipY(y, z):
return (2 ** z) - y - 1
if __name__ == "__main__":
usage = "usage: %prog file.mbtiles"
parser = OptionParser(usage=usage,
description="Print information about an mbtiles file")
parser.add_option("-y", "--flip-y", action="store_true", dest="flip_y", help="use TMS y origin, not OSM/google")
(options, args) = parser.parse_args()
for path in args:
if not os.path.exists(path):
print path + " not found"
continue
try:
con = sqlite.connect(path)
cursor = con.cursor()
print "Tables:"
cursor.execute("SELECT type, name, sql FROM sqlite_master ORDER BY type, name")
for t, name, sql in cursor.fetchall():
print "\t%s %s" % (t, name)
print "\t\t%s" % (sql,)
cursor.execute("SELECT name, value FROM metadata")
print "\nMetadata:"
for key, value in cursor.fetchall():
print "\t%s=%s" % (key, value)
print "\nTiles:"
cursor.execute("SELECT DISTINCT zoom_level FROM tiles")
zooms = cursor.fetchall()
for (zoom,) in zooms:
cursor = con.cursor()
#get tile extent
cursor.execute("""SELECT min(tile_column), max(tile_column),
min(tile_row), max(tile_row) FROM tiles WHERE zoom_level=?""", (zoom,))
minX, maxX, minY, maxY = cursor.fetchone()
minY = flipY(minY, zoom)
maxY = flipY(maxY, zoom)
#count tiles
cursor.execute("SELECT count(1) FROM tiles WHERE zoom_level=?", (zoom,))
(tile_count,) = cursor.fetchone()
print "\t%d" % zoom
print "\t\t%d tiles" % tile_count
if options.flip_y: #mbtiles use TMS origin, but by default we flip
print "\t\tx:%d-%d y:%d-%d" % (minX, maxX, flipY(minY, zoom), flipY(maxY, zoom))
else:
print "\t\tx:%d-%d y:%d-%d" % (minX, maxX, minY, maxY)
#convert tile extent to latlon
minYTop, minYBottom = latEdges(minY, zoom)
maxYTop, maxYBottom = latEdges(maxY, zoom)
minXLeft, minXRight = lonEdges(minX, zoom)
maxXLeft, maxXRight = lonEdges(maxX, zoom)
print "\t\tBBOX:", (min(minXLeft, minXRight, maxXLeft, maxXRight),
min(minYBottom, minYTop, maxYBottom, maxYTop),
max(minXLeft, minXRight, maxXLeft, maxXRight),
max(minYBottom, minYTop, maxYBottom, maxYTop))
except Exception, e:
print "Error", e
finally:
if con:
con.close()
@JesseCrocker

This comment has been minimized.

Copy link
Owner Author

JesseCrocker commented May 14, 2014

Example output

$ mbtile-info.py example.mbtiles
Tables:
    index images_index
        CREATE INDEX images_index ON images (tile_id)
    index map_index
        CREATE INDEX map_index ON map (zoom_level,tile_column,tile_row)
    table images
        CREATE TABLE images (tile_id TEXT, tile_data BLOB)
    table map
        CREATE TABLE map (zoom_level INTEGER,tile_column INTEGER,tile_row INTEGER,tile_id TEXT)
    table metadata
        CREATE TABLE metadata (name TEXT, value TEXT)
    view tiles
        CREATE VIEW tiles AS SELECT map.zoom_level as zoom_level,map.tile_column as tile_column,map.tile_row as tile_row,images.tile_data as tile_data FROM map JOIN images ON map.tile_id = images.tile_id

Metadata:
    name=FraserIsland_png32_1401
    description=None
    attribution=None
    type=overlay
    version=1
    format=png
    minzoom=8
    maxzoom=15
    bounds=152.626880,-25.835844,153.421742,-24.690222

Tiles:
    8
        4 tiles
        x:236-237 y:147-146
        BBOX: (151.875, -27.059125784374054, 154.6875, -24.5271348225978)
    9
        6 tiles
        x:473-474 y:294-292
        BBOX: (152.578125, -26.431228064506435, 153.984375, -24.5271348225978)
    10
        15 tiles
        x:946-948 y:588-584
        BBOX: (152.578125, -26.11598592533352, 153.6328125, -24.5271348225978)
    11
        40 tiles
        x:1892-1896 y:1176-1169
        BBOX: (152.578125, -25.958044673317843, 153.45703125, -24.68695241199915)
    12
        150 tiles
        x:3784-3793 y:2352-2338
        BBOX: (152.578125, -25.878994400196206, 153.45703125, -24.68695241199915)
    13
        551 tiles
        x:7569-7587 y:4704-4676
        BBOX: (152.6220703125, -25.83944940206318, 153.45703125, -24.68695241199915)
    14
        2146 tiles
        x:15138-15174 y:9409-9352
        BBOX: (152.6220703125, -25.83944940206318, 153.43505859375, -24.68695241199915)
    15
        8468 tiles
        x:30276-30348 y:18819-18704
        BBOX: (152.6220703125, -25.83944940206318, 153.424072265625, -24.68695241199915)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.