tileserver-gl/src/serve_vector.js
2016-03-02 17:51:50 +01:00

101 lines
2.7 KiB
JavaScript

'use strict';
var async = require('async'),
asyncLock = require('async-lock'),
crypto = require('crypto'),
fs = require('fs'),
path = require('path'),
util = require('util'),
zlib = require('zlib');
var abaculus = require('abaculus'),
clone = require('clone'),
concat = require('concat-stream'),
express = require('express'),
mercator = new (require('sphericalmercator'))(),
mbgl = require('mapbox-gl-native'),
mbtiles = require('mbtiles'),
request = require('request');
var utils = require('./utils');
module.exports = function(maps, options, prefix) {
var lock = new asyncLock();
var app = express().disable('x-powered-by'),
domains = options.domains,
tilePath = '/{z}/{x}/{y}.pbf';
var rootPath = path.join(process.cwd(), options.root);
var mbtilesPath = options.mbtiles;
var map = {
tileJSON: {}
};
maps[prefix] = map;
var source = new mbtiles(path.join(rootPath, mbtilesPath), function(err) {
source.getInfo(function(err, info) {
map.tileJSON['name'] = prefix.substr(1);
Object.assign(map.tileJSON, info);
map.tileJSON['tilejson'] = '2.0.0';
map.tileJSON['basename'] = prefix.substr(1);
map.tileJSON['format'] = 'pbf';
Object.assign(map.tileJSON, options.options || {});
});
});
var tilePattern = tilePath
.replace('{z}', ':z(\\d+)')
.replace('{x}', ':x(\\d+)')
.replace('{y}', ':y(\\d+)');
var getTile = function(z, x, y, callback) {
source.getTile(z, x, y, function(err, data, headers) {
if (err) {
callback(err);
} else {
var md5 = crypto.createHash('md5').update(data).digest('base64');
headers['content-md5'] = md5;
headers['content-type'] = 'application/x-protobuf';
headers['content-encoding'] = 'gzip';
callback(null, data, headers);
}
});
};
app.get(tilePattern, function(req, res, next) {
var z = req.params.z | 0,
x = req.params.x | 0,
y = req.params.y | 0;
return getTile(z, x, y, function(err, data, headers) {
if (err) {
return next(err);
}
if (headers) {
res.set(headers);
}
if (data == null) {
return res.status(404).send('Not found');
} else {
return res.status(200).send(data);
}
}, res, next);
});
app.get('/index.json', function(req, res, next) {
var info = clone(map.tileJSON);
info.tiles = utils.getTileUrls(req.protocol, domains, req.headers.host,
prefix, tilePath, info.format,
req.query.key);
return res.send(info);
});
return app;
};