D3 & TopoJSON sample for Austria.
Idea and tutorial: Let's Make a Map by Mike Bostock
Makefile for build of TopoJSON 'aut.json': Why Use Make by Mike Bostock
D3 & TopoJSON sample for Austria.
Idea and tutorial: Let's Make a Map by Mike Bostock
Makefile for build of TopoJSON 'aut.json': Why Use Make by Mike Bostock
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
.subunit.AUT { fill: #dcd; } | |
.place, | |
.place-label { | |
fill: #444; | |
} | |
text { | |
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
font-size: 10px; | |
pointer-events: none; | |
} | |
.subunit-boundary { | |
fill: none; | |
stroke: #777; | |
stroke-dasharray: 2,2; | |
stroke-linejoin: round; | |
} | |
.subunit-label { | |
fill: #777; | |
fill-opacity: .5; | |
font-size: 20px; | |
font-weight: 300; | |
text-anchor: middle; | |
} | |
</style> | |
<body> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script src="http://d3js.org/topojson.v1.min.js"></script> | |
<script> | |
var width = 960, | |
height = 1160; | |
var projection = d3.geo.albers() | |
.center([0, 45.5]) | |
.rotate([-13.8, 0]) | |
.parallels([40, 50]) | |
.scale(9000) | |
.translate([width / 2, height / 2]); | |
var path = d3.geo.path() | |
.projection(projection) | |
.pointRadius(2); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
d3.json("aut.json", function(error, aut) { | |
console.log(aut); | |
svg.selectAll(".subunit") | |
.data(topojson.feature(aut, aut.objects.subunits).features) | |
.enter().append("path") | |
.attr("class", function(d) { | |
return "subunit " + d.id; | |
}) | |
.attr("d", path); | |
svg.append("path") | |
.datum(topojson.feature(aut, aut.objects.places)) | |
.attr("d", path) | |
.attr("class", "place"); | |
svg.selectAll(".place-label") | |
.data(topojson.feature(aut, aut.objects.places).features) | |
.enter().append("text") | |
.attr("class", "place-label") | |
.attr("transform", function(d) { return "translate(" + projection(d.geometry.coordinates) + ")"; }) | |
.attr("dy", ".35em") | |
.text(function(d) { return d.properties.name; }); | |
svg.selectAll(".place-label") | |
.attr("x", function(d) { return d.geometry.coordinates[0] > 16.3 ? 6 : -6; }) | |
.style("text-anchor", function(d) { return d.geometry.coordinates[0] > 16.3 ? "start" : "end"; }); | |
svg.selectAll(".subunit-label") | |
.data(topojson.feature(aut, aut.objects.subunits).features) | |
.enter().append("text") | |
.attr("class", function(d) { return "subunit-label " + d.id; }) | |
.attr("transform", function(d) { return "translate(" + path.centroid(d) + ")"; }) | |
.attr("dy", ".35em") | |
.text(function(d) { return d.properties.name; }); | |
}); | |
</script> | |
</body> |
aut.json: subunits.json places.json | |
topojson --id-property su_a3 -p name=NAME -p name -o aut.json subunits.json places.json | |
subunits.json: ne_10m_admin_0_map_subunits.shp | |
ogr2ogr -f GeoJSON -where "adm0_a3 IN ('AUT')" subunits.json ne_10m_admin_0_map_subunits.shp | |
places.json: ne_10m_populated_places.shp | |
ogr2ogr -f GeoJSON -where "iso_a2 = 'AT' AND SCALERANK < 20" places.json ne_10m_populated_places.shp | |
ne_10m_admin_0_map_subunits.shp: subunits.zip | |
unzip subunits.zip | |
touch ne_10m_admin_0_map_subunits.shp | |
ne_10m_populated_places.shp: places.zip | |
unzip places.zip | |
touch ne_10m_populated_places.shp | |
subunits.zip: | |
curl -o subunits.zip 'http://www.nacis.org/naturalearth/10m/cultural/ne_10m_admin_0_map_subunits.zip' | |
places.zip: | |
curl -o places.zip 'http://www.nacis.org/naturalearth/10m/cultural/ne_10m_populated_places.zip' | |
clean: | |
rm `ls | grep -v 'zip' | grep -v 'Makefile' ` |