Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions docs/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,26 @@ For example::
}
}


The data source does not need to be specified here unless you explicitly want to serve the raw data.

Serving Terrain Tiles
--------------

If you serve terrain tiles, it is possible to configure an ``encoding`` with ``mapbox`` or ``terrarium`` to enable a terrain preview mode and the ``elevation`` api for the ``data`` endpoint.

For example::

"data": {
"terrain1": {
"mbtiles": "terrain1.mbtiles",
"encoding": "mapbox"
},
"terrain2": {
"pmtiles": "terrain2.pmtiles"
"encoding": "terrarium"
}
}

Referencing local files from style JSON
=======================================

Expand Down Expand Up @@ -283,7 +300,7 @@ For example::
"source3": {
"url": "pmtiles://https://foo.lan/source3.pmtiles",
"type": "vector"
},
}
}

Alternatively, you can use ``pmtiles://{source2}`` to reference existing data object from the config.
Expand Down
8 changes: 8 additions & 0 deletions docs/endpoints.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ Source data

* TileJSON at ``/data/{id}.json``

* If terrain mbtile data is served and ``encoding`` is configured (see config) the elevation can be queried

* by ``/data/{id}/elevation/{z}/{x}/{y}`` for the tile

* or ``/data/{id}/elevation/{z}/{long}/{lat}`` for the coordinate

* the result will be a json object like ``{"z":7,"x":68,"y":45,"red":134,"green":66,"blue":0,"latitude":11.84069,"longitude":46.04798,"elevation":1602}``

Static files
===========
* Static files are served at ``/files/{filename}``
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"type": "module",
"scripts": {
"test": "mocha test/**.js --timeout 10000 --exit",
"test-docker": "xvfb-run npm test",
"lint:yml": "yamllint --schema=CORE_SCHEMA *.{yml,yaml}",
"lint:js": "npm run lint:eslint && npm run lint:prettier",
"lint:js:fix": "npm run lint:eslint:fix && npm run lint:prettier:fix",
Expand Down
2 changes: 1 addition & 1 deletion public/resources/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ section {
}
.details h3 {
font-size: 18px;
margin-top: 25px;
margin-top: 5px;
}
.details p {
padding: 0;
Expand Down
150 changes: 108 additions & 42 deletions public/templates/data.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,25 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{name}} - TileServer GL</title>
{{#is_vector}}
{{#use_maplibre}}
<link rel="stylesheet" type="text/css" href="{{public_url}}maplibre-gl.css{{&key_query}}" />
<link rel="stylesheet" type="text/css" href="{{public_url}}maplibre-gl-inspect.css{{&key_query}}" />
<script src="{{public_url}}maplibre-gl.js{{&key_query}}"></script>
<script src="{{public_url}}maplibre-gl-inspect.js{{&key_query}}"></script>
<style>
body {background:#fff;color:#333;font-family:Arial, sans-serif;}
{{^is_terrain}}
#map {position:absolute;top:0;left:0;right:250px;bottom:0;}
{{/is_terrain}}
{{#is_terrain}}
#map { position:absolute; top:0; bottom:0; width:100%; }
{{/is_terrain}}
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:0;width:240px;overflow:auto;}
#layerList div div {width:15px;height:15px;display:inline-block;}
</style>
{{/is_vector}}
{{^is_vector}}
{{/use_maplibre}}
{{^use_maplibre}}
<link rel="stylesheet" type="text/css" href="{{public_url}}leaflet.css{{&key_query}}" />
<script src="{{public_url}}leaflet.js{{&key_query}}"></script>
<script src="{{public_url}}leaflet-hash.js{{&key_query}}"></script>
Expand All @@ -37,23 +42,22 @@
background-image: url({{public_url}}images/marker-icon.png{{&key_query}});
}
</style>
{{/is_vector}}
{{/use_maplibre}}
</head>
<body>
{{#is_vector}}
{{#use_maplibre}}
<h1>{{name}}</h1>
<div id="map"></div>
{{^is_terrain}}
<div id="layerList"></div>
<pre id="propertyList"></pre>
{{/is_terrain}}
<script>
var keyMatch = location.search.match(/[\?\&]key=([^&]+)/i);
var keyParam = keyMatch ? '?key=' + keyMatch[1] : '';

var map = new maplibregl.Map({
container: 'map',
hash: true,
maxPitch: 85,
style: {
var keyMatch = location.search.match(/[\?\&]key=([^&]+)/i);
var keyParam = keyMatch ? '?key=' + keyMatch[1] : '';

{{^is_terrain}}
var style = {
version: 8,
sources: {
'vector_layer_': {
Expand All @@ -62,37 +66,99 @@
}
},
layers: []
}
});
map.addControl(new maplibregl.NavigationControl());
var inspect = new MaplibreInspect({
showInspectMap: true,
showInspectButton: false
});
map.addControl(inspect);
map.on('styledata', function() {
var layerList = document.getElementById('layerList');
layerList.innerHTML = '';
Object.keys(inspect.sources).forEach(function(sourceId) {
var layerIds = inspect.sources[sourceId];
layerIds.forEach(function(layerId) {
var item = document.createElement('div');
item.innerHTML = '<div style="' +
'background:' + inspect.assignLayerColor(layerId) + ';' +
'"></div> ' + layerId;
layerList.appendChild(item);
});
})
});
};
{{/is_terrain}}
{{#is_terrain}}
var style = {
version: 8,
sources: {
"terrain": {
"type": "raster-dem",
"url": "{{public_url}}data/{{id}}.json",
"encoding": "{{terrain_encoding}}"
},
"hillshade": {
"type": "raster-dem",
"url": "{{public_url}}data/{{id}}.json",
"encoding": "{{terrain_encoding}}"
}
},
"terrain": {
"source": "terrain"
},
layers: [
{
"id": "background",
"paint": {
{{^if is_terrainrgb}}
"background-color": "hsl(190, 99%, 63%)"
{{else}}
"background-color": "hsl(0, 100%, 25%)"
{{/if}}
},
"type": "background"
},
{
"id": "hillshade",
"source": "hillshade",
"type": "hillshade",
"paint": {
"hillshade-shadow-color": "hsl(39, 21%, 33%)",
"hillshade-illumination-direction": 315,
"hillshade-exaggeration": 0.8
}
}
]
};
{{/is_terrain}}

var map = new maplibregl.Map({
container: 'map',
hash: true,
maxPitch: 85,
style: style
});
map.addControl(new maplibregl.NavigationControl({
visualizePitch: true,
showZoom: true,
showCompass: true
}));
{{#is_terrain}}
map.addControl(
new maplibregl.TerrainControl({
source: "terrain",
})
);
{{/is_terrain}}
{{^is_terrain}}
var inspect = new MaplibreInspect({
showInspectMap: true,
showInspectButton: false
});
map.addControl(inspect);
map.on('styledata', function() {
var layerList = document.getElementById('layerList');
layerList.innerHTML = '';
Object.keys(inspect.sources).forEach(function(sourceId) {
var layerIds = inspect.sources[sourceId];
layerIds.forEach(function(layerId) {
var item = document.createElement('div');
item.innerHTML = '<div style="' +
'background:' + inspect.assignLayerColor(layerId) + ';' +
'"></div> ' + layerId;
layerList.appendChild(item);
});
})
});
{{/is_terrain}}
</script>
{{/is_vector}}
{{^is_vector}}
{{/use_maplibre}}
{{^use_maplibre}}
<h1 style="display:none;">{{name}}</h1>
<div id='map'></div>
<script>
var keyMatch = location.search.match(/[\?\&]key=([^&]+)/i);
var keyParam = keyMatch ? '?key=' + keyMatch[1] : '';

var keyMatch = location.search.match(/[\?\&]key=([^&]+)/i);
var keyParam = keyMatch ? '?key=' + keyMatch[1] : '';
var map = L.map('map', { zoomControl: false });
new L.Control.Zoom({ position: 'topright' }).addTo(map);

Expand Down Expand Up @@ -129,7 +195,7 @@
attribution: tile_attribution
}).addTo(map);
}

map.eachLayer(function(layer) {
// do not add scale prefix even if retina display is detected
layer.scalePrefix = '.';
Expand All @@ -141,6 +207,6 @@
new L.Hash(map);
}, 0);
</script>
{{/is_vector}}
{{/use_maplibre}}
</body>
</html>
25 changes: 18 additions & 7 deletions public/templates/index.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@
<title>TileServer GL - Server for vector and raster maps with GL styles</title>
<link rel="stylesheet" type="text/css" href="{{public_url}}index.css{{&key_query}}" />
<script>
function toggle_xyz(id) {
function toggle_link(id, link) {
var el = document.getElementById(id);
var s = el.style;
s.display = s.display == 'none' ? 'inline-block' : 'none';
if (s.display == 'none') {
s.display = 'inline-block';
} else if (el.value == link) {
s.display = 'none';
}
el.value = link;
el.setSelectionRange(0, el.value.length);
return false;
}
Expand Down Expand Up @@ -37,7 +42,7 @@
<div class="filter-details">
<h3>Filter styles and data by name or identifier</h3>
<!-- filter input , needs to call filter() when content changes...-->
<input id="filter" type="text" oninput="filter()" placeholder="Start typing name or identifier" />
<input id="filter" type="text" oninput="filter()" placeholder="Start typing name or identifier" autofocus />
</div>
</div>
</div>
Expand Down Expand Up @@ -66,8 +71,8 @@
| <a href="{{public_url}}styles/{{@key}}/wmts.xml{{&../key_query}}">WMTS</a>
{{/if}}
{{#if xyz_link}}
| <a href="#" onclick="return toggle_xyz('xyz_style_{{@key}}');">XYZ</a>
<input id="xyz_style_{{@key}}" type="text" value="{{&xyz_link}}" style="display:none;" />
| <a href="#" onclick="return toggle_link('xyz_style_{{@key}}', '{{&xyz_link}}');">XYZ</a>
<input id="xyz_style_{{@key}}" type="text" value="" style="display:none;" />
{{/if}}
</p>
</div>
Expand Down Expand Up @@ -105,9 +110,12 @@
<p class="services">
services: <a href="{{public_url}}data/{{@key}}.json{{&../key_query}}">TileJSON</a>
{{#if xyz_link}}
| <a href="#" onclick="return toggle_xyz('xyz_data_{{@key}}');">XYZ</a>
<input id="xyz_data_{{@key}}" type="text" value="{{&xyz_link}}" style="display:none;" />
| <a href="#" onclick="return toggle_link('link_data_{{@key}}', '{{&xyz_link}}');">XYZ</a>
{{/if}}
{{#if elevation_link}}
| <a href="#" onclick="return toggle_link('link_data_{{@key}}', '{{&elevation_link}}');">Elevation</a>
{{/if}}
<input id="link_data_{{@key}}" type="text" value="" style="display:none;" />
</p>
</div>
<div class="viewers">
Expand All @@ -116,6 +124,9 @@
{{/is_vector}}
{{^is_vector}}
<a class="btn" href="{{public_url}}data/{{@key}}/{{&../key_query}}{{viewer_hash}}">View</a>
{{#elevation_link}}
<a class="btn" href="{{public_url}}data/preview/{{@key}}/{{&../key_query}}{{viewer_hash}}">Preview</a>
Comment thread
acalcutt marked this conversation as resolved.
Outdated
{{/elevation_link}}
{{/is_vector}}
</div>
</div>
Expand Down
Loading