Merge d790c684f2 into bcac161a25
This commit is contained in:
commit
19cb2f6b8d
10 changed files with 76 additions and 48 deletions
|
|
@ -66,6 +66,16 @@ The value of ``root`` is used as prefix for all data types.
|
|||
|
||||
You can use this to optionally specify on what domains the rendered tiles are accessible. This can be used for basic load-balancing or to bypass browser's limit for the number of connections per domain.
|
||||
|
||||
``baseURL``
|
||||
-----------
|
||||
|
||||
When you run the tile server server behind a load-balancer, the automatic URL generators wont't have the required information to build URLs which point to the correct LB endpoint.
|
||||
|
||||
Also, if your load balancer is forwarding a HTTPS connection to the non-HTTPS ``tileserver-gl``, setting the ``baseURL`` is indispensable.
|
||||
|
||||
Not compatible with the ``domains`` option.
|
||||
|
||||
|
||||
``formatQuality``
|
||||
-----------------
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
@font-face {
|
||||
font-family: 'OpenSans';
|
||||
src: url('/fonts/OpenSans-Regular.ttf');
|
||||
src: url('fonts/OpenSans-Regular.ttf');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'OpenSans';
|
||||
src: url('/fonts/OpenSans-Italic.ttf');
|
||||
src: url('fonts/OpenSans-Italic.ttf');
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'OpenSans';
|
||||
src: url('/fonts/OpenSans-Bold.ttf');
|
||||
src: url('fonts/OpenSans-Bold.ttf');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
|
@ -149,21 +149,21 @@ footer a {
|
|||
body {
|
||||
background-repeat:no-repeat !important;
|
||||
background-size: contain !important;
|
||||
background-image: url(/images/header-map-640px.png);
|
||||
background-image: url(images/header-map-640px.png);
|
||||
}
|
||||
@media only screen and (min-width: 641px) {
|
||||
body {
|
||||
background-image: url(/images/header-map-1280px.png);
|
||||
background-image: url(images/header-map-1280px.png);
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 1281px) {
|
||||
body {
|
||||
background-image: url(/images/header-map-1600px.png);
|
||||
background-image: url(images/header-map-1600px.png);
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 1601px) {
|
||||
body {
|
||||
background-image: url(/images/header-map-2560px.png);
|
||||
background-image: url(images/header-map-2560px.png);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -209,4 +209,4 @@ body {
|
|||
.btn:first-child{
|
||||
padding: 0 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{name}} - TileServer GL</title>
|
||||
{{#is_vector}}
|
||||
<link rel="stylesheet" type="text/css" href="/mapbox-gl.css{{&key_query}}" />
|
||||
<script src="/mapbox-gl.js{{&key_query}}"></script>
|
||||
<link rel="stylesheet" type="text/css" href="{{baseURL}}/mapbox-gl.css{{&key_query}}" />
|
||||
<script src="{{baseURL}}/mapbox-gl.js{{&key_query}}"></script>
|
||||
<style>
|
||||
body {background:#000;color:#ccc;}
|
||||
#map {position:absolute;top:0;left:0;right:250px;bottom:0;}
|
||||
|
|
@ -17,9 +17,9 @@
|
|||
</style>
|
||||
{{/is_vector}}
|
||||
{{^is_vector}}
|
||||
<link rel="stylesheet" type="text/css" href="/mapbox.css{{&key_query}}" />
|
||||
<script src="/mapbox.js{{&key_query}}"></script>
|
||||
<script src="/leaflet-hash.js{{&key_query}}"></script>
|
||||
<link rel="stylesheet" type="text/css" href="{{baseURL}}/mapbox.css{{&key_query}}" />
|
||||
<script src="{{baseURL}}/mapbox.js{{&key_query}}"></script>
|
||||
<script src="{{baseURL}}/leaflet-hash.js{{&key_query}}"></script>
|
||||
<style>
|
||||
body { margin:0; padding:0; }
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
|
|
@ -108,7 +108,7 @@
|
|||
}
|
||||
};
|
||||
xhttp.responseType = 'json';
|
||||
xhttp.open('GET', '/data/{{id}}.json{{&key_query}}', true);
|
||||
xhttp.open('GET', '{{baseURL}}/data/{{id}}.json{{&key_query}}', true);
|
||||
xhttp.send();
|
||||
|
||||
var propertyList = document.getElementById('propertyList');
|
||||
|
|
@ -133,7 +133,7 @@
|
|||
<h1 style="display:none;">{{name}}</h1>
|
||||
<div id='map'></div>
|
||||
<script>
|
||||
var map = L.mapbox.map('map', '/data/{{id}}.json{{&key_query}}', { zoomControl: false });
|
||||
var map = L.mapbox.map('map', '{{baseURL}}/data/{{id}}.json{{&key_query}}', { zoomControl: false });
|
||||
map.eachLayer(function(layer) {
|
||||
// do not add scale prefix even if retina display is detected
|
||||
layer.scalePrefix = '.';
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>TileServer GL - Server for vector and raster maps with GL styles</title>
|
||||
<link rel="stylesheet" type="text/css" href="/index.css{{&key_query}}" />
|
||||
<link rel="stylesheet" type="text/css" href="{{baseURL}}/index.css{{&key_query}}" />
|
||||
<script>
|
||||
function toggle_xyz(id) {
|
||||
var el = document.getElementById(id);
|
||||
|
|
@ -17,23 +17,23 @@
|
|||
</head>
|
||||
<body>
|
||||
<section>
|
||||
<h1 class="title {{#if is_light}}light{{/if}}"><img src="/images/logo.png" alt="TileServer GL" /></h1>
|
||||
<h1 class="title {{#if is_light}}light{{/if}}"><img src="{{baseURL}}/images/logo.png" alt="TileServer GL" /></h1>
|
||||
<h2 class="subtitle">Vector {{#if is_light}}<s>and raster</s>{{else}}and raster{{/if}} maps with GL styles</h2>
|
||||
<h2 class="box-header">Styles</h2>
|
||||
<div class="box">
|
||||
{{#each styles}}
|
||||
<div class="item">
|
||||
{{#if thumbnail}}
|
||||
<img src="/styles/{{@key}}/rendered/{{thumbnail}}{{&../key_query}}" alt="{{name}} preview" />
|
||||
<img src="{{baseURL}}/styles/{{@key}}/rendered/{{thumbnail}}{{&../key_query}}" alt="{{name}} preview" />
|
||||
{{else}}
|
||||
<img src="/images/placeholder.png" alt="{{name}} preview" />
|
||||
<img src="{{baseURL}}/images/placeholder.png" alt="{{name}} preview" />
|
||||
{{/if}}
|
||||
<div class="details">
|
||||
<h3>{{name}}</h3>
|
||||
<p class="identifier">identifier: {{@key}}</p>
|
||||
<p class="services">
|
||||
{{#if serving_rendered}}
|
||||
services: <a href="/styles/{{@key}}/rendered.json{{&../key_query}}">TileJSON</a>
|
||||
services: <a href="{{baseURL}}/styles/{{@key}}/rendered.json{{&../key_query}}">TileJSON</a>
|
||||
{{/if}}
|
||||
{{#if wmts_link}}
|
||||
| <a href="{{&wmts_link}}">WMTS</a>
|
||||
|
|
@ -47,14 +47,14 @@
|
|||
<div class="viewers">
|
||||
{{#if serving_data}}
|
||||
{{#if serving_rendered}}
|
||||
<a class="btn" href="/styles/{{@key}}/{{&../key_query}}{{viewer_hash}}">Viewer</a>
|
||||
<a class="btn" href="{{baseURL}}/styles/{{@key}}/{{&../key_query}}{{viewer_hash}}">Viewer</a>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if serving_rendered}}
|
||||
<a class="btn" href="/styles/{{@key}}/?{{&../key_query_part}}raster{{viewer_hash}}">Raster</a>
|
||||
<a class="btn" href="{{baseURL}}/styles/{{@key}}/?{{&../key_query_part}}raster{{viewer_hash}}">Raster</a>
|
||||
{{/if}}
|
||||
{{#if serving_data}}
|
||||
<a class="btn" href="/styles/{{@key}}/?{{&../key_query_part}}vector{{viewer_hash}}">Vector</a>
|
||||
<a class="btn" href="{{baseURL}}/styles/{{@key}}/?{{&../key_query_part}}vector{{viewer_hash}}">Vector</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -65,15 +65,15 @@
|
|||
{{#each data}}
|
||||
<div class="item">
|
||||
{{#if thumbnail}}
|
||||
<img src="/data/{{@key}}/{{thumbnail}}{{&../key_query}}" alt="{{name}} preview" />
|
||||
<img src="{{baseURL}}/data/{{@key}}/{{thumbnail}}{{&../key_query}}" alt="{{name}} preview" />
|
||||
{{else}}
|
||||
<img src="/images/placeholder.png" alt="{{name}} preview" />
|
||||
<img src="{{baseURL}}/images/placeholder.png" alt="{{name}} preview" />
|
||||
{{/if}}
|
||||
<div class="details">
|
||||
<h3>{{name}}</h3>
|
||||
<p class="identifier">identifier: {{@key}}{{#if formatted_filesize}} | size: {{formatted_filesize}}{{/if}} | type: {{#is_vector}}vector{{/is_vector}}{{^is_vector}}raster{{/is_vector}} data</p>
|
||||
<p class="services">
|
||||
services: <a href="/data/{{@key}}.json{{&../key_query}}">TileJSON</a>
|
||||
services: <a href="{{baseURL}}/data/{{@key}}.json{{&../key_query}}">TileJSON</a>
|
||||
{{#if wmts_link}}
|
||||
| <a href="{{&wmts_link}}">WMTS</a>
|
||||
{{/if}}
|
||||
|
|
@ -85,10 +85,10 @@
|
|||
</div>
|
||||
<div class="viewers">
|
||||
{{#is_vector}}
|
||||
<a class="btn" href="/data/{{@key}}/{{&../key_query}}{{viewer_hash}}">X-Ray view</a>
|
||||
<a class="btn" href="{{baseURL}}/data/{{@key}}/{{&../key_query}}{{viewer_hash}}">X-Ray view</a>
|
||||
{{/is_vector}}
|
||||
{{^is_vector}}
|
||||
<a class="btn" href="/data/{{@key}}/{{&../key_query}}{{viewer_hash}}">Raster view</a>
|
||||
<a class="btn" href="{{baseURL}}/data/{{@key}}/{{&../key_query}}{{viewer_hash}}">Raster view</a>
|
||||
{{/is_vector}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -96,7 +96,7 @@
|
|||
</div>
|
||||
</section>
|
||||
<footer>
|
||||
<a href="https://www.klokantech.com/" target="_blank"><img src="/images/klokantech.png" /></a>
|
||||
<a href="https://www.klokantech.com/" target="_blank"><img src="{{baseURL}}/images/klokantech.png" /></a>
|
||||
<p>
|
||||
<a href="https://github.com/klokantech/tileserver-gl" target="_blank">Powered by TileServer GL ({{server_version}})</a> – <a href="https://www.klokantech.com/" target="_blank">open-source project from Klokan Technologies GmbH.</a>
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{name}} - TileServer GL</title>
|
||||
<link rel="stylesheet" type="text/css" href="/mapbox-gl.css{{&key_query}}" />
|
||||
<script src="/mapbox-gl.js{{&key_query}}"></script>
|
||||
<link rel="stylesheet" type="text/css" href="{{baseURL}}/mapbox-gl.css{{&key_query}}" />
|
||||
<script src="{{baseURL}}/mapbox-gl.js{{&key_query}}"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/mapbox.css{{&key_query}}" />
|
||||
<script src="/mapbox.js{{&key_query}}"></script>
|
||||
<script src="/leaflet-hash.js{{&key_query}}"></script>
|
||||
<script src="{{baseURL}}/mapbox.js{{&key_query}}"></script>
|
||||
<script src="{{baseURL}}/leaflet-hash.js{{&key_query}}"></script>
|
||||
<style>
|
||||
body { margin:0; padding:0; }
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
|
|
@ -26,12 +26,12 @@
|
|||
if (preference == 'vector') {
|
||||
var map = new mapboxgl.Map({
|
||||
container: 'map',
|
||||
style: '/styles/{{id}}.json{{&key_query}}',
|
||||
style: '{{baseURL}}/styles/{{id}}.json{{&key_query}}',
|
||||
hash: true
|
||||
});
|
||||
map.addControl(new mapboxgl.Navigation());
|
||||
} else {
|
||||
var map = L.mapbox.map('map', '/styles/{{id}}/rendered.json{{&key_query}}', { zoomControl: false });
|
||||
var map = L.mapbox.map('map', '{{baseURL}}/styles/{{id}}/rendered.json{{&key_query}}', { zoomControl: false });
|
||||
new L.Control.Zoom({ position: 'topright' }).addTo(map);
|
||||
setTimeout(function() {
|
||||
new L.Hash(map);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ module.exports = function(options, repo, params, id) {
|
|||
var app = express().disable('x-powered-by');
|
||||
|
||||
var mbtilesFile = path.resolve(options.paths.mbtiles, params.mbtiles);
|
||||
var baseURL = options.baseURL;
|
||||
var tileJSON = {
|
||||
'tiles': params.domains || options.domains
|
||||
};
|
||||
|
|
@ -81,7 +82,7 @@ module.exports = function(options, repo, params, id) {
|
|||
app.get('/' + id + '.json', function(req, res, next) {
|
||||
var info = clone(tileJSON);
|
||||
info.tiles = utils.getTileUrls(req, info.tiles,
|
||||
'data/' + id, info.format);
|
||||
'data/' + id, info.format, baseURL);
|
||||
return res.send(info);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ module.exports = function(options, repo, params, id, dataResolver) {
|
|||
var lastModified = new Date().toUTCString();
|
||||
|
||||
var rootPath = options.paths.root;
|
||||
var baseURL = options.baseURL;
|
||||
|
||||
var styleFile = params.style;
|
||||
var map = {
|
||||
|
|
@ -564,7 +565,7 @@ module.exports = function(options, repo, params, id, dataResolver) {
|
|||
app.get('/rendered.json', function(req, res, next) {
|
||||
var info = clone(tileJSON);
|
||||
info.tiles = utils.getTileUrls(req, info.tiles,
|
||||
'styles/' + id + '/rendered', info.format);
|
||||
'styles/' + id + '/rendered', info.format, baseURL);
|
||||
return res.send(info);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ module.exports = function(options, repo, params, id, reportTiles, reportFont) {
|
|||
|
||||
var styleFile = path.join(options.paths.styles, params.style);
|
||||
|
||||
var baseURL = options.baseURL;
|
||||
|
||||
var styleJSON = clone(require(styleFile));
|
||||
Object.keys(styleJSON.sources).forEach(function(name) {
|
||||
var source = styleJSON.sources[name];
|
||||
|
|
@ -57,8 +59,8 @@ module.exports = function(options, repo, params, id, reportTiles, reportFont) {
|
|||
if (!opt_nokey && req.query.key) {
|
||||
query = '?key=' + req.query.key;
|
||||
}
|
||||
return url.replace(
|
||||
'local://', req.protocol + '://' + req.headers.host + '/') + query;
|
||||
return url.replace('local://',
|
||||
(baseURL ? baseURL : req.protocol + '://' + req.headers.host) + '/') + query;
|
||||
};
|
||||
|
||||
var styleJSON_ = clone(styleJSON);
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ module.exports = function(opts, callback) {
|
|||
}
|
||||
|
||||
var options = config.options || {};
|
||||
var baseURL = options.baseURL;
|
||||
|
||||
var paths = options.paths || {};
|
||||
options.paths = paths;
|
||||
paths.root = path.resolve(
|
||||
|
|
@ -165,7 +167,7 @@ module.exports = function(opts, callback) {
|
|||
version: styleJSON.version,
|
||||
name: styleJSON.name,
|
||||
id: id,
|
||||
url: req.protocol + '://' + req.headers.host +
|
||||
url: (baseURL ? baseURL : req.protocol + '://' + req.headers.host) +
|
||||
'/styles/' + id + '.json' + query
|
||||
});
|
||||
});
|
||||
|
|
@ -176,7 +178,7 @@ module.exports = function(opts, callback) {
|
|||
Object.keys(serving[type]).forEach(function(id) {
|
||||
var info = clone(serving[type][id]);
|
||||
info.tiles = utils.getTileUrls(req, info.tiles,
|
||||
type + '/' + id, info.format);
|
||||
type + '/' + id, info.format, baseURL);
|
||||
arr.push(info);
|
||||
});
|
||||
return arr;
|
||||
|
|
@ -224,6 +226,7 @@ module.exports = function(opts, callback) {
|
|||
|
||||
serveTemplate('/$', 'index', function(req) {
|
||||
var styles = clone(config.styles || {});
|
||||
|
||||
Object.keys(styles).forEach(function(id) {
|
||||
var style = styles[id];
|
||||
style.name = (serving.styles[id] || serving.rendered[id] || {}).name;
|
||||
|
|
@ -247,10 +250,12 @@ module.exports = function(opts, callback) {
|
|||
base64url('http://' + req.headers.host +
|
||||
'/styles/' + id + '/rendered.json' + query) + '/wmts';
|
||||
|
||||
|
||||
var tiles = utils.getTileUrls(
|
||||
req, style.serving_rendered.tiles,
|
||||
'styles/' + id + '/rendered', style.serving_rendered.format);
|
||||
'styles/' + id + '/rendered', style.serving_rendered.format, baseURL);
|
||||
style.xyz_link = tiles[0];
|
||||
style.baseURL = baseURL;
|
||||
}
|
||||
});
|
||||
var data = clone(serving.data || {});
|
||||
|
|
@ -277,7 +282,7 @@ module.exports = function(opts, callback) {
|
|||
'/data/' + id + '.json' + query) + '/wmts';
|
||||
|
||||
var tiles = utils.getTileUrls(
|
||||
req, data_.tiles, 'data/' + id, data_.format);
|
||||
req, data_.tiles, 'data/' + id, data_.format, baseURL);
|
||||
data_.xyz_link = tiles[0];
|
||||
}
|
||||
if (data_.filesize) {
|
||||
|
|
@ -292,11 +297,13 @@ module.exports = function(opts, callback) {
|
|||
size /= 1024;
|
||||
}
|
||||
data_.formatted_filesize = size.toFixed(2) + ' ' + suffix;
|
||||
data_.baseURL = baseURL;
|
||||
}
|
||||
});
|
||||
return {
|
||||
styles: styles,
|
||||
data: data
|
||||
data: data,
|
||||
baseURL: baseURL
|
||||
};
|
||||
});
|
||||
|
||||
|
|
@ -310,6 +317,7 @@ module.exports = function(opts, callback) {
|
|||
style.name = (serving.styles[id] || serving.rendered[id]).name;
|
||||
style.serving_data = serving.styles[id];
|
||||
style.serving_rendered = serving.rendered[id];
|
||||
style.baseURL = baseURL;
|
||||
return style;
|
||||
});
|
||||
|
||||
|
|
@ -327,6 +335,8 @@ module.exports = function(opts, callback) {
|
|||
}
|
||||
data.id = id;
|
||||
data.is_vector = data.format == 'pbf';
|
||||
|
||||
data.baseURL = baseURL;
|
||||
return data;
|
||||
});
|
||||
|
||||
|
|
|
|||
12
src/utils.js
12
src/utils.js
|
|
@ -6,20 +6,24 @@ var async = require('async'),
|
|||
|
||||
var glyphCompose = require('glyph-pbf-composite');
|
||||
|
||||
module.exports.getTileUrls = function(req, domains, path, format) {
|
||||
module.exports.getTileUrls = function(req, domains, path, format, baseURL) {
|
||||
var key = req.query.key;
|
||||
var query = (key && key.length > 0) ? ('?key=' + key) : '';
|
||||
|
||||
if (baseURL) {
|
||||
return [baseURL + '/' + path + '/{z}/{x}/{y}.' + format + query]
|
||||
}
|
||||
|
||||
if (domains) {
|
||||
if (domains.constructor === String && domains.length > 0) {
|
||||
domains = domains.split(',');
|
||||
}
|
||||
|
||||
}
|
||||
if (!domains || domains.length == 0) {
|
||||
domains = [req.headers.host];
|
||||
}
|
||||
|
||||
var key = req.query.key;
|
||||
var query = (key && key.length > 0) ? ('?key=' + key) : '';
|
||||
|
||||
var uris = [];
|
||||
domains.forEach(function(domain) {
|
||||
uris.push(req.protocol + '://' + domain + '/' + path +
|
||||
|
|
|
|||
Loading…
Reference in a new issue