2

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.

enter image description here

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?

Michael Baudin
  • 1,022
  • 10
  • 25
Francisco Gonzalez
  • 437
  • 1
  • 3
  • 15
  • What exactly is the difference between the "real" distance and the euclidian distance? Do you mean the "geodetic distance" i.e. the shortest path along the ellipsoid of the earth at sea level between one point and another? In this context, how may you take into account for the altitude in the distance equation? – Michael Baudin Oct 17 '20 at 20:16
  • @MichaelBaudin I try to explain better. I have 2 points in a valley (V form). One in a mountain (\) and other in front of this (/). The 2 points with the same altitude and the same y coordinate. And x distance is 100 p1= (100,50,800) p3= (0,50,800) distance = 100. I would like something more. Now I have a point p2 (in the middle). The altitude of this is 0 p2= (50,50,0). Then I went the distance p1 to p3 but considering intermediate points every 1 km (for example). Because considering p2 the distance between p1 and p3 is distance = sqrt((100-50)²+800²) + sqrt((50-0)²+(0-800)²) – Francisco Gonzalez Oct 18 '20 at 08:51

1 Answers1

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()

Kriging result over 500 points

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()

3D visualisation of the altitude

josephmure
  • 208
  • 1
  • 9
Jean A.
  • 291
  • 1
  • 17
  • It is amazing, but I try to find something more. Add details in the question. Thx!!! – Francisco Gonzalez Oct 17 '20 at 15:59
  • Once you have the metamodel (i.e. (x, y, z = f(x, y)) all over the map), it becomes easy to calculate the distance when you go from (x0, y0, z0) to (x1, y1, z1) by summing the distances between (x, y, z) and (x + dx, y+dy, z+dz) – Jean A. Oct 19 '20 at 09:07