You can display map tiles with d3-tile, and then overlay them with TopoJSON vectors.
Tiles copyright OpenStreetMap contributors.
license: gpl-3.0 |
You can display map tiles with d3-tile, and then overlay them with TopoJSON vectors.
Tiles copyright OpenStreetMap contributors.
<!DOCTYPE html> | |
<html> | |
<head> | |
<style> | |
body { | |
margin: 0; | |
} | |
.subunit { | |
fill: none; | |
stroke: steelblue; | |
stroke-width: 3px; | |
} | |
</style> | |
</head> | |
<body> | |
<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/[email protected]/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, "delhi_ward_outline.json") | |
.await(ready) | |
function ready(error, map){ | |
centerZoom(map); | |
tiles(); | |
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(){ | |
var pi = Math.PI, | |
tau = 2 * pi; | |
var tiles = d3.tile() | |
.size([width, height]) | |
.scale(projection.scale() * tau) | |
.translate(projection([0, 0])) | |
(); | |
svg.selectAll("image") | |
.data(tiles) | |
.enter().append("image") | |
.attr("xlink:href", function(d) { return "http://" + "abc"[d[1] % 3] + ".tile.openstreetmap.org/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; }) | |
.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> |