Published
Edited
Aug 26, 2019
3 forks
26 stars
Insert cell
Insert cell
Insert cell
Insert cell
globe = spinningBall.init(globeDiv, [-95.3656049, 29.7537002], 11000)
Insert cell
Insert cell
camPosition = {
let moving = globe.update(now * 0.001);
renderGlobe(globe.cameraPos);
return globe.cameraPos;
}
Insert cell
Insert cell
Insert cell
globeDiv = html`<div></div>`;
Insert cell
Insert cell
Insert cell
Insert cell
context = {
const context = DOM.context2d(width, numPixelsY);
// Add the canvas to our globe div, after removing any existing child nodes
globeDiv.innerHTML = "";
globeDiv.appendChild(context.canvas);
return context;
}
Insert cell
Insert cell
Insert cell
Insert cell
function setProjection(camPos) {
let visibleYextent = 2 * camPos[2] * globe.view.maxRay[1];
let scale = globe.radius() * numPixelsY / visibleYextent;
let snyderP = 1 + camPos[2] / globe.radius();
let projection = d3.geoSatellite()
.translate([width / 2, numPixelsY / 2])
.scale(scale)
.rotate([-camPos[0] * degrees, -camPos[1] * degrees, 0])
.distance(snyderP)
.clipAngle(Math.acos(1 / snyderP) * degrees)
.precision(0.1);
return projection;
}
Insert cell
Insert cell
Insert cell
function renderLowRes(path) {
context.beginPath(), path(land110m), context.globalAlpha = 1.0, context.fill();
context.beginPath(), path(grid.major), context.strokeStyle = "#aaa", context.globalAlpha = 0.8, context.stroke();
context.beginPath(), path(grid.horizon), context.strokeStyle = "#000", context.stroke();
}
Insert cell
Insert cell
function renderHighRes(path) {
context.beginPath(), path(land50m), context.globalAlpha = 1.0, context.fill();
context.beginPath(), path(grid.minor), context.strokeStyle = "#aaa", context.globalAlpha = 0.4, context.stroke();
context.beginPath(), path(grid.major), context.strokeStyle = "#aaa", context.globalAlpha = 0.8, context.stroke();
context.beginPath(), path(grid.horizon), context.strokeStyle = "#000", context.stroke();
}
Insert cell
Insert cell
function renderGlobe(camPos) {
const projection = setProjection(camPos);
const path = d3.geoPath(projection, context);
context.clearRect(0, 0, width, numPixelsY);
globe.camMoving() ? renderLowRes(path) : renderHighRes(path);
//renderLowRes(path);
}
Insert cell
Insert cell
degrees = 180 / Math.PI;
Insert cell
numPixelsY = width * 0.6;
Insert cell
grid = ({
major: d3.geoGraticule().step([15,15])(),
minor: d3.geoGraticule().step([5,5])(),
horizon: ({type: "Sphere"})
})
Insert cell
land110m = fetch("https://cdn.jsdelivr.net/npm/world-atlas@1/world/110m.json")
.then(response => response.json())
.then(world => topojson.feature(world, world.objects.land));
Insert cell
land50m = fetch("https://cdn.jsdelivr.net/npm/world-atlas@1/world/50m.json")
.then(response => response.json())
.then(world => topojson.feature(world, world.objects.land));
Insert cell
topojson = require("topojson-client@3")
Insert cell
d3 = require("d3-geo@1", "d3-geo-projection@2")
Insert cell
spinningBall = import("spinning-ball@0.2.0")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more