Skip to content

Instantly share code, notes, and snippets.

@pnavarrc
Last active August 30, 2016 18:12
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pnavarrc/14ed098d4072be2715db to your computer and use it in GitHub Desktop.
Save pnavarrc/14ed098d4072be2715db to your computer and use it in GitHub Desktop.
Square Countries

Countries as Squares

Thumbnail

Small experiment of showing each country as a square. The center of each square is computed projecting the centroid of each feature, the (projected) area of each country is computed using the D3 path.area method.

References

Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
<html>
<head>
<title>Countries as Squares</title>
<script charset="utf-8" src="http://d3js.org/d3.v3.min.js"></script>
<script charset="utf-8" src="http://d3js.org/topojson.v1.min.js"></script>
<style>
body {
background-color: #222;
}
path.country {
fill: #333;
}
rect.country {
stroke: #5EFFEF;
stroke-opacity: 0.9;
stroke-width: 1;
fill: #5EFFEF;
fill-opacity: 0.05;
}
rect.highlighted {
fill-opacity: 0.6;
stroke-width: 1;
stroke: #78fff2;
}
.country-label {
pointer-events: none;
font-family: Arial, sans-serif;
font-size: 21px;
fill: #5EFFEF;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
var width = 800,
height = 400;
// Create the geographic projection
var projection = d3.geo.equirectangular()
.scale(width / (2 * Math.PI))
.translate([width / 2, height / 2]);
// Configure the path generator
var pathGenerator = d3.geo.path()
.projection(projection);
var div = d3.select('#map'),
svg = div.append('svg'),
grp = svg.append('g');
svg.attr('width', width).attr('height', height + 200);
grp.attr('transform', 'translate(' + [0, 100] + ')');
d3.json('countries.topojson', function(error, data) {
if (error) {
console.error(error);
throw error;
}
var geojson = topojson.feature(data, data.objects.countries).features;
// Compute the projected centroid, area and length of the side
// of the squares.
geojson.forEach(function(d) {
d.centroid = projection(d3.geo.centroid(d));
d.area = d3.geo.path().projection(projection).area(d);
d.side = Math.sqrt(d.area);
});
// Sort the features by projected area
geojson.sort(function(a, b) { return b.area - a.area; });
var countries = grp.selectAll('path.country').data(geojson);
countries.enter().append('path').classed('country', true);
countries.attr('d', pathGenerator);
countries.exit().remove();
// Squares
var squares = grp.selectAll('rect.country').data(geojson);
squares.enter().append('rect').classed('country', true);
squares
.attr('x', function(d) { return d.centroid[0] - d.side / 2; })
.attr('y', function(d) { return d.centroid[1] - d.side / 2; })
.attr('width', function(d) { return d.side; })
.attr('height', function(d) { return d.side; });
squares.on('mouseover', function(d) {
// Highlight on mouse over
d3.select(this).classed('highlighted', true);
grp.append('text')
.classed('country-label', true)
.attr('x', 20)
.attr('y', 0)
.text(d.properties.admin);
})
.on('mouseout', function(d) {
d3.select(this).classed('highlighted', false);
grp.selectAll('text.country-label').remove();
});
squares.exit().remove();
});
</script>
</body>
</html>
URL = http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/50m/cultural/ne_50m_admin_0_countries.zip
ne_50m_admin_0_countries.zip:
curl -LO $(URL)
ne_50m_admin_0_countries.shp: ne_50m_admin_0_countries.zip
unzip ne_50m_admin_0_countries.zip
touch ne_50m_admin_0_countries.shp
countries.json: ne_50m_admin_0_countries.shp
ogr2ogr -f GeoJSON countries.json ne_50m_admin_0_countries.shp
countries.topojson: countries.json
topojson -p admin -o countries.topojson countries.json
clean:
rm ne_50m_admin_0_countries*
rm countries.json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment