forked from mbostock's block: Satellite Projection
forked from basilesimon's block: Satellite Projection
license: gpl-3.0 |
forked from mbostock's block: Satellite Projection
forked from basilesimon's block: Satellite Projection
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
</style> | |
<body> | |
<script src="//d3js.org/d3.v4.min.js"></script> | |
<script src="//d3js.org/d3-geo-projection.v2.min.js"></script> | |
<script src="//d3js.org/topojson.v2.js"></script> | |
<script src="//unpkg.com/[email protected]/build/d3-jetpack.js"></script> | |
<button onclick="zoom()">click to zoom</button> | |
<canvas width="960" height="500"></canvas> | |
<script> | |
const canvas = d3.select("canvas"); | |
const width = canvas.property("width"); | |
const height = canvas.property("height"); | |
let context = canvas.node().getContext("2d"); | |
let projection = d3.geoSatellite() | |
.distance(1.1) | |
.scale(5000) | |
.rotate([-38, -33, -30]) | |
.center([0, 2]) | |
.tilt(30) | |
.precision(0.1); | |
let path = d3.geoPath(projection, context); | |
const zoom = d3.zoom() | |
//.scaleExtent([5000, 20000]) | |
.scaleExtent([1, 10]) | |
.on('zoom', zoomed); | |
const graticule = d3.geoGraticule() | |
.extent([[-10,30], [80, 80]]) | |
.step([3, 3]); | |
let render = function() {}; | |
const draw = (error, land, circle, camp) => { | |
render = (projection, context) => { | |
context.clearRect(0, 0, width, height); | |
path = d3.geoPath(projection, context); | |
context.strokeStyle = "#ccc"; | |
context.fillStyle = "#fff"; | |
context.beginPath(); | |
path(topojson.feature(land, land.objects.ne_10m_admin_0_countries2)); | |
context.fill(); | |
context.stroke(); | |
context.closePath(); | |
context.beginPath(); | |
context.strokeStyle = "rgba(255,0,0,0.3)"; | |
context.fillStyle = "rgba(255,0,0,0.1)"; | |
path(topojson.feature(circle, circle.objects.Circle_Measure)); | |
context.stroke(); | |
context.fill(); | |
context.closePath(); | |
const shelters = topojson.feature(camp, camp.objects.Rukban_Structures_20190121).features; | |
for (let i=0; i<shelters.length; i++) { | |
context.beginPath(); | |
const tent = shelters[i]; | |
context.moveTo(projection(tent.geometry.coordinates)[0] + 1, projection(tent.geometry.coordinates)[1]); | |
context.arc(projection(tent.geometry.coordinates)[0], projection(tent.geometry.coordinates)[1], 1, 0, 2 * Math.PI); | |
context.fillStyle = "rgba(0,0,0,0.1)"; | |
context.fill(); | |
context.closePath(); | |
} | |
}; | |
canvas.call(zoom); | |
render(projection, context); | |
} | |
function zoomed () { | |
const t = d3.event.transform; | |
console.log(t, d3.zoomIdentity); | |
context.save(); | |
// const proj = projection | |
// //.translate([t.x, t.y]) | |
// .scale(t.k); | |
context.scale(t.k, t.k); | |
context.translate(t.x, t.y); | |
render(projection, context); | |
context.restore(); | |
} | |
d3.queue() | |
.defer(d3.json, "https://gist.githubusercontent.com/basilesimon/e15cc6647a5ecc3c2c9b961215e8bf6b/raw/5733bff346be28f61ca2e2dcb982a82a48733bcd/sat.json") | |
.defer(d3.json, "https://gist.githubusercontent.com/basilesimon/20178b9d63dbda0fb8ed14590fcca036/raw/3214d4c452f83f7538d0b2c20e30d535711e8a80/circle.json") | |
.defer(d3.json, "https://gist.githubusercontent.com/basilesimon/614713d27f4c55d0392d77501f12b420/raw/8443dc30bb5f9b129a8e67e658c8c901a154f8fc/rukban.json") | |
.await(draw); | |
</script> |