Sketch in cache

This commit is contained in:
Tom Russell 2019-02-24 15:15:52 +00:00
parent af46067018
commit c5ebcd2df8
3 changed files with 96 additions and 4 deletions

4
.gitignore vendored
View File

@ -18,5 +18,9 @@ etl/**/*.xls
etl/**/*.xlsx
etl/**/*.zip
# Cache
app/tilecache/**/*.png
app/tilecache/**/*.mbtiles
# Notes
TODO

72
app/src/tiles/cache.js Normal file
View File

@ -0,0 +1,72 @@
/**
* Cache tiles (PNG images generated from database)
*
* Frequency of change:
* - base layer tiles change rarely - on changes to underlying geometry table
* - visualisation layer tiles change frequently - with almost any edit to the buildings table
*
* Cost of generation and storage:
* - low zoom tiles are more expensive to render, containing more features from the database
* - high zoom tiles are cheaper to rerender, and changes are more visible
* - there are many more high zoom tiles than low: 4 tiles at zoom level n+1 for each tile
* at zoom level n
*
*/
import fs from 'fs';
import path from 'path';
// const CACHE_PATH = process.env.CACHE_PATH
const CACHE_PATH = '/home/tom/projects/colouring-london/colouring-london/app/tilecache'
function get(tileset, z, x, y, cb){
if (!should_try_cache(tileset, z)) {
cb("Skip cache", null)
return
}
const dir = `${CACHE_PATH}/${tileset}/${z}/${x}`
const fname = `${dir}/${y}.png`
fs.readFile(fname, cb)
}
function put(im, tileset, z, x, y, cb){
if (!should_try_cache(tileset, z)) {
cb("Skip cache")
return
}
const dir = `${CACHE_PATH}/${tileset}/${z}/${x}`
const fname = `${dir}/${y}.png`
fs.writeFile(fname, im, 'binary', (err) => {
if (err && err.code === 'ENOENT') {
try {
console.log("trying")
mkdir_recursive(dir);
fs.writeFile(fname, im, 'binary', cb);
} catch (error) {
console.log("mkdir error")
cb(err);
}
} else {
cb(err)
}
});
}
// for node >10 we could drop this in favour of fs.mkdir(dir, { recursive: true }, (err) => {})
function mkdir_recursive(dir) {
const parent = path.dirname(dir);
if (!fs.existsSync(parent)) {
mkdir_recursive(parent)
}
fs.mkdirSync(dir);
}
function should_try_cache(tileset, z) {
if (tileset === 'base_light' || tileset === 'base_light') {
// cache for higher zoom levels (unlikely to change)
return z <= 15
}
// else cache for lower zoom levels (change slowly)
return z <= 12
}
export { get, put };

View File

@ -4,6 +4,7 @@
*/
import express from 'express';
import { get, put } from './cache';
import { render_tile } from './tile';
import { strictParseInt } from '../parse';
@ -51,12 +52,27 @@ function handle_tile_request(tileset, req, res) {
return {error:'Bad parameter'}
}
render_tile(tileset, int_z, int_x, int_y, undefined, function(err, im) {
if (err) throw err
get(tileset, int_z, int_x, int_y, (err, im) => {
if (err) {
render_tile(tileset, int_z, int_x, int_y, undefined, (err, im) => {
if (err) throw err
res.writeHead(200, {'Content-Type': 'image/png'})
res.end(im)
put(im, tileset, z, x, y, (err) => {
if (err) {
console.error(err)
}
res.writeHead(200, {'Content-Type': 'image/png'})
res.end(im)
})
})
} else {
res.writeHead(200, {'Content-Type': 'image/png'})
res.end(im)
}
})
}
function handle_highlight_tile_request(req, res) {