A fork of Mike Bostock's Snowden route map, adding visualisation of route direction and information about flights known to have been taken vs those not taken (or atleast not known to have been taken)
Oliver O’Brien’s original analysis of Snowden Route Maps.
xxxxxxxxxx
<meta charset="utf-8">
<style>
body {
background: #fcfcfa;
}
.stroke {
fill: none;
stroke: #999;
stroke-width: 3px;
}
.fill {
fill: #fff;
}
.graticule {
fill: none;
stroke: #ddd;
stroke-width: .5px;
stroke-opacity: .5;
}
.land {
fill: #ddd;
}
.boundary {
fill: none;
stroke: #fff;
stroke-width: .5px;
}
.points circle {
fill: #fff;
stroke: red;
stroke-width: 2px;
}
.points text {
font: 11px sans-serif;
text-anchor: middle;
text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
}
.route {
fill: none;
stroke: red;
stroke-width: 3px;
}
.possible-route {
stroke-dasharray:5, 5;
fill: none;
stroke: red;
stroke-width: 3px;
}
.arrowHead{
fill:red;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script>
var width = 960,
height = 570;
var places = {
HNL: [-157 - 55 / 60 - 21 / 3600, 21 + 19 / 60 + 07 / 3600],
HKG: [113 + 54 / 60 + 53 / 3600, 22 + 18 / 60 + 32 / 3600],
SVO: [37 + 24 / 60 + 53 / 3600, 55 + 58 / 60 + 22 / 3600],
HAV: [-82 - 24 / 60 - 33 / 3600, 22 + 59 / 60 + 21 / 3600],
CCS: [-66 - 59 / 60 - 26 / 3600, 10 + 36 / 60 + 11 / 3600],
UIO: [-78 - 21 / 60 - 31 / 3600, 0 + 06 / 60 + 48 / 3600]
};
var routes = {
known:[
[ places.HNL, places.HKG ],
[ places.HKG, places.SVO ]
],
possible:[
[ places.SVO, places.HAV ],
[ places.HAV, places.CCS ],
[ places.CCS, places.UIO ]
]
};
var projection = d3.geo.kavrayskiy7()
.scale(170)
.rotate([-40, 0])
.translate([width / 2, height / 2])
.precision(.1);
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("defs").append("path")
.datum({type: "Sphere"})
.attr("id", "sphere")
.attr("d", path);
d3.select("defs")
.append("marker")
.attr("id", "arrow")
.attr("viewBox", "0 -5 10 10")
.attr("refX", 15)
.attr("refY", 0)
.attr("markerWidth", 4)
.attr("markerHeight", 4)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5")
.attr("class","arrowHead");
svg.append("use")
.attr("class", "stroke")
.attr("xlink:href", "#sphere");
svg.append("use")
.attr("class", "fill")
.attr("xlink:href", "#sphere");
svg.append("path")
.datum(graticule)
.attr("class", "graticule")
.attr("d", path);
for(var i=0;i<routes.known.length;i++){
svg.append("path")
.datum({
type:"LineString",
coordinates:routes.known[i]
})
.attr("class", "route")
.attr("d", path)
.attr("marker-end", "url(#arrow)");
}
for(var i=0;i<routes.possible.length;i++){
svg.append("path")
.datum({
type:"LineString",
coordinates:routes.possible[i]
})
.attr("class", "possible-route")
.attr("d", path)
.attr("marker-end", "url(#arrow)");
}
var point = svg.append("g")
.attr("class", "points")
.selectAll("g")
.data(d3.entries(places))
.enter().append("g")
.attr("transform", function(d) { return "translate(" + projection(d.value) + ")"; });
point.append("circle")
.attr("r", 4.5);
point.append("text")
.attr("y", 10)
.attr("dy", ".71em")
.text(function( d ) { return d.key; });
d3.json("/../../data/world-50m.json", function(error, world) {
svg.insert("path", ".graticule")
.datum(topojson.feature(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 !== b; }))
.attr("class", "boundary")
.attr("d", path);
});
d3.select(self.frameElement).style("height", height + "px");
</script>
Modified http://d3js.org/d3.v3.min.js to a secure url
Modified http://d3js.org/d3.geo.projection.v0.min.js to a secure url
Modified http://d3js.org/topojson.v1.min.js to a secure url
Changed /mbostock/raw/4090846/world-50m.json to a local referenece
https://d3js.org/d3.v3.min.js
https://d3js.org/d3.geo.projection.v0.min.js
https://d3js.org/topojson.v1.min.js