Use d3.geo.bounds
and d3.geo.distance
to compute an approximate scale to display a complete feature.
Created
September 8, 2014 15:41
-
-
Save pnavarrc/62047b5638d624cfa9cb to your computer and use it in GitHub Desktop.
Automatic Scaling Features with D3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<title>Automatic Scaling Features with D3</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> | |
.country { | |
fill: #bbb; | |
stroke: #eee; | |
stroke-width: 1; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="map"></div> | |
<script> | |
var width = 600, | |
height = 600; | |
// Create the geographic projection | |
var projection = d3.geo.mercator() | |
.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); | |
d3.json('countries.topojson', function(error, data) { | |
if (error) { | |
console.error(error); | |
throw error; | |
} | |
var features = topojson.feature(data, data.objects.countries).features; | |
// Construct a feature for South America | |
// ------------------------------------- | |
// Filter out the countries outside South America | |
var southAmerica = features.filter(function(country) { | |
return country.properties.continent === 'South America'; | |
}); | |
var southAmericaFeature = { | |
type: 'FeatureCollection', | |
features: southAmerica | |
}; | |
// Compute the feature bounds and centroid | |
var bounds = d3.geo.bounds(southAmericaFeature), | |
center = d3.geo.centroid(southAmericaFeature); | |
// Compute the angular distance between bound corners | |
var distance = d3.geo.distance(bounds[0], bounds[1]), | |
scale = height / distance / Math.sqrt(2); | |
// Update the projection scale and centroid | |
projection.scale(scale).center(center); | |
// Draws the countries | |
var countries = grp.selectAll('path.country').data([southAmericaFeature]); | |
countries.enter().append('path').classed('country', true); | |
countries.attr('d', pathGenerator); | |
countries.exit().remove(); | |
}); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 -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