Geographic Interpolate in Python [closed]

﹥>﹥吖頭↗ 提交于 2021-02-05 06:59:05

问题


I have 500 points with longitude x, latitude y, altitude z, and the value at these points.

On the other hand, I have other 200 points than I would like to interpolate, where the latitude, longitude, and altitude are known.

I would like to interpolate considering the altitude of the points and geography between these points, my maps are Spain.

An example:

I have 2 points (x,y,z) and (x',y',z'). The real distance is black line, a polynomial interpolation is blue line (approx. distance), and euclidean distance between these 2 point is red line. I would like to obtain the blue or black line distance.

The following example which takes (x,y) as input would fit:

https://nbviewer.jupyter.org/github/cjohnson318/geostatsmodels/blob/master/notebooks/KrigingExample.ipynb

but I would like to also manage the altitude z as a input parameter.

Some libraries in Python? Some tutorial?


回答1:


I'll try to answer your question using OpenTURNS platform.

Let's consider that Spain is a square 1000 x 1000 km and that your 500 points are randomly distributed over the surface

import openturns as ot
import numpy as np

# initiate a sample of size 500 with 2 coordinates
inputdata = ot.Sample(500, 2)
# 1st column random between 0 and 1000
inputdata[:,0] = ot.Uniform(0,1000).getSample(500)
# 2nd column random between 0 and 1000  
inputdata[:,1] = ot.Uniform(0,1000).getSample(500)

Then let's assign a height for each of these points. OpenTURNS allows to define symbolic functions :

height = ot.SymbolicFunction(["x","y"], ["10 +10 * (x + y) / 1000 + 10 * ((x + y) / 1000) * sin( 3 * x * pi_ / 1000 )*cos(5 * y * pi_ / 1000)"])
outputdata = height(inputdata)

Now we would like to interpolate the data to estimate the height of any point on the map. The Kriging method allows to do so but you'd better know some information about your problem (general trend, correlation between the heights of 2 distant points).

# dimension of the input data
dimension = 2
basis = ot.ConstantBasisFactory(dimension).build()
covarianceModel = ot.SquaredExponential(dimension)

Then we just call the kriging algorithm to do the interpolation

algo = ot.KrigingAlgorithm(inputdata, outputdata, covarianceModel, basis)
algo.run()
result = algo.getResult()
metamodel = result.getMetaModel()

metamodel is exactly the function you want!

# gives the inferred height of the point (x = 123, y = 967)
metamodel([123, 967])
>>> [12.2225]

Should you like to draw the result, you can calculate the predicted values on a meshgrid of your square

gridx = np.arange(0.0,1001,10)
nx = len(gridx)
gridy = np.arange(0.0,1001,10)
ny = len(gridx)
X, Y = np.meshgrid(gridx, gridy)

predictions = np.array(metamodel([[xi,yi] for (xi, yi) in zip(X.ravel(),Y.ravel())])).reshape(nx,ny)

then you can use matplotlib to view the result:

import matplotlib.pylab as plt
plt.figure()
vmin = predictions.min()
vmax = predictions.max()
plt.pcolor(X, Y, predictions, cmap='viridis', vmin=vmin, vmax=vmax)
plt.scatter([d[0] for d in inputdata], [d[1] for d in inputdata],  c = [d for d in outputdata], s=2, edgecolor = "white", cmap='viridis', vmin=vmin, vmax=vmax)
plt.colorbar()
plt.show()

You can also view it in 3D :-)

from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
    
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(X, Y, predictions, cmap=cm.viridis,
                           linewidth=0, antialiased=False)
fig.colorbar(surf, shrink=0.5, aspect=5)
    
plt.show()



来源:https://stackoverflow.com/questions/60892146/geographic-interpolate-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!