Skip to content

Instantly share code, notes, and snippets.

@HarryStevens
Last active September 20, 2017 06:59
Show Gist options
  • Save HarryStevens/088792f5f9cb444bfaf7d6fc3e0e8445 to your computer and use it in GitHub Desktop.
Save HarryStevens/088792f5f9cb444bfaf7d6fc3e0e8445 to your computer and use it in GitHub Desktop.
Map Tiles Playground
license: gpl-3.0
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
}
#select {
position: absolute;
width: 100%;
text-align: center;
}
.subunit {
fill: none;
stroke: steelblue;
stroke-width: 3px;
}
</style>
</head>
<body>
<div id="select">
<select>
<option value="osm" selected>Open Street Map</option>
<option value="toner">Stamen Toner</option>
<option value="terrain">Stamen Terrain</option>
<option value="terrain_labels">Stamen Terrain Only Labels</option>
<option value="terrain_nolabels">Stamen Terrain No Labels</option>
<option value="watercolor">Stamen Watercolor</option>
<option value="mapbox_earth">Mapbox Natural Earth</option>
<option value="light_all">Carto Light All</option>
<option value="dark_all">Carto Dark All</option>
<option value="light_nolabels">Carto Light No Labels</option>
<option value="light_only_labels">Carto Light Only Labels</option>
<option value="dark_nolabel">Carto Dark No Labels</option>
<option value="dark_only_labels">Carto Dark Only Labels</option>
</select>
</div>
<div id="map"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.20/topojson.min.js"></script>
<script src="https://unpkg.com/d3-marcon@2.0.1/build/d3-marcon.min.js"></script>
<script src="https://d3js.org/d3-tile.v0.0.min.js"></script>
<script>
var m = d3.marcon().width(window.innerWidth).height(window.innerHeight);
m.render();
var width = m.innerWidth(), height = m.innerHeight(), svg = m.svg();
var projection = d3.geoMercator();
var path = d3.geoPath()
.projection(projection);
d3.queue()
.defer(d3.json, "india.json")
.await(ready);
function ready(error, map){
centerZoom(map);
tiles($("select").val());
$("select").change(function(){
tiles($(this).val());
});
drawSubUnits(map);
}
// This function "centers" and "zooms" a map by setting its projection's scale and translate according to its outer boundary
// It also returns the boundary itself in case you want to draw it to the map
function centerZoom(data){
var o = topojson.mesh(data, data.objects.polygons, function(a, b) { return a === b; });
projection
.scale(1)
.translate([0, 0]);
var b = path.bounds(o),
s = 1 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height),
t = [(width - s * (b[1][0] + b[0][0])) / 2, (height - s * (b[1][1] + b[0][1])) / 2];
projection
.scale(s)
.translate(t);
return o;
}
function drawSubUnits(data){
svg.selectAll(".subunit")
.data(topojson.feature(data, data.objects.polygons).features)
.enter().append("path")
.attr("class", "subunit")
.attr("d", path);
}
function tiles(type){
var types = {
osm: function(d){ return "http://" + "abc"[d[1] % 3] + ".tile.openstreetmap.org/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
toner: function(d){ return "http://tile.stamen.com/toner/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
terrain: function(d){ return "http://tile.stamen.com/terrain/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
terrain_labels: function(d){ return "http://tile.stamen.com/terrain-labels/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
terrain_nolabels: function(d){ return "http://tile.stamen.com/terrain-background/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
watercolor: function(d){ return "http://tile.stamen.com/watercolor/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
mapbox_earth: function(d){return "https://a.tiles.mapbox.com/v3/mapbox.natural-earth-2/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
light_all: function(d){ return "https://cartodb-basemaps-" + "abcd"[d[1] % 4] + ".global.ssl.fastly.net/light_all/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
dark_all: function(d){ return "https://cartodb-basemaps-" + "abcd"[d[1] % 4] + ".global.ssl.fastly.net/dark_all/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
light_nolabels: function(d){ return "https://cartodb-basemaps-" + "abcd"[d[1] % 4] + ".global.ssl.fastly.net/light_nolabels/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
light_only_labels: function(d){ return "https://cartodb-basemaps-" + "abcd"[d[1] % 4] + ".global.ssl.fastly.net/light_only_labels/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
dark_nolabels: function(d){ return "https://cartodb-basemaps-" + "abcd"[d[1] % 4] + ".global.ssl.fastly.net/dark_nolabels/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
dark_only_labels: function(d){ return "https://cartodb-basemaps-" + "abcd"[d[1] % 4] + ".global.ssl.fastly.net/dark_only_labels/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; }
}
var pi = Math.PI,
tau = 2 * pi;
var tiles = d3.tile()
.size([width, height])
.scale(projection.scale() * tau)
.translate(projection([0, 0]))
();
var image = svg.selectAll("image")
.data(tiles, function(i){ return i });
image
.attr("xlink:href", types[type])
image.enter().append("image")
.attr("xlink:href", types[type])
.attr("x", function(d) { return (d[0] + tiles.translate[0]) * tiles.scale; })
.attr("y", function(d) { return (d[1] + tiles.translate[1]) * tiles.scale; })
.attr("width", tiles.scale)
.attr("height", tiles.scale);
}
</script>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment