Public
Edited
Nov 28, 2023
Importers
5 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
computeStewart = new gpujs.GPU()
.addFunction(function haversineDistance(lon1, lat1, lon2, lat2) {
lat1 *= this.constants.deg2rad;
lon1 *= this.constants.deg2rad;
lat2 *= this.constants.deg2rad;
lon2 *= this.constants.deg2rad;
const dLat = lat2 - lat1;
const dLon = lon2 - lon1;
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1) * Math.cos(lat2) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return this.constants.R * c;
},
{ argumentTypes: { lon1: 'Number',lat1: 'Number', lon2: 'Number',lat2: 'Number'}, returnType: 'Number' },
)
.createKernel(function computeStewartGPU(x_cell, y_cell, x_dot, y_dot, values) {
let sum = 0;
for (let i = 0; i < this.constants.size; i++) {
const dist = this.haversineDistance(x_dot[i], y_dot[i], x_cell[this.thread.x], y_cell[this.thread.x]);
sum = sum + (values[i] * Math.exp(-this.constants.alpha * Math.pow(dist, this.constants.beta)));
}
return sum;
}, {
constants: {
size: inputPoints.length,
alpha: alpha,
beta: beta,
R: 6371 * 2,
deg2rad: Math.PI / 180,
},
output: [grid.features.length],
},
);
Insert cell
computeStewartWorker = {
const worker_code = `
function haversine_dist(lon1, lat1, lon2, lat2, deg2rad = Math.PI / 180) {
const R = 6371 * 2;
lat1 *= deg2rad;
lon1 *= deg2rad;
lat2 *= deg2rad;
lon2 *= deg2rad;
const dLat = lat2 - lat1;
const dLon = lon2 - lon1;
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1) * Math.cos(lat2) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
};

onmessage = function (e) {
const [
cells,
knownpts,
beta,
span,
alpha,
] = e.data;

const nb_cell = cells.length;
const nb_knownpts = knownpts.length;

const func = dist => Math.exp(-alpha * Math.pow(dist, beta));
let cell, x, y, value, coords;
let pot = new Array(nb_cell);
for (let i = 0; i < nb_cell; i++) {
cell = cells[i];
coords = cell.geometry.coordinates;
let sum = 0;
for (let j = 0; j < nb_knownpts; j++) {
[x, y, value] = knownpts[j];
sum += value * func(haversine_dist(x, y, coords[0], coords[1]));
}
pot[i] = sum;
}
postMessage(pot);
}
`
const blob = new Blob([worker_code], { type: "text/javascript" });

return async (gridCells, inputPoints) => {
const oUrl = window.URL.createObjectURL(blob);
const worker = new Worker(oUrl);
return new Promise((resolve, reject) => {
try {
worker.onmessage = result => {
resolve(result.data);
worker.terminate();
window.URL.revokeObjectURL(oUrl);
};
worker.onerror = error => {
reject(error);
worker.terminate();
window.URL.revokeObjectURL(oUrl);
};
worker.postMessage([
gridCells,
inputPoints,
beta,
span,
alpha,
]);
} catch (error) {
reject(error);
}
});
};
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
turf = await require('https://cdn.jsdelivr.net/npm/@turf/turf@6.5.0/turf.min.js')
Insert cell
gpujs = require("gpu.js")
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