/* TODO delete private static List<GridPolygon> getSourcePoligon(GridInfo gridInfo) { var width = gridInfo.Width; var height = gridInfo.Height; var poligon = new GridPolygon(); var points = new List<GridPoint>(); for (double i = gridInfo.MinY; i < gridInfo.MaxY; i += gridInfo.Step) { points.Add(new GridPoint(gridInfo.MinX, i)); } for (double i = gridInfo.MinX; i < gridInfo.MaxX; i += gridInfo.Step) { points.Add(new GridPoint(i, gridInfo.MaxY)); } for (double i = gridInfo.MaxY; i > gridInfo.MinY; i -= gridInfo.Step) { points.Add(new GridPoint(gridInfo.MaxX, i)); } for (double i = gridInfo.MaxX; i > gridInfo.MinX; i -= gridInfo.Step) { points.Add(new GridPoint(i, gridInfo.MinY)); } poligon.Points = points.ToArray(); return new List<GridPolygon> { poligon }; } */ /// <summary> /// Восстановление значений в ячейках грида с помощью бикубической интерполяции, вызывается в параллельных потоках /// </summary> /// <param name="grid">Грид</param> /// <param name="interpolant">Функция для восстановления значений</param> /// <param name="workerId">идентификатор рабочего процесса</param> private static void restoreGridCells(GridField grid, alglib.spline2dinterpolant interpolant, int workerId) { int procCount = Environment.ProcessorCount; int countX = grid.GridInfo.NumberColumns; int countY = grid.GridInfo.NumberRows; var max = countX * (workerId + 1) / procCount; for (var column = countX * workerId / procCount; column < max; ++column) { for (var row = 0; row < countY; ++row) { double? v = grid.GridData[column, row]; if (v == null || !double.IsNegativeInfinity(v.Value)) { var point = grid.createPoint(column, row); grid.GridData[column, row] = alglib.spline2dcalc(interpolant, point.X, point.Y); } } } }
/// <summary> /// Расчет ячеек грида кригингом, вызывается в параллельных потоках /// </summary> /// <param name="config">Настройки для расчёта</param> /// <param name="grid">Рассчитываемый грид</param> /// <param name="semivarianseDelegate">Вариограмма</param> /// <param name="workerId">идентификатор рабочего процесса</param> /// <param name="points">точки из которых набираем значения для расчёта</param> /// <param name="xvals"> /// Хранилище куда складываем насчитанные значения по X<br/> /// В дальнейшем используется для кубического сплайна /// </param> /// <param name="yvals"> /// Хранилище куда складываем насчитанные значения по Y<br/> /// В дальнейшем используется для кубического сплайна /// </param> /// <param name="step"> /// Шаг по которому будем вычислять в каких ячейках насчитать значения<br/> /// Если передано значение <= 0, тогда возьмем 5 /// </param> private static void calculate(KrigingConfig config, GridField grid, Func<double, double> semivarianseDelegate, int workerId, GridPoint[] points, ConcurrentBag<KeyValuePair<double, int>> xvals, ConcurrentBag<KeyValuePair<double, int>> yvals, int step) { if (grid == null || grid.GridData == null) { return; } if (step <= 0) { step = 10; } int countX = grid.GridInfo.NumberColumns; int countY = grid.GridInfo.NumberRows; var degreeOfParallelism = Environment.ProcessorCount; var max = countX * (workerId + 1) / degreeOfParallelism; //нужно ли заполнять множество Y значениями bool needFillYValues = workerId == 0; for (int column = countX * workerId / degreeOfParallelism; column < max; column += step) { for (var row = 0; row < countY; row += step) { var point = grid.createPoint(column, row); double? v = grid.GridData[column, row]; if (v == null || !double.IsNegativeInfinity(v.Value)) { var nearestPoints = getNearestPoints(point, points, config.SearchRadius, config.SectorsCount, config.MaxPointsInSector); grid.GridData[column, row] = (nearestPoints.Length != 0) ? interpolatePoint(point, nearestPoints, semivarianseDelegate) : config.NotDefinedValue; } if (needFillYValues) { yvals.Add(new KeyValuePair<double, int>(point.Y, row)); } } needFillYValues = false; xvals.Add(new KeyValuePair<double, int>(grid.getXCoord(column), column)); } }