There’s nothing to be afraid of with IDW math. Remember that the search distance or the number of closest points determines how many points will be used.
We use the 3 closest points in this example:
Here’s what the table looks like for these 3 distances and values:
| Distance | Value |
| 350m | 12 |
| 750m | 10 |
| 850m | 10 |
For a power of 1, that cell value is equal to:
((12/350) + (10/750) + (10/850)) / ((1/350) + (1/750) + (1/850)) = 11.1
For a power of 2, that cell value is equal to:
= ((12/3502) + (10/7502) + (10/8502)) / ((1/3502) + (1/7502) + (1/8502)) = 11.4
…And here’s the formula:
The sigma notation simply means that you are adding whatever number of points that will be interpolated. Here we are simply summing the elevation values at each point for distance.
A smaller number in the denominator (more distance) has less effect on the interpolated (xp) value. You’re also never going to have values above or below your maximum and minimum known values… So you better hope you have your highest or lowest points in your sample points!
Try plugging in different values. The math really isn’t so bad!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
public class PointXYZ
{
public double X;
public double Y;
public double Z;
public double d;
}
public class Interpolation
{
/// <summary>
/// 插值算法 反距离加权法IDW
/// </summary>
/// <param name="input">离散点的XYZ</param>
/// <param name="outpoint">插入点的XY</param>
/// <returns></returns>
public bool InverseDistanceWeighted(List<PointXYZ> input, PointXYZ outpoint)
{
try
{
double r = 0.0; //距离的倒数和
double ri = 0.0; //i点的权重
foreach (PointXYZ inputpoint in input)
{
inputpoint.d = Math.Sqrt(Math.Pow(inputpoint.X - outpoint.X, 2) + Math.Pow(inputpoint.Y - outpoint.Y, 2));
inputpoint.d = Math.Pow(inputpoint.d, 2);
r += 1.0 / inputpoint.d;
//ipqchase 这里可以加条件过滤一部分,0.0001,生成集合下步使用
}
//= ((12/3502) + (10/7502) + (10/8502)) / ((1/3502) + (1/7502) + (1/8502)) = 11.4
outpoint.Z = 0.0;
foreach (PointXYZ inputpoint in input)
{
ri = 1.0 / inputpoint.d / r;
outpoint.Z += ri * inputpoint.Z;//所有离散点的权重*高程 和,就是该点的idw插值高程
}
return true;
}
catch
{
return true;
}
}
}
}
// See https://aka.ms/new-console-template for more information
using ConsoleApp2;
Console.WriteLine("Hello, World!");
Interpolation p = new Interpolation();
var pt2 = new PointXYZ() { X = 110.0, Y = 150, Z = 0 };
var pt3 = new PointXYZ() { X = 70, Y = 140, Z = 115.4 };
var pt4 = new PointXYZ() { X = 115, Y = 115, Z = 123.1 };
var pt5 = new PointXYZ() { X = 150, Y = 150, Z = 113.8 };
var pt6 = new PointXYZ() { X = 110, Y = 170, Z = 110.5 };
var pt7 = new PointXYZ() { X = 90, Y = 190, Z = 107.2 };
var pt8 = new PointXYZ() { X = 180, Y = 210, Z = 131.78 };
var lst=new List<PointXYZ>();
lst.Add(pt3);
lst.Add(pt4);
lst.Add(pt5);
lst.Add(pt6);
lst.Add(pt7);
lst.Add(pt8);
p.InverseDistanceWeighted(lst, pt2);
Console.WriteLine(pt2.Z);
Console.ReadKey();
x y z
110 150 0
70 140 115.4
115 115 123.1
150 150 113.8
110 170 110.5
90 190 107.2
180 210 131.78