block by mbostock 4150951

Clipped Map Tiles

Full Screen

Demonstrates the d3.geo.tile plug-in used in conjunction with the d3.geo.mercator projection to clip MapBox Natural Earth II raster tiles. The outline of the United States is loaded in TopoJSON format.

Updated Example →

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.stroke {
  fill: none;
  stroke: #000;
  stroke-width: .5;
}

</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script src="d3.geo.tile.min.js"></script>
<script>

var width = 960,
    height = 500;

var projection = d3.geo.mercator()
    .center([-96, 38.3])
    .scale(890);

var path = d3.geo.path()
    .projection(projection);

var tile = d3.geo.tile()
    .scale(projection.scale() * 2 * Math.PI)
    .translate(projection([0, 0]))
    .zoomDelta((window.devicePixelRatio || 1) - .5);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

d3.json("/mbostock/raw/4090846/us.json", function(error, topology) {
  if (error) throw error;

  var tiles = tile();

  var defs = svg.append("defs");

  defs.append("path")
      .attr("id", "land")
      .datum(topojson.feature(topology, topology.objects.land))
      .attr("d", path);

  defs.append("clipPath")
      .attr("id", "clip")
    .append("use")
      .attr("xlink:href", "#land");

  svg.append("g")
      .attr("clip-path", "url(#clip)")
    .selectAll("image")
      .data(tiles)
    .enter().append("image")
      .attr("xlink:href", function(d) { return "//" + ["a", "b", "c", "d"][Math.random() * 4 | 0] + ".tiles.mapbox.com/v3/mapbox.natural-earth-2/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; })
      .attr("width", Math.round(tiles.scale))
      .attr("height", Math.round(tiles.scale))
      .attr("x", function(d) { return Math.round((d[0] + tiles.translate[0]) * tiles.scale); })
      .attr("y", function(d) { return Math.round((d[1] + tiles.translate[1]) * tiles.scale); });

  svg.append("use")
      .attr("xlink:href", "#land")
      .attr("class", "stroke");
});

</script>

d3.geo.tile.min.js

d3.geo.tile=function(){function t(){var t=Math.max(Math.log(n)/Math.LN2-8,0),h=Math.round(t+e),o=Math.pow(2,t-h+8),u=[(r[0]-n/2)/o,(r[1]-n/2)/o],l=[],c=d3.range(Math.max(0,Math.floor(-u[0])),Math.max(0,Math.ceil(a[0]/o-u[0]))),M=d3.range(Math.max(0,Math.floor(-u[1])),Math.max(0,Math.ceil(a[1]/o-u[1])));return M.forEach(function(t){c.forEach(function(a){l.push([a,t,h])})}),l.translate=u,l.scale=o,l}var a=[960,500],n=256,r=[a[0]/2,a[1]/2],e=0;return t.size=function(n){return arguments.length?(a=n,t):a},t.scale=function(a){return arguments.length?(n=a,t):n},t.translate=function(a){return arguments.length?(r=a,t):r},t.zoomDelta=function(a){return arguments.length?(e=+a,t):e},t};