private static int GetIDWNeighborsBrute(InterpolationPoint InCellPoint, ref List <InterpolationPoint> InPointCache, out List <InterpolationPoint> OutNeighbors, IDWNeighborhoodType NeighborhoodType, int NeighborhoodCount, double NeighborhoodDistance, string ProjUnits) { SortInterpolationPointsByDistanceBrute(InCellPoint, ref InPointCache, ProjUnits); OutNeighbors = new List <InterpolationPoint>(); int numPts = 0; if (NeighborhoodType == IDWNeighborhoodType.Variable) //Taking NeighborhoodCount number of nearest points { if (NeighborhoodDistance == -1) //Then take NeighborhoodCount number of nearest points { foreach (InterpolationPoint npoint in InPointCache) { OutNeighbors.Add(new InterpolationPoint(npoint.X, npoint.Y, npoint.Value, npoint.Distance)); numPts++; if (numPts >= NeighborhoodCount) { break; } } } else //Take NeighborhoodCount of nearest points that are a maximum of NeighborhoodDistance away { foreach (InterpolationPoint npoint in InPointCache) { if (npoint.Distance <= NeighborhoodDistance) { OutNeighbors.Add(new InterpolationPoint(npoint.X, npoint.Y, npoint.Value, npoint.Distance)); numPts++; if (numPts >= NeighborhoodCount) { break; } } } } } else if (NeighborhoodType == IDWNeighborhoodType.Fixed) //Taking all points in fixed distance { foreach (InterpolationPoint npoint in InPointCache) { if (npoint.Distance <= NeighborhoodDistance) { OutNeighbors.Add(new InterpolationPoint(npoint.X, npoint.Y, npoint.Value, npoint.Distance)); } } if (OutNeighbors.Count < NeighborhoodCount) //Test for minimum number of points found { return(-1); //Error } } else { return(-1); //Error } return(0); }
/// <summary> /// Inverse Distance Weighting Interpolation /// </summary> /// <param name="InPointsPath">Input point shapefile path to interpolate</param> /// <param name="InValueFieldIndex">Input field index where interpolation value is stored</param> /// <param name="OutGridPath">Output grid path where interpolation is stored</param> /// <param name="CellSize">Cell Size for output grid. Default lower of points extent height or width divided by 250</param> /// <param name="Power">Power variable for IDW algorithm. 0 lt p lt 1 will give sharp changes. >1 will give smoother. Default 2.</param> /// <param name="NeighborhoodType">Variable is a variable number of nearest points. Fixed is all points in a fixed distance</param> /// <param name="NeighborhoodCount">Variable Count is either number of nearest points to use. Fixed Count is minimum points needed to find valid interpolation</param> /// <param name="NeighborhoodDistance">Variable Distance is a maximum distance of nearest points. Fixed Distance is distance to use to select points</param> /// <param name="callback">A callback for progress information</param> public static void IDWBrute(string InPointsPath, int InValueFieldIndex, string OutGridPath, double CellSize, double Power, IDWNeighborhoodType NeighborhoodType, int NeighborhoodCount, double NeighborhoodDistance, MapWinGIS.ICallback callback) { int newperc = 0, oldperc = 0; List <InterpolationPoint> pointsCache; string proj, projUnits; MapWinGIS.Extents pointsExtents; CachePointsBrute(InPointsPath, InValueFieldIndex, out pointsCache, out proj, out projUnits, out pointsExtents, callback); MapWinGIS.Grid outGrid; DataManagement.DeleteGrid(ref OutGridPath); double NoDataValue = -32768; CreateGridFromExtents(pointsExtents, CellSize, proj, NoDataValue, OutGridPath, out outGrid); //Cycle grid and find interpolated value for each cell List <InterpolationPoint> neighbors; InterpolationPoint cellPoint; int nr = outGrid.Header.NumberRows; int nc = outGrid.Header.NumberCols; double sumWeight, sumWeightAndVal; newperc = 0; oldperc = 0; for (int row = 0; row < nr; row++) { newperc = Convert.ToInt32((Convert.ToDouble(row) / Convert.ToDouble(nr)) * 100); if (callback != null) { callback.Progress("Status", newperc, "IDW Row " + row); } newperc = 0; oldperc = 0; for (int col = 0; col < nc; col++) { newperc = Convert.ToInt32((Convert.ToDouble(col) / Convert.ToDouble(nc)) * 100); if ((newperc > oldperc)) { if (callback != null) { callback.Progress("Status", newperc, "IDW Row " + row.ToString() + " Col " + col.ToString()); } oldperc = newperc; } cellPoint = new InterpolationPoint(); outGrid.CellToProj(col, row, out cellPoint.X, out cellPoint.Y); GetIDWNeighborsBrute(cellPoint, ref pointsCache, out neighbors, NeighborhoodType, NeighborhoodCount, NeighborhoodDistance, projUnits); sumWeightAndVal = 0; sumWeight = 0; foreach (InterpolationPoint npoint in neighbors) { sumWeightAndVal += GetIDWeightBrute(cellPoint, npoint, projUnits, Power) * npoint.Value; sumWeight += GetIDWeightBrute(cellPoint, npoint, projUnits, Power); } outGrid.set_Value(col, row, (sumWeightAndVal / sumWeight)); } } outGrid.Save(OutGridPath, MapWinGIS.GridFileType.UseExtension, null); outGrid.Close(); }
private static int GetIDWNeighbors(double[] InCellPoint, ref KDTreeDLL.KDTree InPointsTree, ref double[][] InPoints, out int[] Neighbors, IDWNeighborhoodType NeighborhoodType, int NeighborhoodCount, double NeighborhoodDistance, string ProjUnits) { int tmpIdx; Neighbors = new int[1]; if (NeighborhoodType == IDWNeighborhoodType.Variable) //Taking NeighborhoodCount number of nearest points { if (NeighborhoodDistance == -1) //Then take NeighborhoodCount number of nearest points { Object[] ptIndexObjs = InPointsTree.nearest(InCellPoint, NeighborhoodCount); if (ptIndexObjs.Length == 0) { return(-1); } Neighbors = new int[ptIndexObjs.Length]; for (int i = 0; i < ptIndexObjs.Length; i++) { Neighbors[i] = (int)ptIndexObjs[i]; } } else //Take NeighborhoodCount of nearest points that are a maximum of NeighborhoodDistance away { Object[] ptIndexObjs = InPointsTree.nearest(InCellPoint, NeighborhoodCount); if (ptIndexObjs.Length == 0) { return(-1); } Neighbors = new int[ptIndexObjs.Length]; for (int i = 0; i < ptIndexObjs.Length; i++) { tmpIdx = (int)ptIndexObjs[i]; if (SpatialOperations.Distance(InCellPoint[0], InCellPoint[1], InPoints[tmpIdx][0], InPoints[tmpIdx][1], ProjUnits) <= NeighborhoodDistance) { Neighbors[i] = tmpIdx; } else { Neighbors[i] = -1; } } } } else if (NeighborhoodType == IDWNeighborhoodType.Fixed) //Taking all points in fixed distance { //Something //if (OutNeighbors.Count < NeighborhoodCount) //Test for minimum number of points found //{ // return -1; // //Error //} } else { return(-1); //Error } return(0); }
/// <summary> /// Inverse Distance Weighting Interpolation /// </summary> /// <param name="InPointsPath">Input point shapefile path to interpolate</param> /// <param name="InValueFieldIndex">Input field index where interpolation value is stored</param> /// <param name="OutGridPath">Output grid path where interpolation is stored</param> /// <param name="CellSize">Cell Size for output grid. Default lower of points extent height or width divided by 250</param> /// <param name="Power">Power variable for IDW algorithm. 0 lt p lt 1 will give sharp changes. >1 will give smoother. Default 2.</param> /// <param name="NeighborhoodType">Variable is a variable number of nearest points. Fixed is all points in a fixed distance</param> /// <param name="NeighborhoodCount">Variable Count is either number of nearest points to use. Fixed Count is minimum points needed to find valid interpolation</param> /// <param name="NeighborhoodDistance">Variable Distance is a maximum distance of nearest points. Fixed Distance is distance to use to select points</param> /// <param name="callback">A callback for progress information</param> public static void IDW(string InPointsPath, int InValueFieldIndex, string OutGridPath, double CellSize, double Power, IDWNeighborhoodType NeighborhoodType, int NeighborhoodCount, double NeighborhoodDistance, MapWinGIS.ICallback callback) { int newperc = 0, oldperc = 0; KDTreeDLL.KDTree pointsTree; double[][] Points; double[] PointVals; string proj, projUnits; MapWinGIS.Extents pointsExtents; CachePoints(InPointsPath, InValueFieldIndex, out pointsTree, out Points, out PointVals, out proj, out projUnits, out pointsExtents, callback); MapWinGIS.Grid outGrid; DataManagement.DeleteGrid(ref OutGridPath); double NoDataValue = -32768; CreateGridFromExtents(pointsExtents, CellSize, proj, NoDataValue, OutGridPath, out outGrid); //Cycle grid and find interpolated value for each cell int nr = outGrid.Header.NumberRows; int nc = outGrid.Header.NumberCols; double sumWeight, sumWeightAndVal, projX, projY; int[] neighbors; double[] CellPoint; newperc = 0; oldperc = 0; for (int row = 0; row < nr; row++) { newperc = Convert.ToInt32((Convert.ToDouble(row) / Convert.ToDouble(nr)) * 100); if (callback != null) { callback.Progress("Status", newperc, "IDW Row " + row.ToString() + "/" + nr.ToString()); } oldperc = newperc; newperc = 0; oldperc = 0; for (int col = 0; col < nc; col++) { outGrid.CellToProj(col, row, out projX, out projY); CellPoint = new double[2]; CellPoint[0] = projX; CellPoint[1] = projY; if (GetIDWNeighbors(CellPoint, ref pointsTree, ref Points, out neighbors, NeighborhoodType, NeighborhoodCount, NeighborhoodDistance, projUnits) == 0) { sumWeightAndVal = 0; sumWeight = 0; for (int i = 0; i < neighbors.Length; i++) { sumWeightAndVal += GetIDWeight(CellPoint, Points[neighbors[i]], projUnits, Power) * PointVals[neighbors[i]]; sumWeight += GetIDWeight(CellPoint, Points[neighbors[i]], projUnits, Power); } outGrid.set_Value(col, row, (sumWeightAndVal / sumWeight)); } } } outGrid.Save(OutGridPath, MapWinGIS.GridFileType.UseExtension, null); outGrid.Close(); if (callback != null) { callback.Progress("Status", 0, ""); } }
/// <summary> /// Inverse Distance Weighting Interpolation /// </summary> /// <param name="InPointsPath">Input point shapefile path to interpolate</param> /// <param name="InValueFieldIndex">Input field index where interpolation value is stored</param> /// <param name="OutGridPath">Output grid path where interpolation is stored</param> /// <param name="CellSize">Cell Size for output grid. Default lower of points extent height or width divided by 250</param> /// <param name="Power">Power variable for IDW algorithm. 0 lt p lt 1 will give sharp changes. >1 will give smoother. Default 2.</param> /// <param name="NeighborhoodType">Variable is a variable number of nearest points. Fixed is all points in a fixed distance</param> public static void IDW(string InPointsPath, int InValueFieldIndex, string OutGridPath, double CellSize, double Power, IDWNeighborhoodType NeighborhoodType) { if (NeighborhoodType == IDWNeighborhoodType.Variable) { IDW(InPointsPath, InValueFieldIndex, OutGridPath, CellSize, Power, NeighborhoodType, 12, -1, null); } else { IDW(InPointsPath, InValueFieldIndex, OutGridPath, CellSize, Power, NeighborhoodType, 0, 5 * CellSize, null); } }
/// <summary> /// Inverse Distance Weighting Interpolation /// </summary> /// <param name="InPointsPath">Input point shapefile path to interpolate</param> /// <param name="InValueFieldIndex">Input field index where interpolation value is stored</param> /// <param name="OutGridPath">Output grid path where interpolation is stored</param> /// <param name="CellSize">Cell Size for output grid. Default lower of points extent height or width divided by 250</param> /// <param name="NeighborhoodType">Variable is a variable number of nearest points. Fixed is all points in a fixed distance</param> public static void IDW(string InPointsPath, int InValueFieldIndex, string OutGridPath, double CellSize, IDWNeighborhoodType NeighborhoodType) { IDW(InPointsPath, InValueFieldIndex, OutGridPath, CellSize, 2.0, NeighborhoodType); }