Art by Christoph Niemann at the Googleplex
$ curl -Lo abs_suburbs.zip "http://www.abs.gov.au/AUSSTATS/subscriber.nsf/log?openagent&1270055003_ssc_2011_aust_shape.zip&1270.0.55.003&Data%20Cubes&D68DFFC14D31F4E1CA2578D40013268D&0&July%202011&22.07.2011&Previous"
$ unzip abs_suburbs.zip
$ ogr2ogr -f GeoJSON sydney.geojson SSC_2011_AUST.shp -clipsrc 150.84 -33.73 151.32 -34.09
d3.json("sydney.geojson", function(error, map_features) {
console.log(map_features);
});
var width = 900, height = 700;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var projection = d3.geo.mercator()
.center([151.15, -33.90])
.scale(98000)
.translate([width / 2, height / 2]);
d3.json("sydney.geojson", function(error, map_features) {
svg.append("path")
.datum(map_features)
.attr("d", d3.geo.path().projection(projection));
});
var width = 900, height = 700;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var projection = d3.geo.mercator()
.center([151.15, -33.88])
.scale(120000)
.translate([width / 2, height / 2]);
var path = d3.geo.path().projection(projection);
d3.json("sydney.geojson", function(error, map_features) {
svg.selectAll("path")
.data(map_features.features)
.enter().append("path")
.attr("class", "suburb")
.attr("d", path);
});
svg {
background: #deebf7;
}
path.suburb {
stroke: #d95f0e;
fill: #fff7bc;
}
Armchair Antarctica, GovHack Perth “best mapping application” winner
Shanghai and Zhejiang province, as seen through Mapbox
words: [
"Archers", "vs", "Zombies!",
...
"BlackBerry",
...
"horrible", "kludges"
]
words: [
"Faster,", "easier", "and", "safer",
...
"AngularJS",
...
"Tom", "Walker", "Cognizance"
],
var stopwords = ["and", "the", "with", "for", "to", "of", "in", "from", "a", "can", "but", "get", "an", "so"];
data.forEach(function(item) {
var word_hash = {};
item.words.forEach(function(word) {
if (stopwords.indexOf(word) !== -1) {
return;
}
if (word in word_hash) {
word_hash[word] ++;
} else {
word_hash[word] = 1;
}
});
var wordset = [];
for (var word in word_hash) {
wordset.push({ key: word, value: word_hash[word] });
if (word_hash[word] > max_count) { max_count = word_hash[word]; }
}
});
var fill = d3.scale.category10();
var draw = function(word_data, svg_el) {
d3.select("body").append("svg")
.selectAll("text")
.data(word_data)
.enter().append("text")
.style("font-size", function(d) { return d.size + "px"; })
.style("font-family", "Impact, sans-serif")
.style("fill", function(d, i) { return fill(i); })
.attr("text-anchor", "middle")
.attr("transform", function(d) {
return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
})
.text(function(d) { return d.key; })
}
var layoutWords = function(wordset, i, fontScale) {
var layout = d3.layout.cloud()
.size([450, 450])
.text(function(d) { return d.key; })
.font("Impact")
.fontSize(function(d) { return fontScale(+d.value); })
.rotate(function(d) { return ~~(Math.random() * 4) * 45 - 90; })
.padding(1)
.on("end", function(word_data) {
draw(word_data, g[i]);
})
.words(wordset)
.start();
}
var fontScale = d3.scale.log().range([5, max_count * 3]);
layoutWords(wordset, idx, fontScale);
<div id="map"></div>
<script src="http://cdn.leafletjs.com/leaflet-0.7.1/leaflet.js"></script>
<script>
var map = new L.Map("map", {center: [-33.8691, 151.20538], zoom: 17});
var tileLayer = new L.TileLayer(
"http://{s}.tile.cloudmade.com/API_KEY/998/256/{z}/{x}/{y}.png"
);
map.addLayer(tileLayer);
</script>
map.getPanes().overlayPane
var svg = d3.select(map.getPanes().overlayPane).append("svg");
var fontScale = d3.scale.log().range([5, max_count * 3]);
wordsets.forEach(function(wordset, idx) {
g[idx] = svg.append("g")
.attr("class", "leaflet-zoom-hide");
layoutWords(wordset, idx, fontScale);
});
map.on("moveend", resetSVG);
var resetSVG = function() {
var ctopleft = map.containerPointToLatLng(
L.point(0,0)
);
var ltopleft = map.latLngToLayerPoint(ctopleft);
var cbottomright = map.containerPointToLatLng(
L.point(mapOriginalWidth,mapOriginalHeight)
);
var lbottomright = map.latLngToLayerPoint(cbottomright);
svg.style("left", ltopleft.x + "px")
.style("top", ltopleft.y + "px");
var zoom_level = Math.pow(2, (map.getZoom() - mapOriginalZoom));
for (var i = 0; i < g.length; i ++) {
var word_centre = map.latLngToContainerPoint(new L.LatLng(data[i].lat, data[i].long));
g[i].attr(
"transform", "scale(" + zoom_level + ")"
+ "translate(" + (word_centre.x / zoom_level) + "," + (word_centre.y / zoom_level) + ")"
);
}
}
var mapTopLeft = map.layerPointToLatLng(L.point(0, 0));
var mapBottomRight = map.layerPointToLatLng(L.point(
$("#map").width(),
$("#map").height()
));
var mapOriginalWidth = $("#map").width();
var mapOriginalHeight = $("#map").height();
svg .attr("width", mapOriginalWidth)
.attr("height", mapOriginalHeight)
.style("left", "0px")
.style("top", "0px");
resetSVG();
(like iOS Maps flyover, but with better data)
These slides: hourann.com/2014/sydjs