.html中的方法调用
let variogram=kriging.train(positions.map(pos=>pos[2]),positions.map(pos=>pos[0]),positions.map(pos=>pos[1]),params.krigingModel,params.krigingSigma2,params.krigingAlpha);
let grid=kriging.grid(polygons,variogram,(extent[2]-extent[0])/1000);
kriging.plot(canvas,grid,[extent[0],extent[2]],[extent[1],extent[3]],colors);
kriging-original.js文件中的部分代码解释
Array.prototype.max = function() {
return Math.max.apply(null, this);
Array.prototype.min = function() {
return Math.min.apply(null, this);
Array.prototype.mean = function() {
var i, sum;
for(i = 0, sum = 0; i < this.length; i++)
sum += this[i];
return sum / this.length;
Array.prototype.rep = function(n) {
return Array.apply(null, new Array(n))
.map(Number.prototype.valueOf, this[0]);
Array.prototype.pip = function(x, y) {
var i, j, c = false;
for(i = 0, j = this.length - 1; i < this.length; j = i++) {
if(((this[i][1] > y) != (this[j][1] > y)) &&
(x < (this[j][0] - this[i][0]) * (y - this[i][1]) / (this[j][1] - this[i][1]) + this[i][0])) {
c = !c;
return c;
var kriging = function() {
var kriging = {};
kriging_matrix_diag = function(c, n) {
var i, Z = [0].rep(n * n);
for(i = 0; i < n; i++) Z[i * n + i] = c;
return Z;
kriging_matrix_transpose = function(X, n, m) {
var i, j, Z = Array(m * n);
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
Z[j * n + i] = X[i * m + j];
return Z;
kriging_matrix_scale = function(X, c, n, m) {
var i, j;
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
X[i * m + j] *= c;
kriging_matrix_add = function(X, Y, n, m) {
var i, j, Z = Array(n * m);
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
Z[i * m + j] = X[i * m + j] + Y[i * m + j];
return Z;
kriging_matrix_multiply = function(X, Y, n, m, p) {
var i, j, k, Z = Array(n * p);
for(i = 0; i < n; i++) {
for(j = 0; j < p; j++) {
Z[i * p + j] = 0;
for(k = 0; k < m; k++)
Z[i * p + j] += X[i * m + k] * Y[k * p + j];
return Z;
kriging_matrix_chol = function(X, n) {
var i, j, k, sum, p = Array(n);
for(i = 0; i < n; i++) p[i] = X[i * n + i];
for(i = 0; i < n; i++) {
for(j = 0; j < i; j++)
p[i] -= X[i * n + j] * X[i * n + j];
if(p[i] <= 0) return false;
p[i] = Math.sqrt(p[i]);
for(j = i + 1; j < n; j++) {
for(k = 0; k < i; k++)
X[j * n + i] -= X[j * n + k] * X[i * n + k];
X[j * n + i] /= p[i];
for(i = 0; i < n; i++) X[i * n + i] = p[i];
return true;
kriging_matrix_chol2inv = function(X, n) {
var i, j, k, sum;
for(i = 0; i < n; i++) {
X[i * n + i] = 1 / X[i * n + i];
for(j = i + 1; j < n; j++) {
sum = 0;
for(k = i; k < j; k++)
sum -= X[j * n + k] * X[k * n + i];
X[j * n + i] = sum / X[j * n + j];
for(i = 0; i < n; i++)
for(j = i + 1; j < n; j++)
X[i * n + j] = 0;
for(i = 0; i < n; i++) {
X[i * n + i] *= X[i * n + i];
for(k = i + 1; k < n; k++)
X[i * n + i] += X[k * n + i] * X[k * n + i];
for(j = i + 1; j < n; j++)
for(k = j; k < n; k++)
X[i * n + j] += X[k * n + i] * X[k * n + j];
for(i = 0; i < n; i++)
for(j = 0; j < i; j++)
X[i * n + j] = X[j * n + i];
kriging_matrix_solve = function(X, n) {
var m = n;
var b = Array(n * n);
var indxc = Array(n);
var indxr = Array(n);
var ipiv = Array(n);
var i, icol, irow, j, k, l, ll;
var big, dum, pivinv, temp;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++) {
if(i == j) b[i * n + j] = 1;
else b[i * n + j] = 0;
for(j = 0; j < n; j++) ipiv[j] = 0;
for(i = 0; i < n; i++) {
big = 0;
for(j = 0; j < n; j++) {
if(ipiv[j] != 1) {
for(k = 0; k < n; k++) {
if(ipiv[k] == 0) {
if(Math.abs(X[j * n + k]) >= big) {
big = Math.abs(X[j * n + k]);
irow = j;
icol = k;
++(ipiv[icol]);
if(irow != icol) {
for(l = 0; l < n; l++) {
temp = X[irow * n + l];
X[irow * n + l] = X[icol * n + l];
X[icol * n + l] = temp;
for(l = 0; l < m; l++) {
temp = b[irow * n + l];
b[irow * n + l] = b[icol * n + l];
b[icol * n + l] = temp;
indxr[i] = irow;
indxc[i] = icol;
if(X[icol * n + icol] == 0) return false;
pivinv = 1 / X[icol * n + icol];
X[icol * n + icol] = 1;
for(l = 0; l < n; l++) X[icol * n + l] *= pivinv;
for(l = 0; l < m; l++) b[icol * n + l] *= pivinv;
for(ll = 0; ll < n; ll++) {
if(ll != icol) {
dum = X[ll * n + icol];
X[ll * n + icol] = 0;
for(l = 0; l < n; l++) X[ll * n + l] -= X[icol * n + l] * dum;
for(l = 0; l < m; l++) b[ll * n + l] -= b[icol * n + l] * dum;
for(l = (n - 1); l >= 0; l--)
if(indxr[l] != indxc[l]) {
for(k = 0; k < n; k++) {
temp = X[k * n + indxr[l]];
X[k * n + indxr[l]] = X[k * n + indxc[l]];
X[k * n + indxc[l]] = temp;
return true;
kriging_variogram_gaussian = function(h, nugget, range, sill, A) {
return nugget + ((sill - nugget) / range) *
(1.0 - Math.exp(-(1.0 / A) * Math.pow(h / range, 2)));
kriging_variogram_exponential = function(h, nugget, range, sill, A) {
return nugget + ((sill - nugget) / range) *
(1.0 - Math.exp(-(1.0 / A) * (h / range)));
kriging_variogram_spherical = function(h, nugget, range, sill, A) {
if(h > range) return nugget + (sill - nugget) / range;
return nugget + ((sill - nugget) / range) *
(1.5 * (h / range) - 0.5 * Math.pow(h / range, 3));
kriging.train = function(t, x, y, model, sigma2, alpha) {
var variogram = {
t: t,
x: x,
y: y,
nugget: 0.0,
range: 0.0,
sill: 0.0,
A: 1 / 3,
n: 0
switch(model) {
case "gaussian":
variogram.model = kriging_variogram_gaussian;
break;
case "exponential":
variogram.model = kriging_variogram_exponential;
break;
case "spherical":
variogram.model = kriging_variogram_spherical;
break;
var i, j, k, l, n = t.length;
var distance = Array((n * n - n) / 2);
for(i = 0, k = 0; i < n; i++)
for(j = 0; j < i; j++, k++) {
distance[k] = Array(2);
distance[k][0] = Math.pow(
Math.pow(x[i] - x[j], 2) +
Math.pow(y[i] - y[j], 2), 0.5);
distance[k][1] = Math.abs(t[i] - t[j]);
distance.sort(function(a, b) { return a[0] - b[0]; });
variogram.range = distance[(n * n - n) / 2 - 1][0];
var lags = ((n * n - n) / 2) > 30 ? 30 : (n * n - n) / 2;
var tolerance = variogram.range / lags;
var lag = [0].rep(lags);
var semi = [0].rep(lags);
if(lags < 30) {
for(l = 0; l < lags; l++) {
lag[l] = distance[l][0];
semi[l] = distance[l][1];
} else {
for(i = 0, j = 0, k = 0, l = 0; i < lags && j < ((n * n - n) / 2); i++, k = 0) {
while(distance[j][0] <= ((i + 1) * tolerance)) {
lag[l] += distance[j][0];
semi[l] += distance[j][1];
j++;
k++;
if(j >= ((n * n - n) / 2)) break;
if(k > 0) {
lag[l] /= k;
semi[l] /= k;
l++;
if(l < 2) return variogram;
n = l;
variogram.range = lag[n - 1] - lag[0];
var X = [1].rep(2 * n);
var Y = Array(n);
var A = variogram.A;
for(i = 0; i < n; i++) {
switch(model) {
case "gaussian":
X[i * 2 + 1] = 1.0 - Math.exp(-(1.0 / A) * Math.pow(lag[i] / variogram.range, 2));
break;
case "exponential":
X[i * 2 + 1] = 1.0 - Math.exp(-(1.0 / A) * lag[i] / variogram.range);
break;
case "spherical":
X[i * 2 + 1] = 1.5 * (lag[i] / variogram.range) -
0.5 * Math.pow(lag[i] / variogram.range, 3);
break;
Y[i] = semi[i];
var Xt = kriging_matrix_transpose(X, n, 2);
var Z = kriging_matrix_multiply(Xt, X, 2, n, 2);
Z = kriging_matrix_add(Z, kriging_matrix_diag(1 / alpha, 2), 2, 2);
var cloneZ = Z.slice(0);
if(kriging_matrix_chol(Z, 2))
kriging_matrix_chol2inv(Z, 2);
else {
kriging_matrix_solve(cloneZ, 2);
Z = cloneZ;
var W = kriging_matrix_multiply(kriging_matrix_multiply(Z, Xt, 2, 2, n), Y, 2, n, 1);
variogram.nugget = W[0];
variogram.sill = W[1] * variogram.range + variogram.nugget;
variogram.n = x.length;
n = x.length;
var K = Array(n * n);
for(i = 0; i < n; i++) {
for(j = 0; j < i; j++) {
K[i * n + j] = variogram.model(Math.pow(Math.pow(x[i] - x[j], 2) +
Math.pow(y[i] - y[j], 2), 0.5),
variogram.nugget,
variogram.range,
variogram.sill,
variogram.A);
K[j * n + i] = K[i * n + j];
K[i * n + i] = variogram.model(0, variogram.nugget,
variogram.range,
variogram.sill,
variogram.A);
var C = kriging_matrix_add(K, kriging_matrix_diag(sigma2, n), n, n);
var cloneC = C.slice(0);
if(kriging_matrix_chol(C, n))
kriging_matrix_chol2inv(C, n);
else {
kriging_matrix_solve(cloneC, n);
C = cloneC;
var K = C.slice(0);
var M = kriging_matrix_multiply(C, t, n, n, 1);
variogram.K = K;
variogram.M = M;
return variogram;
kriging.predict = function(x, y, variogram) {
var i, k = Array(variogram.n);
for(i = 0; i < variogram.n; i++)
k[i] = variogram.model(Math.pow(Math.pow(x - variogram.x[i], 2) +
Math.pow(y - variogram.y[i], 2), 0.5),
variogram.nugget, variogram.range,
variogram.sill, variogram.A);
return kriging_matrix_multiply(k, variogram.M, 1, variogram.n, 1)[0];
kriging.variance = function(x, y, variogram) {
var i, k = Array(variogram.n);
for(i = 0; i < variogram.n; i++)
k[i] = variogram.model(Math.pow(Math.pow(x - variogram.x[i], 2) +
Math.pow(y - variogram.y[i], 2), 0.5),
variogram.nugget, variogram.range,
variogram.sill, variogram.A);
return variogram.model(0, variogram.nugget, variogram.range,
variogram.sill, variogram.A) +
kriging_matrix_multiply(kriging_matrix_multiply(k, variogram.K,
1, variogram.n, variogram.n),
k, 1, variogram.n, 1)[0];
kriging.grid = function(polygons, variogram, width) {
var i, j, k, n = polygons.length;
if(n == 0) return;
var xlim = [polygons[0][0][0], polygons[0][0][0]];
var ylim = [polygons[0][0][1], polygons[0][0][1]];
for(i = 0; i < n; i++)
for(j = 0; j < polygons[i].length; j++) {
if(polygons[i][j][0] < xlim[0])
xlim[0] = polygons[i][j][0];
if(polygons[i][j][0] > xlim[1])
xlim[1] = polygons[i][j][0];
if(polygons[i][j][1] < ylim[0])
ylim[0] = polygons[i][j][1];
if(polygons[i][j][1] > ylim[1])
ylim[1] = polygons[i][j][1];
var xtarget, ytarget;
var a = Array(2),
b = Array(2);
var lxlim = Array(2);
var lylim = Array(2);
var x = Math.ceil((xlim[1] - xlim[0]) / width);
var y = Math.ceil((ylim[1] - ylim[0]) / width);
var A = Array(x + 1);
for(i = 0; i <= x; i++) A[i] = Array(y + 1);
for(i = 0; i < n; i++) {
lxlim[0] = polygons[i][0][0];
lxlim[1] = lxlim[0];
lylim[0] = polygons[i][0][1];
lylim[1] = lylim[0];
for(j = 1; j < polygons[i].length; j++) {
if(polygons[i][j][0] < lxlim[0])
lxlim[0] = polygons[i][j][0];
if(polygons[i][j][0] > lxlim[1])
lxlim[1] = polygons[i][j][0];
if(polygons[i][j][1] < lylim[0])
lylim[0] = polygons[i][j][1];
if(polygons[i][j][1] > lylim[1])
lylim[1] = polygons[i][j][1];
a[0] = Math.floor(((lxlim[0] - ((lxlim[0] - xlim[0]) % width)) - xlim[0]) / width);
a[1] = Math.ceil(((lxlim[1] - ((lxlim[1] - xlim[1]) % width)) - xlim[0]) / width);
b[0] = Math.floor(((lylim[0] - ((lylim[0] - ylim[0]) % width)) - ylim[0]) / width);
b[1] = Math.ceil(((lylim[1] - ((lylim[1] - ylim[1]) % width)) - ylim[0]) / width);
for(j = a[0]; j <= a[1]; j++)
for(k = b[0]; k <= b[1]; k++) {
xtarget = xlim[0] + j * width;
ytarget = ylim[0] + k * width;
if(polygons[i].pip(xtarget, ytarget))
A[j][k] = kriging.predict(xtarget,
ytarget,
variogram);
A.xlim = xlim;
A.ylim = ylim;
A.zlim = [variogram.t.min(), variogram.t.max()];
A.width = width;
return A;
kriging.contour = function(value, polygons, variogram) {
kriging.plot = function(canvas, grid, xlim, ylim, colors) {
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
var range = [xlim[1] - xlim[0], ylim[1] - ylim[0], grid.zlim[1] - grid.zlim[0]];
var i, j, x, y, z;
var n = grid.length;
var m = grid[0].length;
var wx = Math.ceil(grid.width * canvas.width / (xlim[1] - xlim[0]));
var wy = Math.ceil(grid.width * canvas.height / (ylim[1] - ylim[0]));
for(i = 0; i < n; i++)
for(j = 0; j < m; j++) {
if(grid[i][j] == undefined) continue;
x = canvas.width * (i * grid.width + grid.xlim[0] - xlim[0]) / range[0];
y = canvas.height * (1 - (j * grid.width + grid.ylim[0] - ylim[0]) / range[1]);
z = (grid[i][j] - grid.zlim[0]) / range[2];
if(z < 0.0) z = 0.0;
if(z > 1.0) z = 1.0;
ctx.fillStyle = colors[Math.floor((colors.length - 1) * z)];
ctx.fillRect(Math.round(x - wx / 2), Math.round(y - wy / 2), wx, wy);
return kriging;
}();
.html中的方法调用 //训练使用高斯过程与贝叶斯先验 let variogram=kriging.train(positions.map(pos=>pos[2]),positions.map(pos=>pos[0]),positions.map(pos=>pos[1]),params.krigingModel,params.krigingSigma2,params.krigingAlpha); //网格矩阵或轮廓路径 let grid=kriging.grid(po
1. Vue是会把所有的data上的对象数据会转化成响应式的,可以从Vue源码看出来,所以Cesium的Viewer对象千万不要写在data、state、computed里面。data里面初始化和ui相关的数据。
那如果不存data、state、compued里面,可以存在window的全局对象里面:
可以这样写:window.earth = Viewer
克里金插值法是一种空间插值算法,说到插值,顾名思义就是根据已知点求得未知点数值的一种方式;
专业点的解释:与IDW插值方法相似,均是对未知点的特定邻域范围的测量点或者特定数量的相邻测量点的数值进行加权相加,以求得未知点的数值,实现对未知点的预测。其中,周围测量点的权重根据半方差函数来确定。
1核心方法
kriging.train(t, x, y, model, sigma2, alpha):使用gaussian、exponential或spherical模型对数据集进行训练,返回一个variogra.
Cesium结合
kriging.
js制作降雨等值面前因实现效果图使用
克里金插值kriging.
js使用方法解析
因工作需要使用cesium制作降雨等值面,所以在参考众多博客后。终于是成功实现了降雨等值面。
参考博客:
https://blog.csdn.net/weixin_44265800/article/details/103106321
https://www.jianshu.com/p/c8473ac0b08a
https://zhuanlan.zhihu.com/p/73769138
克里金插值是一种地统计分析方法,可用于空间插值、趋势分析和地质预测等。在使用Python编写克里金插值代码之前,需要通过调用SciPy和Scikit-learn等Python库进行必要的预处理和运算。
先导入相应的库:
import numpy as np
from scipy.spatial.distance import cdist
from sklearn.metrics.pairwise import rbf_kernel
接着定义一个函数来计算克里金插值的权重系数:
def kriging_weights(X, y, model, delta):
pairwise_dist = cdist(X, X, 'euclidean')
cov_matrix = model(pairwise_dist)
reg_matrix = np.eye(X.shape[0]) * delta**2
weights = np.linalg.solve(cov_matrix + reg_matrix, y - y.mean())
return weights
其中,X为样本数据的空间坐标,y为对应的观测值,model为核函数,delta为正则化参数。
接下来编写主函数进行克里金插值:
def kriging_interpolate(x, X, y, model=rbf_kernel, delta=1e-5):
weights = kriging_weights(X, y, model, delta)
pairwise_dist = cdist(X, np.atleast_2d(x), 'euclidean')
y_pred = (weights * model(pairwise_dist).T).sum(axis=0) + y.mean()
return y_pred
其中,x为需要进行插值的空间坐标,X和y为样本数据和对应的观测值,model和delta的含义同上。最终返回插值结果y_pred。
需要注意的是,克里金插值中的核函数和正则化参数对插值结果有很大的影响,需要根据实际情况进行调整和选择。此外,也可以根据具体的需求进行改进,比如考虑半变异函数的选择和拟合等。