|
<html> |
|
<head> |
|
<meta chartset="utf-8"> |
|
<style> |
|
body { |
|
margin: 0; |
|
font-family: monospace; |
|
} |
|
|
|
.container > svg, |
|
.container > canvas { |
|
position: absolute; |
|
} |
|
|
|
path { |
|
fill: none; |
|
stroke: #000; |
|
stroke-linejoin: round; |
|
stroke-linecap: round; |
|
} |
|
|
|
.major_road { stroke: #776; } |
|
.minor_road { stroke: #ccb; } |
|
.highway { stroke: tomato; } |
|
.rail { stroke: #7de; } |
|
|
|
.annotation { |
|
text-anchor: middle; |
|
text-shadow: -1px 0 #fff, 0 1px #fff, 1px 0 #fff, 0 -1px #fff; |
|
} |
|
.annotation.large { font-size: 22px; } |
|
.annotation.medium { font-size: 16px; } |
|
.annotation.small { font-size: 12px; } |
|
|
|
</style> |
|
</head> |
|
<body> |
|
|
|
<div class="container"></div> |
|
|
|
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> |
|
<script src="d3.geo.tile.js"></script> |
|
<script> |
|
var width = 960, |
|
height = 500; |
|
|
|
var tiler = d3.geo.tile() |
|
.size([width, height]); |
|
|
|
var projection = d3.geo.mercator() |
|
.center([-87.95, 43.040150]) |
|
.scale((1 << 20) / 2 / Math.PI) |
|
.translate([width / 2, height / 2]); |
|
|
|
var path = d3.geo.path() |
|
.projection(projection); |
|
|
|
var svg = d3.select(".container").append("svg") |
|
.attr("width", width) |
|
.attr("height", height) |
|
.call(drawMap); |
|
|
|
var canvas = d3.select(".container").append("canvas") |
|
.attr("width", width) |
|
.attr("height", height) |
|
.call(addGradientEdge, 75); |
|
|
|
function addGradientEdge(selection, borderWidth) { |
|
var context = selection.node().getContext("2d"); |
|
|
|
var gradientData = [ |
|
{ |
|
side: "left", x: 0, y: 0, dx: borderWidth, dy: height, |
|
gradient: context.createLinearGradient(0, 0, borderWidth, 0) |
|
}, |
|
{ |
|
side: "top", x: 0, y: 0, dx: width, dy: borderWidth, |
|
gradient: context.createLinearGradient(0, 0, 0, borderWidth) |
|
}, |
|
{ |
|
side: "right", x: width - borderWidth, y: 0, dx: borderWidth, dy: height, |
|
gradient: context.createLinearGradient(width, 0, width - borderWidth, 0) |
|
}, |
|
{ |
|
side: "bottom", x: 0, y: height - borderWidth, dx: width, dy: borderWidth, |
|
gradient: context.createLinearGradient(0, height, 0, height - borderWidth) |
|
}, |
|
]; |
|
|
|
gradientData.forEach(function(d) { |
|
d.gradient.addColorStop(0, "white"); |
|
d.gradient.addColorStop(1, "rgba(255, 255, 255, 0)"); |
|
context.fillStyle = d.gradient; |
|
context.fillRect(d.x, d.y, d.dx, d.dy); |
|
}); |
|
} |
|
|
|
function drawMap(selection) { |
|
var annotation_data = [ |
|
{ |
|
text: "Milwaukee", |
|
coords: [-87.894746, 43.040746], |
|
size: "large" |
|
}, |
|
{ |
|
text: "Wauwatosa", |
|
coords: [-88.005609, 43.050873], |
|
size: "medium" |
|
}, |
|
{ |
|
text: "West Allis", |
|
coords: [-88.006764, 43.016687], |
|
size: "medium" |
|
} |
|
]; |
|
|
|
var tiles = selection.selectAll(".tile") |
|
.data(tiler |
|
.scale(projection.scale() * 2 * Math.PI) |
|
.translate(projection([0, 0]))); |
|
|
|
tiles.enter().append("g") |
|
.attr("class", "tile") |
|
.each(function(d) { |
|
var tile = d3.select(this); |
|
d3.json("http://" + ["a", "b", "c"][(d[0] * 31 + d[1]) % 3] + ".tile.openstreetmap.us/vectiles-highroad/" + d[2] + "/" + d[0] + "/" + d[1] + ".json", function(error, json) { |
|
tile.selectAll("path") |
|
.data(json.features.sort(function(a, b) { return a.properties.sort_key - b.properties.sort_key; })) |
|
.enter().append("path") |
|
.attr("class", function(d) { return d.properties.kind; }) |
|
.attr("d", path); |
|
}); |
|
}); |
|
|
|
var annotations = selection.selectAll(".annotation").data(annotation_data); |
|
|
|
annotations.enter().append("text") |
|
.attr("class", function(d) { return "annotation " + d.size; }) |
|
.attr("x", function(d) { return projection(d.coords)[0]; }) |
|
.attr("y", function(d) { return projection(d.coords)[1]; }) |
|
.text(function(d) { return d.text; }); |
|
} |
|
|
|
</script> |
|
</body> |
|
</html> |