2018-09-30 14:50:09 -04:00
|
|
|
/**
|
|
|
|
* Tile-rendering helpers
|
|
|
|
*
|
|
|
|
*/
|
2018-09-10 05:44:32 -04:00
|
|
|
import path from 'path';
|
|
|
|
import mapnik from 'mapnik';
|
|
|
|
import SphericalMercator from '@mapbox/sphericalmercator';
|
|
|
|
|
2019-02-24 07:17:59 -05:00
|
|
|
import { strictParseInt } from '../parse';
|
2018-09-13 15:36:14 -04:00
|
|
|
|
2018-09-30 11:18:34 -04:00
|
|
|
// connection details from environment variables
|
2018-09-10 05:44:32 -04:00
|
|
|
const DATASOURCE_CONFIG = {
|
2018-09-30 11:18:34 -04:00
|
|
|
'host': process.env.PGHOST,
|
|
|
|
'dbname': process.env.PGDATABASE,
|
|
|
|
'user': process.env.PGUSER,
|
|
|
|
'password': process.env.PGPASSWORD,
|
|
|
|
'port': process.env.PGPORT,
|
2018-09-10 05:44:32 -04:00
|
|
|
'geometry_field': 'geometry_geom',
|
|
|
|
'extent' : '-20005048.4188,-9039211.13765,19907487.2779,17096598.5401',
|
|
|
|
'srid': 3857,
|
|
|
|
'type': 'postgis'
|
|
|
|
}
|
|
|
|
|
|
|
|
const TILE_SIZE = 256
|
|
|
|
const TILE_BUFFER_SIZE = 64
|
|
|
|
const PROJ4_STRING = '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over';
|
|
|
|
|
2018-09-30 11:18:34 -04:00
|
|
|
// register datasource adapters for mapnik database connection
|
2018-09-10 05:44:32 -04:00
|
|
|
if (mapnik.register_default_input_plugins) mapnik.register_default_input_plugins();
|
2018-09-30 11:18:34 -04:00
|
|
|
// register fonts for text rendering
|
2018-09-11 18:29:30 -04:00
|
|
|
mapnik.register_default_fonts();
|
2018-09-10 05:44:32 -04:00
|
|
|
|
|
|
|
const mercator = new SphericalMercator({
|
|
|
|
size: TILE_SIZE
|
|
|
|
});
|
|
|
|
|
2019-01-22 17:37:44 -05:00
|
|
|
function get_bbox(int_z, int_x, int_y){
|
|
|
|
return mercator.bbox(
|
|
|
|
int_x,
|
|
|
|
int_y,
|
|
|
|
int_z,
|
|
|
|
false,
|
|
|
|
'900913'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function should_try_cache(style, int_z) {
|
|
|
|
if (style === 'base_light' || style === 'base_light') {
|
|
|
|
// cache for higher zoom levels (unlikely to change)
|
|
|
|
return int_z <= 15
|
|
|
|
}
|
|
|
|
// else cache for lower zoom levels (change slowly)
|
|
|
|
return int_z <= 12
|
|
|
|
}
|
|
|
|
|
|
|
|
function render_tile(params, table_def, style_def, cb){
|
2018-09-10 05:44:32 -04:00
|
|
|
const { z, x, y } = params
|
2018-09-13 15:36:14 -04:00
|
|
|
const int_z = strictParseInt(z);
|
|
|
|
const int_x = strictParseInt(x);
|
|
|
|
const int_y = strictParseInt(y);
|
2018-09-10 05:44:32 -04:00
|
|
|
|
2018-09-13 15:36:14 -04:00
|
|
|
if (isNaN(int_x) || isNaN(int_y) || isNaN(int_z)){
|
2018-09-10 05:44:32 -04:00
|
|
|
console.error("Missing x or y or z")
|
|
|
|
return {error:'Bad parameter'}
|
|
|
|
}
|
2019-01-22 17:37:44 -05:00
|
|
|
const bbox = get_bbox(int_z, int_x, int_y)
|
|
|
|
// const should_cache = should_try_cache(style_def[0], int_z)
|
2018-09-10 05:44:32 -04:00
|
|
|
|
|
|
|
const map = new mapnik.Map(TILE_SIZE, TILE_SIZE, PROJ4_STRING);
|
|
|
|
map.bufferSize = TILE_BUFFER_SIZE;
|
|
|
|
|
|
|
|
const layer = new mapnik.Layer('tile', PROJ4_STRING);
|
|
|
|
const conf = Object.assign({table: table_def}, DATASOURCE_CONFIG)
|
|
|
|
|
2018-09-13 18:55:53 -04:00
|
|
|
var postgis;
|
|
|
|
try {
|
|
|
|
postgis = new mapnik.Datasource(conf);
|
|
|
|
layer.datasource = postgis;
|
|
|
|
layer.styles = style_def
|
2018-09-10 05:44:32 -04:00
|
|
|
|
2018-09-13 18:55:53 -04:00
|
|
|
map.load(
|
|
|
|
path.join(__dirname, '..', 'map_styles', 'polygon.xml'),
|
|
|
|
{ strict: true },
|
|
|
|
function(err, map){
|
|
|
|
if (err) {
|
|
|
|
console.error(err);
|
|
|
|
return
|
|
|
|
}
|
2018-09-10 05:44:32 -04:00
|
|
|
|
2018-09-13 18:55:53 -04:00
|
|
|
map.add_layer(layer)
|
|
|
|
const im = new mapnik.Image(map.width, map.height)
|
|
|
|
map.extent = bbox
|
|
|
|
map.render(im, cb);
|
|
|
|
}
|
|
|
|
)
|
|
|
|
} catch(err) {
|
|
|
|
console.error(err);
|
|
|
|
}
|
2018-09-10 05:44:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export { get_bbox, render_tile };
|