Skip to content

Instantly share code, notes, and snippets.

@Fil
Last active September 2, 2017 13:41
Show Gist options
  • Save Fil/5faf7ee46a823a85efc3cea99a463c85 to your computer and use it in GitHub Desktop.
Save Fil/5faf7ee46a823a85efc3cea99a463c85 to your computer and use it in GitHub Desktop.
Poor man's Composite projection
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
path { fill: none; stroke: black; }
#land { fill: black }
#sphere { stroke-width: 2; fill: lightblue; }
#invert { fill: red}
</style>
</head>
<body>
<script>
// Feel free to change or delete any of the code you see in this editor!
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500)
var projections = [
d3.geoLagrange()
.clipExtent([[0,0],[480,250]]),
d3.geoAzimuthalEqualArea()
.clipExtent([[480,0],[960,250]]),
d3.geoOrthographic()
.clipExtent([[0,250],[480,500]]),
d3.geoAzimuthalEquidistant()
.clipExtent([[480,250],[960,500]])
];
//o = d3.geoCircle().center([0,0]).radius(10)();
var paths = projections.map(p => d3.geoPath(p));
var projection = {};
projection.invert = function(p) {
for( var i = 0; i < projections.length; i++) {
var k = projections[i].invert(p);
if (k && paths[i]({type:"Point", coordinates: k}))
return k;
}
}
svg.on('mousemove', function(){
var m = d3.mouse(this);
point.datum({
type:"Point",
coordinates: projection.invert(m)
})
})
var path = function(d) {
return paths.map(p => p(d))
.filter(d => !!d)
.join("") || null;
}
svg.append("path")
.attr("id", "sphere")
.datum({type: "Sphere"})
.attr('d', d3.geoPath(d3.geoOrthographic()))
svg.append("path")
.datum(d3.geoGraticule()())
.classed('composite', true)
var land = svg.append("path")
.attr('id', 'land')
.classed('composite', true);
var point = svg.append("path")
.attr('id', "invert")
.classed('composite', true)
.datum({ type:"Point", coordinates: [1,2] })
d3.json("https://unpkg.com/world-atlas@1/world/110m.json", function(
error,
world
) {
land.datum(topojson.merge(world, world.objects.countries.geometries));
}
);
if (1)
d3.timer(_ => {
projections[0].rotate([_/100, 0])
projections[1].rotate([30, _/100, -_/100])
projections[2].rotate([_/100, 0, -_/100])
projections[3].rotate([_/100, _/100, _/100])
svg.selectAll('path.composite')
.attr("d", path);
})
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment