Skip to content

Instantly share code, notes, and snippets.

@cpdean
Forked from mbostock/.block
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cpdean/1992eaadc20f776696f6 to your computer and use it in GitHub Desktop.
Save cpdean/1992eaadc20f776696f6 to your computer and use it in GitHub Desktop.

This is a fork of mike bostock's vector tiles example.

I've just re-centered it around Minneapolis to see how it looks.

Looking for an easy way to do map visualizations, geo data is too fickle to learn without leveraging tons of examples

Adapting d3.geo.tile to show OpenStreetMap vector tiles. See also the static example.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
margin: 0;
}
.map {
position: relative;
overflow: hidden;
}
.layer {
position: absolute;
}
.tile {
position: absolute;
width: 256px;
height: 256px;
}
.tile path {
fill: none;
stroke: #000;
stroke-linejoin: round;
stroke-linecap: round;
}
.tile path.path {
stroke: #ccb;
stroke-dasharray:4,2,4;
}
.tile .major_road { stroke: #776; }
.tile .minor_road { stroke: #ccb; }
.tile .highway { stroke: #f39; stroke-width: 1.5px; }
.tile .rail { stroke: #7de; }
.info {
position: absolute;
bottom: 10px;
left: 10px;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/d3.geo.tile.v0.min.js"></script>
<script>
var width = Math.max(960, window.innerWidth),
height = Math.max(500, window.innerHeight),
prefix = prefixMatch(["webkit", "ms", "Moz", "O"]);
var tile = d3.geo.tile()
.size([width, height]);
var ids_station = {};
ids_station
ids_station["Terminal"] = 30042;
ids_station["Station"] = "IDS Center";
ids_station["Location"] = "80 South 8th Street";
ids_station["Latitude"] = 44.975641;
ids_station["Longitude"] = -93.272185;
ids_station["Nb docks"] = 23;
var stations = [
ids_station
];
var projection = d3.geo.mercator()
.scale((1 << 23) / 2 / Math.PI)
.translate([-width / 2, -height / 2]); // just temporary
var tileProjection = d3.geo.mercator();
var tilePath = d3.geo.path()
.projection(tileProjection);
var zoom = d3.behavior.zoom()
.scale(projection.scale() * 2 * Math.PI)
.scaleExtent([1 << 20, 1 << 23])
.translate(projection([-93.267202, 44.980991]).map(function(x) { return -x; }))
.on("zoom", zoomed);
var map = d3.select("body").append("div")
.attr("class", "map")
.style("width", width + "px")
.style("height", height + "px")
.call(zoom)
.on("mousemove", mousemoved);
var svg = map.append("svg")
.style("float", "left")
.attr("width", width)
.attr("height", height);
var layer = map.append("div")
.attr("class", "layer");
var info = map.append("div")
.attr("class", "info");
zoomed();
function zoomed() {
var tiles = tile
.scale(zoom.scale())
.translate(zoom.translate())
();
projection
.scale(zoom.scale() / 2 / Math.PI)
.translate(zoom.translate());
var image = layer
.style(prefix + "transform", matrix3d(tiles.scale, tiles.translate))
.selectAll(".tile")
.data(tiles, function(d) { return d; });
image.exit()
.each(function(d) { this._xhr.abort(); })
.remove();
image.enter().append("svg")
.attr("class", "tile")
.style("left", function(d) { return d[0] * 256 + "px"; })
.style("top", function(d) { return d[1] * 256 + "px"; })
.each(function(d) {
var svg = d3.select(this);
this._xhr = 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) {
var k = Math.pow(2, d[2]) * 256; // size of the world in pixels
tilePath.projection()
.translate([k / 2 - d[0] * 256, k / 2 - d[1] * 256]) // [0°,0°] in pixels
.scale(k / 2 / Math.PI);
svg.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", function(d){
return tilePath(d);
});
});
});
// trying to learn from http://bl.ocks.org/emeeks/6147081
//var points = svg.append("g").attr("id","points").attr("transform", "translate(" + zoom.translate() + ")scale(" + zoom.scale() + ")");
var svg_points = svg.selectAll(".point")
.data(stations)
svg_points
.attr("transform", function(d) {
return "translate(" + projection([d.Longitude, d.Latitude]) + ")scale(" + projection.scale() + ")"
})
svg_points
.data(stations)
.enter()
.append("g")
.attr("class", "point")
.attr("transform", function(d) {
return "translate(" + projection([d.Longitude, d.Latitude]) + ")scale(" + projection.scale() + ")"
})
.append("circle")
.attr("r", 0.0000017)
}
function mousemoved() {
info.text(formatLocation(projection.invert(d3.mouse(this)), zoom.scale()));
}
function matrix3d(scale, translate) {
var k = scale / 256, r = scale % 1 ? Number : Math.round;
return "matrix3d(" + [k, 0, 0, 0, 0, k, 0, 0, 0, 0, k, 0, r(translate[0] * scale), r(translate[1] * scale), 0, 1 ] + ")";
}
function prefixMatch(p) {
var i = -1, n = p.length, s = document.body.style;
while (++i < n) if (p[i] + "Transform" in s) return "-" + p[i].toLowerCase() + "-";
return "";
}
function formatLocation(p, k) {
var format = d3.format("." + Math.floor(Math.log(k) / 2 - 2) + "f");
return (p[1] < 0 ? format(-p[1]) + "°S" : format(p[1]) + "°N") + " "
+ (p[0] < 0 ? format(-p[0]) + "°W" : format(p[0]) + "°E");
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment