|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<title>RAT PROJECTION!</title> |
|
<style> |
|
body{ text-align: center } |
|
</style> |
|
|
|
<div id="map"></div> |
|
|
|
<select id="projection-menu"></select> |
|
|
|
<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/d3.geo.polyhedron.v0.min.js"></script> |
|
<script> |
|
|
|
var ratio = window.devicePixelRatio || 1, |
|
width = 960 * ratio, |
|
height = 450 * ratio; |
|
|
|
var options = [ |
|
{name: "Aitoff", projection: d3.geo.aitoff()}, |
|
{name: "Albers", projection: d3.geo.albers().scale(145).parallels([20, 50])}, |
|
{name: "August", projection: d3.geo.august().scale(60)}, |
|
{name: "Baker", projection: d3.geo.baker().scale(100)}, |
|
{name: "Berghaus", projection: d3.geo.berghaus().scale(100)}, |
|
{name: "Boggs", projection: d3.geo.boggs()}, |
|
{name: "Bonne", projection: d3.geo.bonne().scale(100)}, |
|
{name: "Bromley", projection: d3.geo.bromley()}, |
|
{name: "Collignon", projection: d3.geo.collignon().scale(93)}, |
|
{name: "Craster Parabolic", projection: d3.geo.craster()}, |
|
{name: "Eckert I", projection: d3.geo.eckert1().scale(165)}, |
|
{name: "Eckert II", projection: d3.geo.eckert2().scale(165)}, |
|
{name: "Eckert III", projection: d3.geo.eckert3().scale(180)}, |
|
{name: "Eckert IV", projection: d3.geo.eckert4().scale(180)}, |
|
{name: "Eckert V", projection: d3.geo.eckert5().scale(170)}, |
|
{name: "Eckert VI", projection: d3.geo.eckert6().scale(170)}, |
|
{name: "Eisenlohr", projection: d3.geo.eisenlohr().scale(60)}, |
|
{name: "Equirectangular (Plate Carrée)", projection: d3.geo.equirectangular()}, |
|
{name: "Fahey", projection: d3.geo.fahey().scale(120)}, |
|
{name: "Gall Stereographic", projection: d3.geo.cylindricalStereographic().parallel(45).scale(140)}, |
|
{name: "Goode Homolosine", projection: d3.geo.homolosine()}, |
|
{name: "Ginzburg IV", projection: d3.geo.ginzburg4().scale(120)}, |
|
{name: "Ginzburg V", projection: d3.geo.ginzburg5().scale(120)}, |
|
{name: "Ginzburg VI", projection: d3.geo.ginzburg6().scale(120)}, |
|
{name: "Ginzburg VIII", projection: d3.geo.ginzburg8().scale(120)}, |
|
{name: "Ginzburg IX", projection: d3.geo.ginzburg9().scale(120)}, |
|
{name: "Gringorten", projection: d3.geo.gringorten().scale(220)}, |
|
{name: "Guyou", projection: d3.geo.guyou().scale(150)}, |
|
{name: "Hammer", projection: d3.geo.hammer().scale(165)}, |
|
{name: "Hammer Retroazimuthal", projection: d3.geo.hammerRetroazimuthal().scale(90)}, |
|
{name: "HEALPix", projection: d3.geo.healpix()}, |
|
{name: "Hill", projection: d3.geo.hill().scale(120)}, |
|
{name: "Kavrayskiy VII", projection: d3.geo.kavrayskiy7()}, |
|
{name: "Lagrange", projection: d3.geo.lagrange().scale(120)}, |
|
{name: "Lambert cylindrical equal-area", projection: d3.geo.cylindricalEqualArea()}, |
|
{name: "Larrivée", projection: d3.geo.larrivee().scale(95)}, |
|
{name: "Laskowski", projection: d3.geo.laskowski().scale(120)}, |
|
{name: "Loximuthal", projection: d3.geo.loximuthal()}, |
|
{name: "Mercator", projection: d3.geo.mercator().scale(100)}, |
|
{name: "Miller", projection: d3.geo.miller().scale(100)}, |
|
{name: "McBryde–Thomas Flat-Polar Parabolic", projection: d3.geo.mtFlatPolarParabolic()}, |
|
{name: "McBryde–Thomas Flat-Polar Quartic", projection: d3.geo.mtFlatPolarQuartic()}, |
|
{name: "McBryde–Thomas Flat-Polar Sinusoidal", projection: d3.geo.mtFlatPolarSinusoidal()}, |
|
{name: "Mollweide", projection: d3.geo.mollweide().scale(165)}, |
|
{name: "Natural Earth", projection: d3.geo.naturalEarth()}, |
|
{name: "Nell–Hammer", projection: d3.geo.nellHammer()}, |
|
{name: "Orthographic", projection: d3.geo.orthographic().scale(200)}, |
|
{name: "Polyconic", projection: d3.geo.polyconic().scale(100)}, |
|
{name: "Rectangular Polyconic", projection: d3.geo.rectangularPolyconic().scale(120)}, |
|
{name: "Robinson", projection: d3.geo.robinson()}, |
|
{name: "Sinusoidal", projection: d3.geo.sinusoidal()}, |
|
{name: "Sinu-Mollweide", projection: d3.geo.sinuMollweide()}, |
|
{name: "Stereographic", projection: d3.geo.stereographic()}, |
|
{name: "Times", projection: d3.geo.times().scale(140)}, |
|
{name: "Van der Grinten", projection: d3.geo.vanDerGrinten().scale(75)}, |
|
{name: "Van der Grinten II", projection: d3.geo.vanDerGrinten2().scale(75)}, |
|
{name: "Van der Grinten III", projection: d3.geo.vanDerGrinten3().scale(75)}, |
|
{name: "Van der Grinten IV", projection: d3.geo.vanDerGrinten4().scale(120)}, |
|
{name: "Wagner IV", projection: d3.geo.wagner4()}, |
|
{name: "Wagner VI", projection: d3.geo.wagner6()}, |
|
{name: "Wagner VII", projection: d3.geo.wagner7()}, |
|
{name: "Waterman", projection: d3.geo.polyhedron.waterman().scale(70)}, |
|
{name: "Winkel Tripel", projection: d3.geo.winkel3()} |
|
]; |
|
|
|
var menu = d3.select("#projection-menu") |
|
.on("change", change); |
|
|
|
menu.selectAll("option") |
|
.data(options) |
|
.enter().append("option") |
|
.text(function(d) { return d.name; }); |
|
|
|
function change() { |
|
update(options[this.selectedIndex]); |
|
} |
|
|
|
var i = 0, |
|
n = options.length - 1; |
|
|
|
rando(); |
|
|
|
var projection = options[i].projection; |
|
|
|
options.forEach(function(option) { |
|
option.projection |
|
.translate([width / 2, height / 2]) |
|
.scale(option.projection.scale() * ratio) |
|
.clipExtent([[2 * ratio, 2 * ratio], [width - 2 * ratio, height - 2 * ratio]]); |
|
}); |
|
|
|
var graticule = d3.geo.graticule()(), |
|
rat, |
|
boundaries; |
|
|
|
var canvas = d3.select("#map").append("canvas") |
|
.attr("width", width) |
|
.attr("height", height) |
|
.style("width", width / ratio + "px") |
|
.style("height", height / ratio + "px"); |
|
|
|
var context = canvas.node().getContext("2d"); |
|
context.fillStyle = "#f9f9f9"; |
|
context.strokeStyle = "#000"; |
|
|
|
var path = d3.geo.path() |
|
.projection(projection) |
|
.context(context); |
|
|
|
function rando() { |
|
var j = Math.floor(Math.random() * n); |
|
i = j + (j >= i); |
|
menu.property("selectedIndex", i = j + (j >= i)); |
|
} |
|
|
|
function change() { |
|
update(options[this.selectedIndex]); |
|
} |
|
|
|
function pathTween(projection0, projection1) { |
|
var t = 0, |
|
projection = d3.geo.projection(function(λ, φ) { |
|
λ *= 180 / Math.PI, φ *= 180 / Math.PI; |
|
var p0 = projection0([λ, φ]), p1 = projection1([λ, φ]); |
|
return [(1 - t) * p0[0] + t * p1[0], (1 - t) * -p0[1] + t * -p1[1]]; |
|
}) |
|
.scale(1) |
|
.translate([width / 2, height / 2]) |
|
.clipExtent(projection0.clipExtent()), |
|
path = d3.geo.path().projection(projection).context(context); |
|
return function() { |
|
return function(u) { |
|
t = u; |
|
redraw(path); |
|
}; |
|
}; |
|
} |
|
|
|
function update(option) { |
|
canvas.transition() |
|
.duration(750) |
|
.ease( d3.ease("quad") ) |
|
.tween("path", pathTween(projection, projection = option.projection)); |
|
path.projection(projection); |
|
} |
|
|
|
function redraw(path) { |
|
context.clearRect(0, 0, width, height); |
|
context.lineWidth = .5 * ratio; |
|
|
|
context.strokeStyle = "#999"; |
|
context.beginPath(), path(graticule), context.stroke(); |
|
|
|
context.beginPath(), path({type: "Sphere"}), context.stroke(); |
|
|
|
context.lineWidth = 2 * ratio; |
|
|
|
if (rat) { |
|
context.fillStyle = "#000"; |
|
context.beginPath(), path(rat), context.fill(); |
|
} |
|
} |
|
|
|
d3.json("/awoodruff/raw/9180acad6ee2b6b580a0/WorldRat.json", function(error, data) { |
|
rat = data; |
|
redraw(path) |
|
}); |
|
|
|
</script> |
|
</body> |
|
</html> |