Skip to content

Instantly share code, notes, and snippets.

@wboykinm
Last active December 10, 2015 04:29
Show Gist options
  • Save wboykinm/4381346 to your computer and use it in GitHub Desktop.
Save wboykinm/4381346 to your computer and use it in GitHub Desktop.
Tiled Map Print Composer (via @tmcw)
<DOCTYPE !HTML>
<style>
img.tile {
position:absolute;
}
#download {
position:absolute;
top:10px;
left:10px;
}
</style>
<body>
<canvas id='map'></canvas>
<button id='download'>download</button>
<div style='display:none;' id='loader'></div>
<script src="http://d3js.org/d3.v2.js"></script>
<script>
var width = 960,
height = 500,
projection = d3.geo.mercator().scale(1024).translate([512, 256]),
path = d3.geo.path().projection(projection);
var container = d3.select("#map")
.attr("width", width)
.attr("height", height)
.call(d3.behavior.zoom()
.translate(projection.translate())
.scale(projection.scale())
.on("zoom", redraw));
function tileUrl(d) {
return 'http://a.tiles.mapbox.com/v3/landplanner.map-dm7abyjg/' + d[0] + '/' + d[1] + '/' + d[2] + '.png';
}
var canvas = d3.select('#map').node();
var ctx = canvas.getContext('2d');
d3.select('#download').on('click', function() {
window.open(canvas.toDataURL(), "image", "width=960, height=500");
});
function redraw() {
if (d3.event && d3.event.translate) {
projection
.translate(d3.event.translate)
.scale(d3.event.scale);
}
var t = projection.translate(),
s = projection.scale(),
z = Math.max(Math.log(s) / Math.log(2) - 8, 0);
rz = Math.floor(z),
ts = 256 * Math.pow(2, z - rz);
// This is the 0, 0 px of the projection
var tile_origin = [s / 2 - t[0], s / 2 - t[1]];
var cols = d3.range(Math.max(0, Math.floor(tile_origin[0] / ts)),
Math.max(0, Math.ceil((tile_origin[0] + width) / ts)));
var rows = d3.range(Math.max(0, Math.floor(tile_origin[1] / ts)),
Math.max(0, Math.ceil((tile_origin[1] + height) / ts)));
var coords = [];
cols.forEach(function(x) {
rows.forEach(function(y) {
coords.push([Math.floor(z), x, y, [Math.floor(z), x, y].join(',')]);
});
});
canvas.width = canvas.width;
var tiles = d3.select('#loader').selectAll('img.tile')
.data(coords, function(d) { return d[3]; });
tiles.enter().append('img')
.property('crossOrigin', '*')
.attr('class', 'tile')
.attr('src', tileUrl)
.on('load', function(d) {
redraw();
});
tiles.each(function(d) {
if (!this.naturalWidth) return;
ctx.drawImage(this,
((d[1] * ts) - tile_origin[0]), ((d[2] * ts) - tile_origin[1]),
ts, ts);
});
}
redraw();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment