Skip to content

Instantly share code, notes, and snippets.

@ilyabo
Created December 20, 2012 10:20
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save ilyabo/4344444 to your computer and use it in GitHub Desktop.
Briesemeister projection

Jacques Bertin mentions Briesemeister projection in "Semiology of graphics" as one of a few projections which give good general representations of the world. Most of the deformations are in the oceans and the continents are grouped closely together. It is thoroughly described in the book "Flattening the Earth: Two Thousand Years of Map Projections" by John P. Snyder (page 239).

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.background {
fill: #a4bac7;
}
.foreground {
fill: none;
stroke: #333;
stroke-width: 1.5px;
}
.graticule {
fill: none;
stroke: #fff;
stroke-width: .5px;
}
.graticule:nth-child(2n) {
stroke-dasharray: 2,2;
}
.land {
fill: #d7c7ad;
stroke: #766951;
}
.boundary {
fill: none;
stroke: #a5967e;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="http://d3js.org/topojson.v0.min.js"></script>
<script>
var width = 960,
height = 500;
// "Flattening the Earth: Two Thousand Years of Map Projections"
// By John P. Snyder page 240
// http://bit.ly/Uaq6O1
var briesemeister = (function() {
var R = 1;
var q = Math.sqrt(1.75);
return function(λ, φ) {
var D = 2/(1 + Math.cos(φ) * Math.cos(λ/2));
var x = R * Math.sqrt(3.5 * D) * Math.cos(φ) * Math.sin(λ/2);
var y = R * Math.sqrt(2 * D) * Math.sin(φ) / q;
return [x, y];
}
})();
// var briesemeister = (function() {
// var R = 1;
// var q = Math.sqrt(1.75);
// return function(λ, φ) {
// var c = d3.geo.hammer.raw(λ, φ);
// c[0] /= q;
// return c;
// }
// })();
briesemeister.invert = function(x, y) {
// TODO
return d3.geo.hammer.raw.invert(x, y);
};
d3.geo.briesemeister = function() {
return d3.geo.projection(briesemeister);
};
var projection = d3.geo.briesemeister()
// .scale(1000)
//.rotate([-15, 0])
.rotate([-10, -45])
//.parallels([29.5, 45.5])
//.clipAngle(180 - 1e-3);
var path = d3.geo.path()
.projection(projection);
var graticule = d3.geo.graticule();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.append("path")
.datum(graticule.outline)
.attr("class", "background")
.attr("d", path);
svg.selectAll(".graticule")
.data(graticule.lines)
.enter().append("path")
.attr("class", "graticule")
.attr("d", path);
svg.append("path")
.datum(graticule.outline)
.attr("class", "foreground")
.attr("d", path);
d3.json("/d/4090846/world-110m.json", function(error, world) {
svg.insert("path", ".graticule")
.datum(topojson.object(world, world.objects.land))
.attr("class", "land")
.attr("d", path);
svg.insert("path", ".graticule")
.datum(topojson.mesh(world, world.objects.countries, function(a, b) { return a.id !== b.id; }))
.attr("class", "boundary")
.attr("d", path);
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment