Skip to content

Instantly share code, notes, and snippets.

@ThomasHalwax
Last active April 13, 2020 10:32
Show Gist options
  • Save ThomasHalwax/551a1b4e6bebf049f7050cc916d5c921 to your computer and use it in GitHub Desktop.
Save ThomasHalwax/551a1b4e6bebf049f7050cc916d5c921 to your computer and use it in GitHub Desktop.
working draft for a MBTileSource that reads tiles from a given MBTiles container at a given path
import XYZ from 'ol/source/XYZ'
import TileState from 'ol/TileState'
import Database, { Integer } from 'better-sqlite3'
const MBTileSource = options => {
/* instance of the SQLite db */
const db = new Database(options.path, { readonly: true })
const metadata = name => {
const result = db.prepare('SELECT value FROM metadata WHERE name=?').get(name)
return (result ? result.value : null)
}
const imageFormat = metadata('format')
if (!imageFormat || imageFormat === 'pbf') throw new Error('unsupported tile image format')
const getTile = (z, x, y /* , pixelRatio, projection */) => {
// console.log(`fetching tile for ${z}/${x}/${y}`)
const tile = db.prepare(`
SELECT tile_data FROM tiles
WHERE zoom_level = :z AND tile_column = :x AND tile_row = :y`
).get({
z: Integer(z),
x: Integer(x),
y: Integer((1 << z) - 1 - y) // flip y for TMS tiling scheme
})
return tile ? tile.tile_data : null
}
const source = new XYZ()
/* no URL required, returns just the z,x,y coords as an array */
source.tileUrlFunction = (coordinates /*, p2, projection */) => {
return coordinates
}
/* loading the tiles by coords */
source.tileLoadFunction = (tile, coords) => {
const image = getTile(coords[0], coords[1], coords[2])
if (image) {
tile.getImage().src = `data:image/${imageFormat};base64,${Buffer.from(image).toString('base64')}`
} else {
tile.setState(TileState.ERROR)
}
}
return source
}
export default MBTileSource
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment