Change endpoint URLs (close #154)

- styles at /style/{id}/style.json
- rendered tiles at /style/{id}/{z}/{x}/{y}.{format}
- TileJSONs at /style/{id}.json
This commit is contained in:
Petr Sloup 2017-06-22 16:36:08 +02:00
parent 8007f1386c
commit 698c527e94
9 changed files with 26 additions and 26 deletions

View file

@ -6,18 +6,18 @@ If you visit the server on the configured port (default 8080) you can see your m
Styles Styles
====== ======
* Styles are served at ``/styles/{id}.json`` (+ array at ``/styles.json``) * Styles are served at ``/styles/{id}/style.json`` (+ array at ``/styles.json``)
* Sprites at ``/styles/{id}/sprite[@2x].{format}`` * Sprites at ``/styles/{id}/sprite[@2x].{format}``
* Fonts at ``/fonts/{fontstack}/{start}-{end}.pbf`` * Fonts at ``/fonts/{fontstack}/{start}-{end}.pbf``
Rendered tiles Rendered tiles
============== ==============
* Rendered tiles are served at ``/styles/{id}/rendered/{z}/{x}/{y}[@2x].{format}`` * Rendered tiles are served at ``/styles/{id}/{z}/{x}/{y}[@2x].{format}``
* The optional ``@2x`` (or ``@3x``, ``@4x``) part can be used to render HiDPI (retina) tiles * The optional ``@2x`` (or ``@3x``, ``@4x``) part can be used to render HiDPI (retina) tiles
* Available formats: ``png``, ``jpg`` (``jpeg``), ``webp`` * Available formats: ``png``, ``jpg`` (``jpeg``), ``webp``
* TileJSON at ``/styles/{id}/rendered.json`` * TileJSON at ``/styles/{id}.json``
* The rendered tiles are not available in the ``tileserver-gl-light`` version. * The rendered tiles are not available in the ``tileserver-gl-light`` version.

View file

@ -25,7 +25,7 @@
{{#each styles}} {{#each styles}}
<div class="item"> <div class="item">
{{#if thumbnail}} {{#if thumbnail}}
<img src="/styles/{{@key}}/rendered/{{thumbnail}}{{&../key_query}}" alt="{{name}} preview" /> <img src="/styles/{{@key}}/{{thumbnail}}{{&../key_query}}" alt="{{name}} preview" />
{{else}} {{else}}
<img src="/images/placeholder.png" alt="{{name}} preview" /> <img src="/images/placeholder.png" alt="{{name}} preview" />
{{/if}} {{/if}}
@ -35,10 +35,10 @@
<p class="services"> <p class="services">
services: services:
{{#if serving_data}} {{#if serving_data}}
<a href="/styles/{{@key}}.json{{&../key_query}}">GL Style</a> <a href="/styles/{{@key}}/style.json{{&../key_query}}">GL Style</a>
{{/if}} {{/if}}
{{#if serving_rendered}} {{#if serving_rendered}}
{{#if serving_data}}| {{/if}}<a href="/styles/{{@key}}/rendered.json{{&../key_query}}">TileJSON</a> {{#if serving_data}}| {{/if}}<a href="/styles/{{@key}}.json{{&../key_query}}">TileJSON</a>
{{/if}} {{/if}}
{{#if wmts_link}} {{#if wmts_link}}
| <a href="{{&wmts_link}}">WMTS</a> | <a href="{{&wmts_link}}">WMTS</a>

View file

@ -27,12 +27,12 @@
mapboxgl.setRTLTextPlugin('/mapbox-gl-rtl-text.js{{&key_query}}'); mapboxgl.setRTLTextPlugin('/mapbox-gl-rtl-text.js{{&key_query}}');
var map = new mapboxgl.Map({ var map = new mapboxgl.Map({
container: 'map', container: 'map',
style: '/styles/{{id}}.json{{&key_query}}', style: '/styles/{{id}}/style.json{{&key_query}}',
hash: true hash: true
}); });
map.addControl(new mapboxgl.NavigationControl()); map.addControl(new mapboxgl.NavigationControl());
} else { } else {
var map = L.mapbox.map('map', '/styles/{{id}}/rendered.json{{&key_query}}', { zoomControl: false }); var map = L.mapbox.map('map', '/styles/{{id}}.json{{&key_query}}', { zoomControl: false });
new L.Control.Zoom({ position: 'topright' }).addTo(map); new L.Control.Zoom({ position: 'topright' }).addTo(map);
setTimeout(function() { setTimeout(function() {
new L.Hash(map); new L.Hash(map);

View file

@ -310,7 +310,7 @@ module.exports = function(options, repo, params, id, dataResolver) {
repo[id] = tileJSON; repo[id] = tileJSON;
var tilePattern = '/rendered/:z(\\d+)/:x(\\d+)/:y(\\d+)' + var tilePattern = '/' + id + '/:z(\\d+)/:x(\\d+)/:y(\\d+)' +
':scale(' + scalePattern + ')?\.:format([\\w]+)'; ':scale(' + scalePattern + ')?\.:format([\\w]+)';
var respondImage = function(z, lon, lat, bearing, pitch, var respondImage = function(z, lon, lat, bearing, pitch,
@ -544,7 +544,7 @@ module.exports = function(options, repo, params, id, dataResolver) {
if (options.serveStaticMaps !== false) { if (options.serveStaticMaps !== false) {
var staticPattern = var staticPattern =
'/static/:raw(raw)?/%s/:width(\\d+)x:height(\\d+)' + '/' + id + '/static/:raw(raw)?/%s/:width(\\d+)x:height(\\d+)' +
':scale(' + scalePattern + ')?\.:format([\\w]+)'; ':scale(' + scalePattern + ')?\.:format([\\w]+)';
var centerPattern = var centerPattern =
@ -628,7 +628,7 @@ module.exports = function(options, repo, params, id, dataResolver) {
app.get(util.format(staticPattern, boundsPattern), serveBounds); app.get(util.format(staticPattern, boundsPattern), serveBounds);
app.get('/static/', function(req, res, next) { app.get('/' + id + '/static/', function(req, res, next) {
for (var key in req.query) { for (var key in req.query) {
req.query[key.toLowerCase()] = req.query[key]; req.query[key.toLowerCase()] = req.query[key];
} }
@ -694,10 +694,10 @@ module.exports = function(options, repo, params, id, dataResolver) {
}); });
} }
app.get('/rendered.json', function(req, res, next) { app.get('/' + id + '.json', function(req, res, next) {
var info = clone(tileJSON); var info = clone(tileJSON);
info.tiles = utils.getTileUrls(req, info.tiles, info.tiles = utils.getTileUrls(req, info.tiles,
'styles/' + id + '/rendered', info.format); 'styles/' + id, info.format);
return res.send(info); return res.send(info);
}); });

View file

@ -62,7 +62,7 @@ module.exports = function(options, repo, params, id, reportTiles, reportFont) {
repo[id] = styleJSON; repo[id] = styleJSON;
app.get('/' + id + '.json', function(req, res, next) { app.get('/' + id + '/style.json', function(req, res, next) {
var fixUrl = function(url, opt_nokey, opt_nostyle) { var fixUrl = function(url, opt_nokey, opt_nostyle) {
if (!url || (typeof url !== 'string') || url.indexOf('local://') !== 0) { if (!url || (typeof url !== 'string') || url.indexOf('local://') !== 0) {
return url; return url;

View file

@ -150,7 +150,7 @@ function start(opts) {
return mbtilesFile; return mbtilesFile;
} }
).then(function(sub) { ).then(function(sub) {
app.use('/styles/' + id + '/', sub); app.use('/styles/', sub);
}) })
); );
} else { } else {
@ -189,7 +189,7 @@ function start(opts) {
name: styleJSON.name, name: styleJSON.name,
id: id, id: id,
url: req.protocol + '://' + req.headers.host + url: req.protocol + '://' + req.headers.host +
'/styles/' + id + '.json' + query '/styles/' + id + '/style.json' + query
}); });
}); });
res.send(result); res.send(result);
@ -200,7 +200,7 @@ function start(opts) {
var info = clone(serving[type][id]); var info = clone(serving[type][id]);
var path = ''; var path = '';
if (type == 'rendered') { if (type == 'rendered') {
path = 'styles/' + id + '/rendered'; path = 'styles/' + id;
} else { } else {
path = type + '/' + id; path = type + '/' + id;
} }
@ -288,11 +288,11 @@ function start(opts) {
var query = req.query.key ? ('?key=' + req.query.key) : ''; var query = req.query.key ? ('?key=' + req.query.key) : '';
style.wmts_link = 'http://wmts.maptiler.com/' + style.wmts_link = 'http://wmts.maptiler.com/' +
base64url('http://' + req.headers.host + base64url('http://' + req.headers.host +
'/styles/' + id + '/rendered.json' + query) + '/wmts'; '/styles/' + id + '.json' + query) + '/wmts';
var tiles = utils.getTileUrls( var tiles = utils.getTileUrls(
req, style.serving_rendered.tiles, req, style.serving_rendered.tiles,
'styles/' + id + '/rendered', style.serving_rendered.format); 'styles/' + id, style.serving_rendered.format);
style.xyz_link = tiles[0]; style.xyz_link = tiles[0];
} }
}); });

View file

@ -71,6 +71,6 @@ describe('Metadata', function() {
}); });
}); });
testTileJSON('/styles/test-style/rendered.json'); testTileJSON('/styles/test-style.json');
testTileJSON('/data/openmaptiles.json'); testTileJSON('/data/openmaptiles.json');
}); });

View file

@ -11,12 +11,12 @@ var testIs = function(url, type, status) {
var prefix = 'test-style'; var prefix = 'test-style';
describe('Styles', function() { describe('Styles', function() {
describe('/styles/' + prefix + '.json is valid style', function() { describe('/styles/' + prefix + '/style.json is valid style', function() {
testIs('/styles/' + prefix + '.json', /application\/json/); testIs('/styles/' + prefix + '/style.json', /application\/json/);
it('contains expected properties', function(done) { it('contains expected properties', function(done) {
supertest(app) supertest(app)
.get('/styles/' + prefix + '.json') .get('/styles/' + prefix + '/style.json')
.expect(function(res) { .expect(function(res) {
res.body.version.should.equal(8); res.body.version.should.equal(8);
res.body.name.should.be.String(); res.body.name.should.be.String();
@ -27,8 +27,8 @@ describe('Styles', function() {
}).end(done); }).end(done);
}); });
}); });
describe('/styles/streets.json is not served', function() { describe('/styles/streets/style.json is not served', function() {
testIs('/styles/streets.json', /./, 404); testIs('/styles/streets/style.json', /./, 404);
}); });
describe('/styles/' + prefix + '/sprite[@2x].{format}', function() { describe('/styles/' + prefix + '/sprite[@2x].{format}', function() {

View file

@ -1,6 +1,6 @@
var testTile = function(prefix, z, x, y, format, status, scale, type) { var testTile = function(prefix, z, x, y, format, status, scale, type) {
if (scale) y += '@' + scale + 'x'; if (scale) y += '@' + scale + 'x';
var path = '/styles/' + prefix + '/rendered/' + z + '/' + x + '/' + y + '.' + format; var path = '/styles/' + prefix + '/' + z + '/' + x + '/' + y + '.' + format;
it(path + ' returns ' + status, function(done) { it(path + ' returns ' + status, function(done) {
var test = supertest(app).get(path); var test = supertest(app).get(path);
test.expect(status); test.expect(status);