-
Notifications
You must be signed in to change notification settings - Fork 18
/
index.html
executable file
·175 lines (155 loc) · 5.83 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
<!DOCTYPE html>
<html>
<head>
<title>Census Dotmap</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta name="og:url" content="http://bmander.com/dotmap/index.html" />
<meta name="og:title" content="Census Dotmap" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100% }
.button:hover {background-color:#ffdddd;}
.button {
cursor:pointer;
padding:2px;
border:solid;
border-width:1px;
font-size:small;
background-color:white;
display:inline-block;
}
</style>
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDM5hCtSjwpVyntcUPCOP1dzheF6JXcx5k&sensor=false">
</script>
<script type="text/javascript">
var dotTypeOptions = {
getTileUrl: function(coord, zoom) {
var ret = "data/tiles/"+zoom+"/"+coord.x+"/"+coord.y+".png";
/*
// left in to show hosted tile references
if( zoom <= 7 ){
var ret = "https://s3.amazonaws.com/dotmap_tiles/"+zoom+"/"+coord.x+"/"+coord.y+".png";
} else {
var ret = "https://s3.amazonaws.com/dotmap_tiles/"+zoom+"/"+coord.x+"/"+coord.y+".png";
var ret = "http://mt"+((coord.x+coord.y)%4)+".bmander.com/tiles/"+zoom+"/"+coord.x+"/"+coord.y+".png";
}
*/
return ret;
},
tileSize: new google.maps.Size(256, 256),
maxZoom: 14,
minZoom: 4,
name: "Census dots"
};
var acetateOptions = {
getTileUrl: function(coord, zoom) {
//var ret = "http://acetate.geoiq.com/tiles/acetate-labels/"+zoom+"/"+coord.x+"/"+coord.y+".png";
var ret = "http://a.tiles.mapbox.com/v3/landplanner.map-mcowljes/"+zoom+"/"+coord.x+"/"+coord.y+".png"
return ret;
},
tileSize: new google.maps.Size(256, 256),
maxZoom: 14,
minZoom: 4,
name: "Roads overlay"
};
var lat = 39.0;
var lon = -96.341308;
var zoom = 4;
var labels = false;
function setViewportFromArgs(){
var urlhash = window.location.hash;
if( urlhash != "" ){
urlhash = urlhash.substring(1); //remove the hash
var parts = urlhash.split("&");
var coord = {};
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]);
} else if(keyval[0]==="o"){
coord.o = keyval[1];
}
}
if( coord.lat && coord.lon ){
lat = coord.lat;
lon = coord.lon;
}
if( coord.z ){
zoom = coord.z;
}
if( coord.o ){
labels = coord.o==="t";
}
}
}
function realizeToggleState(){
var togglediv = document.getElementById("toggle");
if( labels ){
togglediv.innerHTML = "hide labels";
map.overlayMapTypes.push( acetateType );
} else {
togglediv.innerHTML = "show labels";
map.overlayMapTypes.pop();
}
}
function toggleLabels(){
labels = !labels;
realizeToggleState();
}
var dotMapType = new google.maps.ImageMapType(dotTypeOptions);
var acetateType = new google.maps.ImageMapType(acetateOptions);
var map;
function initialize() {
setViewportFromArgs();
var myLatlng = new google.maps.LatLng(lat, lon);
var mapOptions = {
center: myLatlng,
zoom: zoom,
streetViewControl: false,
backgroundColor:"ffffff",
mapTypeControl:false,
};
map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
map.mapTypes.set('dot', dotMapType);
map.setMapTypeId('dot');
realizeToggleState();
}
function roundToPlace(x,places){
return Math.round(x*Math.pow(10,places))/Math.pow(10,places);
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:80%; height:100%; float:left"></div>
<div style="background-color:#F2F2F2;float:left;width:20%;height:100%;overflow:scroll;">
<div style="padding:5px;font-size:small">
<span class="button" id="toggle" onclick="toggleLabels();">show labels</span>
<h1>Census Dotmap</h1>
<!--
<span class="button" onclick="window.location.hash='lat='+roundToPlace(map.getCenter().lat(),6)+'&lon='+roundToPlace(map.getCenter().lng(),6)+'&z='+map.getZoom()+'&o='+(labels?'t':'f');return false;">link to this map</span>
<h1>Census Dotmap</h1>
<p><a href="http://bmander.com/dotmap/store.html">Buy a print</a></blink>
<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>
<h3>Why?</h3>
<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>
<h3>How?</h3>
<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>
-->
</div>
</div>
</body>
</html>