<title>Census Dotmap</title>
<link rel="image_src" href="/dotmap/sample.png" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta name="description" content="This is a map of every person counted by the 2010 US and 2011 Canadian censuses. The map has 341,817,095 dots - one for each person." />
<meta name="og:description" content="This is a map of every person counted by the 2010 US and 2011 Canadian censuses. The map has 341,817,095 dots - one for each person." />
<meta name="og:image" content="/dotmap/sample.png" />
<meta name="og:url" content="https://bmander.com/dotmap/index.html" />
<meta name="og:title" content="Census Dotmap" />
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100% }
<link type="text/css" rel="stylesheet" href="main.css" />
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDM5hCtSjwpVyntcUPCOP1dzheF6JXcx5k&sensor=false">
<script type="text/javascript"
src="https://dev.geosprocket.com/hon/js/wax.g.js">
<script type="text/javascript">
getTileUrl: function(coord, zoom) {
//var ret = "tiles/"+zoom+"/"+coord.x+"/"+coord.y+".png";
var ret = "https://s3.amazonaws.com/dotmap_tiles/"+zoom+"/"+coord.x+"/"+coord.y+".png";
var ret = "https://s3.amazonaws.com/dotmap_tiles/"+zoom+"/"+coord.x+"/"+coord.y+".png";
var ret = "https://mt"+((coord.x+coord.y)%4)+".bmander.com/tiles/"+zoom+"/"+coord.x+"/"+coord.y+".png";
tileSize: new google.maps.Size(256, 256),
function setViewportFromArgs(){
var urlhash = window.location.hash;
urlhash = urlhash.substring(1); //remove the hash
var parts = urlhash.split("&");
for(var i=0; i<parts.length; i++){
var keyval = parts[i].split("=");
if(keyval[0]==="lat" || keyval[0]==="lon") {
coord[keyval[0]] = parseFloat(keyval[1])
} else if(keyval[0]==="z"){
coord.z = parseInt(keyval[1]);
if( coord.lat && coord.lon ){
var dotMapType = new google.maps.ImageMapType(dotTypeOptions);
wax.tilejson('https://api.tiles.mapbox.com/v3/landplanner.map-73h9vsq0.jsonp', function(tilejson) {
var myLatlng = new google.maps.LatLng(lat, lon);
streetViewControl: false,
backgroundColor:"ffffff",
mapTypeIds: ["dot", google.maps.MapTypeId.ROADMAP],
style: google.maps.MapTypeControlStyle.DEFAULT
map = new google.maps.Map(document.getElementById("map_canvas"),
map.mapTypes.set('dot', dotMapType);
map.overlayMapTypes.insertAt(0, new wax.g.connector(tilejson));
function roundToPlace(x,places){
return Math.round(x*Math.pow(10,places))/Math.pow(10,places);
<body onload="initialize()">
<div id="map_canvas" style="width:80%; height:100%; float:left"></div>
<div style="float:left;width:20%">
<div style="padding:5px">
<h3>What's all this?</h3>
<p>This is a map of every person counted by the 2010 US and 2011 Canadian censuses. The map has <b>341,817,095</b> dots - one for each person.</p>
<p>I wanted an image of human settlement patterns unmediated by proxies like city boundaries, arterial roads, state lines, &c. Also, it was an interesting challenge.</p>
<h3>Who is responsible for this?</h3>
<p>The US and Canadian censuses, mostly. I made the map. I'm <a href="https://twitter.com/ewedistrict">Brandon Martin-Anderson.</a> <a href="https://twitter.com/kieran">Kieran Huggins</a> came to the rescue with spare server capacity and technical advice once this took off.</p>
<p>I wrote a Python script to generate points from US Census block-level counts, and then generated the tiles with Processing. Here's <a href="methods.html">more detail for the interested</a>.</p>
<h3>I don't see dots. I see smudges.</h3>
<p>The dots are very small. Try zooming in.</p>
<h3>Nobody lives in Central Park/Pier 12/County Lockup/Abandoned Themepark.</h3>
<p>The census reported that someone lived there.</p>
<h3>This says someone lives in the middle of a lake.</h3>
<p>The census reported that someone lives in a block which includes a lake, and that's where their dot was randomly placed. Also, some people live in the middle of lakes.</p>
<a href="#" onclick="window.location.hash='lat='+roundToPlace(map.getCenter().lat(),6)+'&lon='+roundToPlace(map.getCenter().lng(),6)+'&z='+map.getZoom();return false;" style="margin-top:10px;background-color:#ffeeee">link to this map</a>