Add xray viewer for vector data
This commit is contained in:
parent
c132d7fba8
commit
34befd43c9
6 changed files with 141 additions and 18 deletions
|
@ -43,7 +43,7 @@
|
||||||
<li>
|
<li>
|
||||||
<h3>{{name}}</h3>
|
<h3>{{name}}</h3>
|
||||||
<span>(id: {{@key}})</span>
|
<span>(id: {{@key}})</span>
|
||||||
<a href="/vector/{{@key}}/">X-Ray viewer</a>
|
<a href="/vector/{{@key}}/{{viewer_hash}}">X-Ray viewer</a>
|
||||||
<a href="/vector/{{@key}}.json">TileJSON</a>
|
<a href="/vector/{{@key}}.json">TileJSON</a>
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
102
public/templates/xray.tmpl
Normal file
102
public/templates/xray.tmpl
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>{{name}} - TileServer GL</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/mapbox-gl.css" />
|
||||||
|
<script src="/mapbox-gl.js"></script>
|
||||||
|
<style>
|
||||||
|
body {background:#000;color:#ccc;}
|
||||||
|
#map {position:absolute;top:0;left:0;right:250px;bottom:0;}
|
||||||
|
h1 {position:absolute;top:5px;right:0;width:240px;margin:0;line-height:20px;font-size:20px;}
|
||||||
|
#layerList {position:absolute;top:35px;right:0;bottom:50%;width:240px;overflow:auto;}
|
||||||
|
#layerList div div {width:15px;height:15px;display:inline-block;}
|
||||||
|
#propertyList {position:absolute;top:40%;bottom:0;right:0;width:240px;overflow:auto;color:#fff;}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<h1>{{name}}</h1>
|
||||||
|
<div id="map"></div>
|
||||||
|
<div id="layerList"></div>
|
||||||
|
<pre id="propertyList"></pre>
|
||||||
|
<script>
|
||||||
|
var map = new mapboxgl.Map({
|
||||||
|
container: 'map',
|
||||||
|
hash: true
|
||||||
|
});
|
||||||
|
map.addControl(new mapboxgl.Navigation());
|
||||||
|
|
||||||
|
function generateColor(str) {
|
||||||
|
var rgb = [0, 0, 0];
|
||||||
|
for (var i = 0; i < str.length; i++) {
|
||||||
|
var v = str.charCodeAt(i);
|
||||||
|
rgb[v % 3] = (rgb[i % 3] + (13*(v%13))) % 12;
|
||||||
|
}
|
||||||
|
var r = 4 + rgb[0];
|
||||||
|
var g = 4 + rgb[1];
|
||||||
|
var b = 4 + rgb[2];
|
||||||
|
r = (r * 16) + r;
|
||||||
|
g = (g * 16) + g;
|
||||||
|
b = (b * 16) + b;
|
||||||
|
return [r, g, b, 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
function initLayer(data) {
|
||||||
|
var layer;
|
||||||
|
var layerList = document.getElementById('layerList');
|
||||||
|
var layers_ = [];
|
||||||
|
data['vector_layers'].forEach(function(el) {
|
||||||
|
var color = generateColor(el['id']);
|
||||||
|
var colorText = 'rgba(' + color[0] + ',' + color[1] + ',' + color[2] + ',' + color[3] + ')';
|
||||||
|
layers_.push({
|
||||||
|
id: el['id'] + Math.random(),
|
||||||
|
source: 'vector_layer_',
|
||||||
|
'source-layer': el['id'],
|
||||||
|
interactive: true,
|
||||||
|
type: 'line',
|
||||||
|
paint: {'line-color': colorText}
|
||||||
|
});
|
||||||
|
var item = document.createElement('div');
|
||||||
|
item.innerHTML = '<div style="' +
|
||||||
|
'background:rgba(' + color[0] + ',' + color[1] + ',' + color[2] + ',1);' +
|
||||||
|
'"></div> ' + el['id'];
|
||||||
|
layerList.appendChild(item);
|
||||||
|
});
|
||||||
|
map.setStyle({
|
||||||
|
version: 8,
|
||||||
|
sources: {
|
||||||
|
'vector_layer_': {
|
||||||
|
type: 'vector',
|
||||||
|
tiles: data['tiles'],
|
||||||
|
minzoom: data['minzoom'],
|
||||||
|
maxzoom: data['maxzoom']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
layers: layers_
|
||||||
|
});
|
||||||
|
|
||||||
|
return layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
var xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.onreadystatechange = function() {
|
||||||
|
if (xhttp.readyState == 4 && xhttp.status == 200) {
|
||||||
|
initLayer(xhttp.response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhttp.responseType = 'json';
|
||||||
|
xhttp.open('GET', '/vector/{{id}}.json', true);
|
||||||
|
xhttp.send();
|
||||||
|
|
||||||
|
var propertyList = document.getElementById('propertyList');
|
||||||
|
map.on('mousemove', function(e) {
|
||||||
|
propertyList.innerHTML = '';
|
||||||
|
map.featuresAt(e.point, {radius: 3}, function(err, features) {
|
||||||
|
if (err) throw err;
|
||||||
|
if (features[0]) {
|
||||||
|
propertyList.innerHTML = JSON.stringify(features[0].properties, null, 2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -143,18 +143,7 @@ module.exports = function(options, repo, params, id) {
|
||||||
};
|
};
|
||||||
Object.assign(tileJSON, params.tilejson || {});
|
Object.assign(tileJSON, params.tilejson || {});
|
||||||
tileJSON.tiles = params.domains || options.domains;
|
tileJSON.tiles = params.domains || options.domains;
|
||||||
if (tileJSON.bounds && !tileJSON.center) {
|
utils.fixTileJSONCenter(tileJSON);
|
||||||
var fitWidth = 1024;
|
|
||||||
var tiles = fitWidth / 256;
|
|
||||||
tileJSON.center = [
|
|
||||||
(tileJSON.bounds[0] + tileJSON.bounds[2]) / 2,
|
|
||||||
(tileJSON.bounds[1] + tileJSON.bounds[3]) / 2,
|
|
||||||
Math.round(
|
|
||||||
-Math.log((tileJSON.bounds[2] - tileJSON.bounds[0]) / 360 / tiles) /
|
|
||||||
Math.LN2
|
|
||||||
)
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
var queue = [];
|
var queue = [];
|
||||||
Object.keys(styleJSON.sources).forEach(function(name) {
|
Object.keys(styleJSON.sources).forEach(function(name) {
|
||||||
|
|
|
@ -31,6 +31,7 @@ module.exports = function(options, repo, params, id) {
|
||||||
tileJSON['format'] = 'pbf';
|
tileJSON['format'] = 'pbf';
|
||||||
|
|
||||||
Object.assign(tileJSON, params.tilejson || {});
|
Object.assign(tileJSON, params.tilejson || {});
|
||||||
|
utils.fixTileJSONCenter(tileJSON);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -153,10 +153,6 @@ module.exports = function(opts, callback) {
|
||||||
// serve web presentations
|
// serve web presentations
|
||||||
app.use('/', express.static(path.join(__dirname, '../public/resources')));
|
app.use('/', express.static(path.join(__dirname, '../public/resources')));
|
||||||
|
|
||||||
handlebars.registerHelper('json', function(context) {
|
|
||||||
return JSON.stringify(context);
|
|
||||||
});
|
|
||||||
|
|
||||||
var templates = path.join(__dirname, '../public/templates');
|
var templates = path.join(__dirname, '../public/templates');
|
||||||
var serveTemplate = function(path, template, dataGetter) {
|
var serveTemplate = function(path, template, dataGetter) {
|
||||||
fs.readFile(templates + '/' + template + '.tmpl', function(err, content) {
|
fs.readFile(templates + '/' + template + '.tmpl', function(err, content) {
|
||||||
|
@ -199,9 +195,19 @@ module.exports = function(opts, callback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
var data = clone(serving.vector || {});
|
||||||
|
Object.keys(data).forEach(function(id) {
|
||||||
|
var vector = data[id];
|
||||||
|
var center = vector.center;
|
||||||
|
if (center) {
|
||||||
|
vector.viewer_hash = '#' + center[2] + '/' +
|
||||||
|
center[1].toFixed(5) + '/' +
|
||||||
|
center[0].toFixed(5);
|
||||||
|
}
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
styles: styles,
|
styles: styles,
|
||||||
data: serving.vector
|
data: data
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -222,6 +228,16 @@ module.exports = function(opts, callback) {
|
||||||
return res.redirect(301, '/styles/' + req.params.id + '/');
|
return res.redirect(301, '/styles/' + req.params.id + '/');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
serveTemplate('/vector/:id/', 'xray', function(params) {
|
||||||
|
var id = params.id;
|
||||||
|
var vector = serving.vector[id];
|
||||||
|
if (!vector) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
vector.id = id;
|
||||||
|
return vector;
|
||||||
|
});
|
||||||
|
|
||||||
var server = app.listen(process.env.PORT || opts.port, function() {
|
var server = app.listen(process.env.PORT || opts.port, function() {
|
||||||
console.log('Listening at http://%s:%d/',
|
console.log('Listening at http://%s:%d/',
|
||||||
this.address().address, this.address().port);
|
this.address().address, this.address().port);
|
||||||
|
|
15
src/utils.js
15
src/utils.js
|
@ -22,3 +22,18 @@ module.exports.getTileUrls = function(req, domains, path, format) {
|
||||||
|
|
||||||
return uris;
|
return uris;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module.exports.fixTileJSONCenter = function(tileJSON) {
|
||||||
|
if (tileJSON.bounds && !tileJSON.center) {
|
||||||
|
var fitWidth = 1024;
|
||||||
|
var tiles = fitWidth / 256;
|
||||||
|
tileJSON.center = [
|
||||||
|
(tileJSON.bounds[0] + tileJSON.bounds[2]) / 2,
|
||||||
|
(tileJSON.bounds[1] + tileJSON.bounds[3]) / 2,
|
||||||
|
Math.round(
|
||||||
|
-Math.log((tileJSON.bounds[2] - tileJSON.bounds[0]) / 360 / tiles) /
|
||||||
|
Math.LN2
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in a new issue