Created
September 20, 2017 05:09
-
-
Save danabauer/e20825b2bef9c3b689fe84582571d404 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
svg, | |
#tiles { | |
position: absolute; | |
width: 960px; | |
height: 600px; | |
overflow: hidden; | |
} | |
</style> | |
<div id="tiles"></div> | |
<svg width="960" height="600"></svg> | |
<script src="//d3js.org/d3.v4.min.js"></script> | |
<script src="//d3js.org/d3-tile.v0.0.min.js"></script> | |
<script src="//d3js.org/topojson.v1.min.js"></script> | |
<script> | |
var pi = Math.PI, | |
tau = 2 * pi; | |
var svg = d3.select("svg"), | |
width = +svg.attr("width"), | |
height = +svg.attr("height"); | |
// Initialize the projection to fit the world in a 1×1 square centered at the origin. | |
var projection = d3.geoMercator() | |
.scale(1 / tau) | |
.translate([0, 0]); | |
// Compute the projected bounding box given a geographic bounding box (here, California). | |
// This assumes parallels are horizontal and meridians are vertical… | |
// but you could use path.bounds to handle arbitrary shapes. | |
// Note that the y-dimension is flipped relative to latitude! | |
var bounds = [[-124.408585, 32.534291], [-114.138271, 42.007768]], | |
p0 = projection([bounds[0][0], bounds[1][1]]), | |
p1 = projection([bounds[1][0], bounds[0][1]]); | |
// Convert this to a scale k and translate tx, ty for the projection. | |
// For crisp image tiles, clamp to the nearest power of two. | |
var k = floor(0.95 / Math.max((p1[0] - p0[0]) / width, (p1[1] - p0[1]) / height)), | |
tx = (width - k * (p1[0] + p0[0])) / 2, | |
ty = (height - k * (p1[1] + p0[1])) / 2; | |
projection | |
.scale(k / tau) | |
.translate([tx, ty]); | |
// Lastly convert this to the corresponding tile.scale and tile.translate; | |
// see http://bl.ocks.org/mbostock/4150951 for a related example. | |
var tiles = d3.tile() | |
.size([width, height]) | |
.scale(k) | |
.translate([tx, ty]) | |
(); | |
d3.select("#tiles") | |
.selectAll("img").data(tiles).enter().append("img") | |
.style("position", "absolute") | |
.attr("src", function(d, i) { return "http://" + "abc"[d[1] % 3] + ".tile.openstreetmap.org/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; }) | |
.style("left", function(d) { return (d[0] + tiles.translate[0]) * tiles.scale + "px"; }) | |
.style("top", function(d) { return (d[1] + tiles.translate[1]) * tiles.scale + "px"; }) | |
.attr("width", tiles.scale) | |
.attr("height", tiles.scale); | |
d3.json("/mbostock/raw/4090846/us.json", function(error, us) { | |
if (error) throw error; | |
svg.append("path") | |
.datum(topojson.mesh(us, us.objects.states)) | |
.attr("d", d3.geoPath().projection(projection)) | |
.attr("fill", "none") | |
.attr("stroke", "#000"); | |
}); | |
function floor(k) { | |
return Math.pow(2, Math.floor(Math.log(k) / Math.LN2)); | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment