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);
}
});
};
}