Free map tiles.
Open Street Map Tiles copyright OpenStreetMap contributors,
Toner and Terrain Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under ODbL.
Watercolor Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under CC BY SA.
Carto Map tiles by Carto.
Mapbox Map tiles by MapBox
xxxxxxxxxx
<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 "https://" + "abc"[d[1] % 3] + ".tile.openstreetmap.org/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
toner: function(d){ return "https://tile.stamen.com/toner/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
terrain: function(d){ return "https://tile.stamen.com/terrain/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
terrain_labels: function(d){ return "https://tile.stamen.com/terrain-labels/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
terrain_nolabels: function(d){ return "https://tile.stamen.com/terrain-background/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; },
watercolor: function(d){ return "https://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>
https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js
https://d3js.org/d3.v4.min.js
https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.20/topojson.min.js
https://unpkg.com/d3-marcon@2.0.1/build/d3-marcon.min.js
https://d3js.org/d3-tile.v0.0.min.js