Skip to content

Instantly share code, notes, and snippets.

@calvinmetcalf
Created February 14, 2013 19:21
Show Gist options
  • Save calvinmetcalf/4955504 to your computer and use it in GitHub Desktop.
Save calvinmetcalf/4955504 to your computer and use it in GitHub Desktop.

D3 Hexbins in leaflet

first rather crude attempt at d3 hexbins in leaflet

<!DOCTYPE html>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=1024, user-scalable=no">
<style>
html { height: 100% }
body { height: 100%; margin: 0; padding: 0;}
#map{ height: 100% }
</style>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.5.1/leaflet.css" />
<title>Hex Bins + leaflet</title>
<div id="map"></div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="https://raw.github.com/mbostock/d3/5348d911938a0d1fdf43d7c86befbd908e431204/lib/colorbrewer/colorbrewer.js"></script>
<script src="https://raw.github.com/d3/d3-plugins/master/hexbin/hexbin.js"></script>
<script src="http://cdn.leafletjs.com/leaflet-0.5.1/leaflet.js"></script>
<script>
var m = L.map("map").setView([42.3164, -71.6803],9);
//make the map
L.layerGroup([
L.tileLayer("http://{s}.tile.stamen.com/terrain-background/{z}/{x}/{y}.jpg",{minZoom:4,maxZoom:18}),
L.tileLayer("http://{s}.tile.stamen.com/terrain-lines/{z}/{x}/{y}.png",{minZoom:4,maxZoom:12,attribution:'Map tiles by <a href="http://stamen.com">Stamen Design</a>, <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> &mdash; Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'})
]).addTo(m);
//add a tileset
var randomLat = d3.random.normal(m.getCenter().lat, .15),
randomLng = d3.random.normal(m.getCenter().lng, .5),
points=d3.range(60000).map(function() { return [randomLat(), randomLng()]; });
//generate 60k random points
var radius = 0.02;
var hexbin = d3.hexbin()
.size([
d3.max(points,function(v){return v[0]})-d3.min(points,function(v){return v[0]}),
d3.max(points,function(v){return v[1]})-d3.min(points,function(v){return v[1]})])
.radius(radius);
//create a hexbin
var hex = hexbin(points);
//populate it
var q = d3.scale.quantile().domain(hex.map(function(h){return h.length;}).reduce(function(a,b){if(a.indexOf(b)===-1){a.push(b)};return a;},[]).sort(function(a,b){return a-b})).range(d3.range(11))
//make a scale
function hexagon(radius) {
var x0 = 0, y0 = 0;
return d3.range(0, 2 * Math.PI, Math.PI / 3).map(function(angle) {
var x1 = Math.sin(angle) * radius,
y1 = -Math.cos(angle) * radius,
dx = x1 - x0,
dy = y1 - y0;
x0 = x1, y0 = y1;
return [dx, dy];
});
};
//from the hexbin file, we need this to create points
var transform = hexagon(radius);
//use it to create a transform function
transform.shift();
//remove the first value as it's a duplicate
L.layerGroup(hex.map(function(h){//create a layergroup
return L.polygon(transform.map(function(t){//filled with polygons
return [h.x+t[0],h.y+t[1]];//that are the hexagons we need
}),{//styled like so
stroke:false,
color:colorbrewer.Spectral[11][10-q(h.length)],//including color brewer colors
fillOpacity:0.4
}).bindPopup("points: "+h.length);//with the number of points in the popup
})).addTo(m);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment