|
<!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> |