Skip to content

Instantly share code, notes, and snippets.

Created December 13, 2017 15:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/8c0e522bee8a88601098d78c635b94f2 to your computer and use it in GitHub Desktop.
Save anonymous/8c0e522bee8a88601098d78c635b94f2 to your computer and use it in GitHub Desktop.
TileJSON.io
<!DOCTYPE html>
<html>
<head>
<title>TileJSON</title>
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css">
<link rel="stylesheet" href="https://openlayers.org/en/v4.3.3/css/ol.css" type="text/css">
<!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
<script src="https://openlayers.org/en/v4.3.3/build/ol.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<style>
html, body, #container {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
max-height: 100%;
max-width: 100%;
overflow: hidden;
}
#map, #diffMap {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
}
#overDiffMap {
position: absolute;
top: 132px;
left: -16px;
right: -16px;
width: calc(100% + 32px);
max-height: calc(100% - 116px);
z-index: 1000;
}
#card {
position: absolute;
top: 32px;
right: 32px;
width: 320px;
}
.ol-zoom {
left: .5em;
top: calc(60px + .5em);
}
#header {
position: absolute;
top: 0;
left: 0;
z-index: 100;
margin-top: 0;
margin-bottom: 0;
padding-top: 12px;
padding-bottom: 12px;
padding-left: 12px;
padding-right: 12px;
background-color: #ec6f75;
color: #fff;
}
#layer-toolbar {
position: absolute;
top: 0;
right: 0;
margin-top: 0;
margin-bottom: 0;
padding-top: 12px;
padding-left: 12px;
padding-right: 12px;
background-color: #e8e8e8;
z-index: 2000;
width: 360px;
}
.btn-flat {
color: #fff !important;
}
#swipe {
-webkit-appearance: none;
appearance: none;
width: 100%;
height: 0px;
opacity: 0.7;
border: none;
}
#swipe:hover {
opacity: 1;
}
#swipe::-webkit-slider-runnable-track {
height: 28px;
background-color: transparent;
border: none;
}
#swipe::-webkit-slider-thumb {
background: #ee6e73;
height: 32px;
width: 32px;
}
.row {
margin-bottom: 0px !important;
}
.thumb {
display: none;
}
</style>
<div id="container">
<div id="header" class="card darken-1" hidden>
<a id="tilejson-link" class="waves-effect waves-teal btn-flat" href="https://tilejson.io" target="_blank">TileJSON.io</a>
<a id="diff-btn" class="waves-effect waves-teal btn-flat">Diff</a>
<a id="exit-diff-btn" class="waves-effect waves-teal btn-flat">Exit Diff</a>
<a id="gist-link" class="waves-effect waves-teal btn-flat" href="https://tilejson.io" target="_blank">GitHub Gist</a>
</div>
<div class="card darken-1" id="layer-toolbar" hidden>
<div class="row">
<div class="input-field col s6">
<select id="leftLayerSelect">
<option value="" disabled selected>Choose a layer</option>
</select>
<label>Left Layer</label>
</div>
<div class="input-field col s6">
<select id="rightLayerSelect">
<option value="" disabled selected>Choose a layer</option>
</select>
<label>Right Layer</label>
</div>
</div>
</div>
<div id="map" class="map"></div>
<div id="diffMap" class="diffMap"></div>
<div id="overDiffMap" hidden>
<input type="range" id="swipe" min="0" max="100" />
</div>
<div id="card" class="card darken-1" hidden>
<a class="btn-floating halfway-fab waves-effect waves-light red" id="card-show" hidden><i class="material-icons">expand_more</i></a>
<a class="btn-floating halfway-fab waves-effect waves-light red" id="card-hide"><i class="material-icons">expand_less</i></a>
<div id="card-content" class="card-content">
<span class="card-title" id="map-title">Shared Map</span>
<p><span id="map-description"></p></p>
</div>
</div>
</div>
<script>
$( document ).ready(function() {
$('select').material_select();
$('#exit-diff-btn').hide();
var urlPath = window.location.pathname.split('/');
$('#gist-link').attr('href', 'https://gist.github.com/anonymous/' + urlPath[urlPath.length - 2] + '#file-tile-json');
$.getJSON('info.json', function(data) {
var map = new ol.Map({
target: 'map',
view: new ol.View({
center: data.center,
zoom: data.zoom
})
});
var diffMap = new ol.Map({
target: 'diffMap',
view: map.getView()
});
$('#diffMap').hide();
if (data.title || data.description) {
$('#card').show();
if (data.title) {
$('#map-title').text(data.title);
} else {
$('#map-title').hide();
}
if (data.description) {
$('#map-description').text(data.description);
}
}
var baseLayer = new ol.layer.Tile({
source: new ol.source.TileJSON({
tileJSON: data.baseLayer,
})
});
diffMap.addLayer(baseLayer);
if (data.shareBase) {
map.addLayer(baseLayer);
} else {
baseLayer.setVisible(false);
}
$.getJSON('tile.json', function(tileData) {
if (data.shareGist || data.shareTileJSONLink || tileData.length >= 2) {
$('#header').show();
if (!data.shareGist) {
$('#gist-link').hide();
}
if (!data.shareTileJSONLink) {
$('#tilejson-link').hide();
}
}
if (tileData.length < 2 || !data.shareDiff) {
$('#diff-btn').hide();
if (!data.shareGist && !data.shareTileJSONLink) {
$('#header').hide();
}
}
tileData.forEach(function (tileJson) {
var layer = new ol.layer.Tile({
source: new ol.source.TileJSON({
tileJSON: tileJson,
})
});
map.addLayer(layer);
layer.setVisible(tileJson.visible);
layer.setOpacity(tileJson.opacity);
});
function initDiffMapAndSelects(left, right) {
const diffMapLayers = diffMap.getLayers().getArray();
var leftLayer, rightLayer;
if (diffMapLayers.length === 1) {
leftLayer = new ol.layer.Tile({
source: new ol.source.TileJSON({
tileJSON: tileData[left],
})
});
diffMap.addLayer(leftLayer);
rightLayer = new ol.layer.Tile({
source: new ol.source.TileJSON({
tileJSON: tileData[right],
})
});
diffMap.addLayer(rightLayer);
setListeners();
} else {
leftLayer = diffMapLayers[1];
leftLayer.setSource(new ol.source.TileJSON({
tileJSON: tileData[left],
}));
rightLayer = diffMapLayers[2];
rightLayer.setSource(new ol.source.TileJSON({
tileJSON: tileData[right],
}));
}
$('#leftLayerSelect').find('option').remove();
tileData.forEach(function (tilejson, i) {
if (i !== parseInt(right)) {
$('#leftLayerSelect').append($('<option>', {
value: i,
text : tilejson.name,
selected: i === parseInt(left)
}));
}
});
$('#rightLayerSelect').find('option').remove();
tileData.forEach(function (tilejson, i) {
if (i !== parseInt(left)) {
$('#rightLayerSelect').append($('<option>', {
value: i,
text : tilejson.name,
selected: i === parseInt(right)
}));
}
});
$('select').material_select();
}
function setListeners() {
const diffMapLayers = diffMap.getLayers().getArray();
var swipe = document.getElementById('swipe');
diffMapLayers[1].on('precompose', function(event) {
var ctx = event.context;
var width = ctx.canvas.width * swipe.value / 100;
ctx.save();
ctx.beginPath();
ctx.rect(0, 0, width, ctx.canvas.height);
ctx.clip();
});
diffMapLayers[1].on('postcompose', function(event) {
var ctx = event.context;
ctx.restore();
});
diffMapLayers[2].on('precompose', function(event) {
var ctx = event.context;
var width = ctx.canvas.width * swipe.value / 100;
ctx.save();
ctx.beginPath();
ctx.rect(width, 0, ctx.canvas.width - width, ctx.canvas.height);
ctx.clip();
});
diffMapLayers[2].on('postcompose', function(event) {
var ctx = event.context;
const width = ctx.canvas.width * swipe.value / 100;
ctx.restore();
ctx.save();
ctx.fillStyle = '#ffffff';
ctx.beginPath();
ctx.fillRect(width - 6, 0, 12, ctx.canvas.height);
ctx.restore();
});
swipe.addEventListener('input', function() {
diffMap.render();
}, false);
}
$('#diff-btn').click(function() {
if (tileData.length < 2) {
return;
}
$('#diff-btn').hide();
$('#exit-diff-btn').show();
$('#card').hide();
$('#overDiffMap').show();
$('#map').hide();
$('#diffMap').show();
$('#layer-toolbar').show();
var left = data.diffLayerLeftId === -1 ? 0 : data.diffLayerLeftId;
var right = data.diffLayerRightId === -1 ? 1 : data.diffLayerRightId;
initDiffMapAndSelects(left, right);
});
$('#exit-diff-btn').click(function() {
$('#diff-btn').show();
$('#exit-diff-btn').hide();
if (data.title || data.description) {
$('#card').show();
}
$('#overDiffMap').hide();
$('#map').show();
$('#diffMap').hide();
$('#layer-toolbar').hide();
});
$('#leftLayerSelect').on('change', function() {
initDiffMapAndSelects(this.value, $('#rightLayerSelect').val());
});
$('#rightLayerSelect').on('change', function() {
initDiffMapAndSelects($('#leftLayerSelect').val(), this.value);
});
if (data.shareDiff && data.defaultToDiff) {
$('#diff-btn').trigger('click');
}
});
});
$('#card-hide').click(function() {
$('#card-content').hide();
$('#card-hide').hide();
$('#card-show').show();
});
$('#card-show').click(function() {
$('#card-content').show();
$('#card-hide').show();
$('#card-show').hide();
});
});
</script>
</body>
</html>
{
"baseLayer": {
"tilejson": "2.2.0",
"name": "base",
"version": "1.0.0",
"scheme": "xyz",
"tiles": [
"https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"
]
},
"diffLayerLeftId": -1,
"diffLayerRightId": -1,
"shareGist": false,
"shareTileJSONLink": true,
"shareBase": false,
"shareDiff": false,
"defaultToDiff": false,
"center": [
-31259792.21138417,
2264177.6234144773
],
"zoom": 11.805268791741776
}
[
{
"tilejson": "2.2.0",
"name": "Layer 1",
"version": "1.0.0",
"scheme": "xyz",
"tiles": [
"https://s3.amazonaws.com/com.azavea.datahub.tms/srtm/ca-tobler/{z}/{x}/{y}.png"
],
"opacity": 1,
"visible": true
},
{
"tilejson": "2.2.0",
"name": "Layer 2",
"version": "1.0.0",
"scheme": "xyz",
"tiles": [
"http://s3.amazonaws.com/com.azavea.datahub.tms/srtm/world-tobler-osm/{z}/{x}/{y}.png"
],
"opacity": 1,
"visible": true
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment