diff --git a/public/templates/index.tmpl b/public/templates/index.tmpl index 258d3c1..054c2ee 100644 --- a/public/templates/index.tmpl +++ b/public/templates/index.tmpl @@ -13,24 +13,24 @@ {{#each styles}}
{{#if thumbnail}} - {{name}} preview + {{name}} preview {{else}}
{{/if}}

{{name}}

Id: {{@key}} - {{#if serving_raster}} - | TileJSON + {{#if serving_rendered}} + | TileJSON {{/if}}

- {{#if serving_style}} + {{#if serving_data}} Vector view {{/if}} - {{#if serving_raster}} + {{#if serving_rendered}} Raster view {{/if}} - {{#if serving_style}} - {{#if serving_raster}} + {{#if serving_data}} + {{#if serving_rendered}} Auto view {{/if}} {{/if}} @@ -41,14 +41,17 @@
{{#each data}}
-
+ {{#if thumbnail}} + {{name}} preview + {{else}} +
+ {{/if}}

{{name}}

-

Id: {{@key}} | TileJSON

+

Id: {{@key}} | {{#is_vector}}Vector{{/is_vector}}{{^is_vector}}Raster{{/is_vector}} data | TileJSON

{{#is_vector}} X-Ray viewer {{/is_vector}} {{^is_vector}} - Raster tiles {{/is_vector}}
{{/each}} diff --git a/public/templates/viewer.tmpl b/public/templates/viewer.tmpl index 282f86b..080cb20 100644 --- a/public/templates/viewer.tmpl +++ b/public/templates/viewer.tmpl @@ -28,7 +28,7 @@ }); map.addControl(new mapboxgl.Navigation()); } else { - var map = L.mapbox.map('map', '/raster/{{id}}.json', { zoomControl: false }); + var map = L.mapbox.map('map', '/styles/{{id}}/rendered.json', { zoomControl: false }); new L.Control.Zoom({ position: 'topright' }).addTo(map); setTimeout(function() { new L.Hash(map); diff --git a/src/serve_tiles.js b/src/serve_data.js similarity index 94% rename from src/serve_tiles.js rename to src/serve_data.js index 1b08604..561f90c 100644 --- a/src/serve_tiles.js +++ b/src/serve_data.js @@ -35,7 +35,7 @@ module.exports = function(options, repo, params, id) { }); }); - var tilePattern = '/data/' + id + '/:z(\\d+)/:x(\\d+)/:y(\\d+).:format([\\w]+)'; + var tilePattern = '/' + id + '/:z(\\d+)/:x(\\d+)/:y(\\d+).:format([\\w]+)'; app.get(tilePattern, function(req, res, next) { var z = req.params.z | 0, @@ -74,7 +74,7 @@ module.exports = function(options, repo, params, id) { }); }); - app.get('/data/' + id + '.json', function(req, res, next) { + app.get('/' + id + '.json', function(req, res, next) { var info = clone(tileJSON); info.tiles = utils.getTileUrls(req, info.tiles, 'data/' + id, info.format); diff --git a/src/serve_font.js b/src/serve_font.js index 49e5b71..fc93772 100644 --- a/src/serve_font.js +++ b/src/serve_font.js @@ -31,7 +31,7 @@ module.exports = function(options, allowedFonts) { } }; - app.get('/fonts/:fontstack/:range([\\d]+-[\\d]+).pbf', + app.get('/:fontstack/:range([\\d]+-[\\d]+).pbf', function(req, res, next) { var fontstack = decodeURI(req.params.fontstack); var range = req.params.range; diff --git a/src/serve_raster.js b/src/serve_rendered.js similarity index 93% rename from src/serve_raster.js rename to src/serve_rendered.js index 201a632..c8c7106 100644 --- a/src/serve_raster.js +++ b/src/serve_rendered.js @@ -61,7 +61,8 @@ module.exports = function(options, repo, params, id) { var source = map.sources[parts[2]]; var z = parts[3] | 0, x = parts[4] | 0, - y = parts[5].split('.')[0] | 0; + y = parts[5].split('.')[0] | 0, + format = parts[5].split('.')[1]; source.getTile(z, x, y, function(err, data, headers) { if (err) { //console.log('MBTiles error, serving empty', err); @@ -76,7 +77,11 @@ module.exports = function(options, repo, params, id) { response.etag = headers['ETag']; } - response.data = zlib.unzipSync(data); + if (format == 'pbf') { + response.data = zlib.unzipSync(data); + } else { + response.data = data; + } callback(null, response); } @@ -162,7 +167,7 @@ module.exports = function(options, repo, params, id) { source.basename = name; source.tiles = [ // meta url which will be detected when requested - 'mbtiles://' + name + '/{z}/{x}/{y}.pbf' + 'mbtiles://' + name + '/{z}/{x}/{y}.' + (info.format || 'pbf') ]; callback(null); }); @@ -180,7 +185,7 @@ module.exports = function(options, repo, params, id) { repo[id] = tileJSON; - var tilePattern = '/raster/' + id + '/:z(\\d+)/:x(\\d+)/:y(\\d+)' + + var tilePattern = '/rendered/:z(\\d+)/:x(\\d+)/:y(\\d+)' + ':scale(' + SCALE_PATTERN + ')?\.:format([\\w]+)'; var respondImage = function(z, lon, lat, bearing, pitch, @@ -279,7 +284,7 @@ module.exports = function(options, repo, params, id) { }); var staticPattern = - '/static/' + id + '/%s:scale(' + SCALE_PATTERN + ')?\.:format([\\w]+)'; + '/rendered/static/%s:scale(' + SCALE_PATTERN + ')?\.:format([\\w]+)'; var centerPattern = util.format(':lon(%s),:lat(%s),:z(\\d+):bearing(,%s)?:pitch(,%s)?/' + @@ -290,8 +295,8 @@ module.exports = function(options, repo, params, id) { var z = req.params.z | 0, x = +req.params.lon, y = +req.params.lat, - bearing = +(req.params.bearing || ',0').substring(1), - pitch = +(req.params.pitch || ',0').substring(1), + bearing = +((req.params.bearing || ',0').substring(1)), + pitch = +((req.params.pitch || ',0').substring(1)), w = req.params.width | 0, h = req.params.height | 0, scale = getScale(req.params.scale), @@ -319,10 +324,10 @@ module.exports = function(options, repo, params, id) { return respondImage(z, x, y, 0, 0, w, h, scale, format, res, next); }); - app.get('/raster/' + id + '.json', function(req, res, next) { + app.get('/rendered.json', function(req, res, next) { var info = clone(tileJSON); info.tiles = utils.getTileUrls(req, info.tiles, - 'raster/' + id, info.format); + 'styles/' + id + '/rendered', info.format); return res.send(info); }); diff --git a/src/serve_style.js b/src/serve_style.js index eb6a80b..87c06f9 100644 --- a/src/serve_style.js +++ b/src/serve_style.js @@ -45,7 +45,7 @@ module.exports = function(options, repo, params, id, reportTiles, reportFont) { repo[id] = styleJSON; - app.get('/styles/' + id + '.json', function(req, res, next) { + app.get('/' + id + '.json', function(req, res, next) { var fixUrl = function(url) { return url.replace( 'local://', req.protocol + '://' + req.headers.host + '/'); @@ -61,7 +61,7 @@ module.exports = function(options, repo, params, id, reportTiles, reportFont) { return res.send(styleJSON_); }); - app.get('/styles/' + id + '/sprite:scale(@[23]x)?\.:format([\\w]+)', + app.get('/' + id + '/sprite:scale(@[23]x)?\.:format([\\w]+)', function(req, res, next) { var scale = req.params.scale, format = req.params.format; diff --git a/src/server.js b/src/server.js index f185103..0e6727c 100644 --- a/src/server.js +++ b/src/server.js @@ -15,17 +15,17 @@ var clone = require('clone'), morgan = require('morgan'); var serve_font = require('./serve_font'), - serve_raster = require('./serve_raster'), + serve_rendered = require('./serve_rendered'), serve_style = require('./serve_style'), - serve_tiles = require('./serve_tiles'), + serve_data = require('./serve_data'), utils = require('./utils'); module.exports = function(opts, callback) { var app = express().disable('x-powered-by'), serving = { styles: {}, - raster: {}, - tiles: {}, + rendered: {}, + data: {}, fonts: { // default fonts, always expose these (if they exist) 'Open Sans Regular': true, 'Arial Unicode MS Regular': true @@ -61,7 +61,7 @@ module.exports = function(opts, callback) { paths.sprites = path.resolve(paths.root, paths.sprites || ''); paths.mbtiles = path.resolve(paths.root, paths.mbtiles || ''); - var tiles = clone(config.data || {}); + var data = clone(config.data || {}); Object.keys(config.styles || {}).forEach(function(id) { var item = config.styles[id]; @@ -71,20 +71,20 @@ module.exports = function(opts, callback) { } if (item.serve_data !== false) { - app.use('/', serve_style(options, serving.styles, item, id, + app.use('/styles/', serve_style(options, serving.styles, item, id, function(mbtiles) { - var tilesItemId; - Object.keys(tiles).forEach(function(id) { - if (tiles[id].mbtiles == mbtiles) { - tilesItemId = id; + var dataItemId; + Object.keys(data).forEach(function(id) { + if (data[id].mbtiles == mbtiles) { + dataItemId = id; } }); - if (tilesItemId) { // mbtiles exist in the tiles config - return tilesItemId; + if (dataItemId) { // mbtiles exist in the data config + return dataItemId; } else { var id = mbtiles.substr(0, mbtiles.lastIndexOf('.')) || mbtiles; - while (tiles[id]) id += '_'; - tiles[id] = { + while (data[id]) id += '_'; + data[id] = { 'mbtiles': mbtiles }; return id; @@ -93,26 +93,27 @@ module.exports = function(opts, callback) { serving.fonts[font] = true; })); } - if (item.raster !== false) { - app.use('/', serve_raster(options, serving.raster, item, id)); + if (item.serve_rendered !== false) { + app.use('/styles/' + id + '/', + serve_rendered(options, serving.rendered, item, id)); } }); if (Object.keys(serving.styles).length > 0) { // serve fonts only if serving some styles - app.use('/', serve_font(options, serving.fonts)); + app.use('/fonts/', serve_font(options, serving.fonts)); } app.use(cors()); - Object.keys(tiles).forEach(function(id) { - var item = tiles[id]; + Object.keys(data).forEach(function(id) { + var item = data[id]; if (!item.mbtiles || item.mbtiles.length == 0) { console.log('Missing "mbtiles" property for ' + id); return; } - app.use('/', serve_tiles(options, serving.tiles, item, id)); + app.use('/data/', serve_data(options, serving.data, item, id)); }); app.get('/styles.json', function(req, res, next) { @@ -139,14 +140,14 @@ module.exports = function(opts, callback) { return arr; }; - app.get('/raster.json', function(req, res, next) { - res.send(addTileJSONs([], req, 'raster')); + app.get('/rendered.json', function(req, res, next) { + res.send(addTileJSONs([], req, 'rendered')); }); app.get('/data.json', function(req, res, next) { - res.send(addTileJSONs([], req, 'tiles')); + res.send(addTileJSONs([], req, 'data')); }); app.get('/index.json', function(req, res, next) { - res.send(addTileJSONs(addTileJSONs([], req, 'raster'), req, 'tiles')); + res.send(addTileJSONs(addTileJSONs([], req, 'rendered'), req, 'data')); }); //------------------------------------ @@ -178,11 +179,11 @@ module.exports = function(opts, callback) { var styles = clone(config.styles || {}); Object.keys(styles).forEach(function(id) { var style = styles[id]; - style.name = (serving.styles[id] || serving.raster[id] || {}).name; - style.serving_style = serving.styles[id]; - style.serving_raster = serving.raster[id]; - if (style.serving_raster) { - var center = style.serving_raster.center; + style.name = (serving.styles[id] || serving.rendered[id] || {}).name; + style.serving_data = serving.styles[id]; + style.serving_rendered = serving.rendered[id]; + if (style.serving_rendered) { + var center = style.serving_rendered.center; if (center) { style.viewer_hash = '#' + center[2] + '/' + center[1].toFixed(5) + '/' + @@ -195,16 +196,24 @@ module.exports = function(opts, callback) { } } }); - var data = clone(serving.tiles || {}); + var data = clone(serving.data || {}); Object.keys(data).forEach(function(id) { - var tiles = data[id]; - var center = tiles.center; + var data_ = data[id]; + var center = data_.center; if (center) { - tiles.viewer_hash = '#' + center[2] + '/' + + data_.viewer_hash = '#' + center[2] + '/' + center[1].toFixed(5) + '/' + center[0].toFixed(5); } - tiles.is_vector = tiles.format == 'pbf'; + data_.is_vector = data_.format == 'pbf'; + if (!data_.is_vector) { + if (center) { + var centerPx = mercator.px([center[0], center[1]], center[2]); + data_.thumbnail = center[2] + '/' + + Math.floor(centerPx[0] / 256) + '/' + + Math.floor(centerPx[1] / 256) + '.' + data_.format; + } + } }); return { styles: styles, @@ -219,24 +228,26 @@ module.exports = function(opts, callback) { return null; } style.id = id; - style.name = (serving.styles[id] || serving.raster[id]).name; - style.serving_style = serving.styles[id]; - style.serving_raster = serving.raster[id]; + style.name = (serving.styles[id] || serving.rendered[id]).name; + style.serving_data = serving.styles[id]; + style.serving_rendered = serving.rendered[id]; return style; }); - app.use('/raster/:id/$', function(req, res, next) { + /* + app.use('/rendered/:id/$', function(req, res, next) { return res.redirect(301, '/styles/' + req.params.id + '/'); }); + */ serveTemplate('/data/:id/$', 'xray', function(params) { var id = params.id; - var tiles = serving.tiles[id]; - if (!tiles) { + var data = serving.data[id]; + if (!data) { return null; } - tiles.id = id; - return tiles; + data.id = id; + return data; }); var server = app.listen(process.env.PORT || opts.port, function() { diff --git a/test/metadata.js b/test/metadata.js index 20f40a9..2a9a3c5 100644 --- a/test/metadata.js +++ b/test/metadata.js @@ -40,7 +40,7 @@ var testTileJSON = function(url, basename) { describe('Metadata', function() { testTileJSONArray('/index.json'); - testTileJSONArray('/raster.json'); + testTileJSONArray('/rendered.json'); testTileJSONArray('/data.json'); describe('/styles.json is valid array', function() { @@ -64,6 +64,6 @@ describe('Metadata', function() { }); }); - testTileJSON('/raster/test.json', 'test'); + testTileJSON('/styles/test/rendered.json', 'test'); testTileJSON('/data/zurich-vector.json', 'zurich-vector'); }); diff --git a/test/static.js b/test/static.js index c3909bd..f41e7c7 100644 --- a/test/static.js +++ b/test/static.js @@ -1,6 +1,6 @@ var testStatic = function(prefix, q, format, status, scale, type) { if (scale) q += '@' + scale + 'x'; - var path = '/static/' + prefix + '/' + q + '.' + format; + var path = '/styles/' + prefix + '/rendered/static/' + q + '.' + format; it(path + ' returns ' + status, function(done) { var test = supertest(app).get(path); if (status) test.expect(status); diff --git a/test/tiles_vector.js b/test/tiles_data.js similarity index 100% rename from test/tiles_vector.js rename to test/tiles_data.js diff --git a/test/tiles_raster.js b/test/tiles_rendered.js similarity index 94% rename from test/tiles_raster.js rename to test/tiles_rendered.js index 6ec1b2a..987304f 100644 --- a/test/tiles_raster.js +++ b/test/tiles_rendered.js @@ -1,6 +1,6 @@ var testTile = function(prefix, z, x, y, format, status, scale, type) { if (scale) y += '@' + scale + 'x'; - var path = '/raster/' + prefix + '/' + z + '/' + x + '/' + y + '.' + format; + var path = '/styles/' + prefix + '/rendered/' + z + '/' + x + '/' + y + '.' + format; it(path + ' returns ' + status, function(done) { var test = supertest(app).get(path); test.expect(status);