Ejemplo n.º 1
0
        /* 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);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Выполнить интерполяцию Кригинга
        /// </summary>
        /// <param name="gridInfo">Информация о регулярной сетке</param>
        /// <param name="config">Конфигурация интерполятора</param>
        /// <param name="semivarianseDelegate">Вариограмма</param>
        /// <param name="irregularPoints">Массив исходных точек для интерполяции</param>
        /// <param name="sourcePolygons">Дополнительные массивы точек для интерполяции, взятые с контуров</param>
        /// <param name="blankPolygons">Контуры бланкования, в которых интерполяция не производится</param>
        /// <returns>Регулярную сетку значений</returns>
        public static GridField doInterpolate(GridInfo gridInfo, KrigingConfig config, Func<double, double> semivarianseDelegate,
            GridPoint[] irregularPoints, List<GridPolygon> sourcePolygons = null, List<GridPolygonArea> blankPolygons = null)
        {

            if (irregularPoints == null || irregularPoints.Length == 0 || config == null)
            {
                return null;
            }
            if (gridInfo == null || gridInfo.Extent.Width < gridInfo.Step || gridInfo.Extent.Height < gridInfo.Step)
            {
                return null;
            }

            /*if (sourcePolygons == null || sourcePolygons.Count == 0) {
                sourcePolygons = getSourcePoligon(gridInfo);
            }*/

            //            if (blankPolygons == null || blankPolygons.Count == 0) {
            //                blankPolygons = getBlankPoligon(gridInfo);
            //            }

            var allPoints = irregularPoints;
            if (sourcePolygons != null && sourcePolygons.Any())
            {
                var allPointsList = irregularPoints.ToList();
                foreach (var gridPolygon in sourcePolygons)
                {
                    if (gridPolygon.Line.Points != null && gridPolygon.Line.Points.Any())
                    {
                        allPointsList.AddRange(gridPolygon.Line.Points);
                    }
                }
                allPoints = allPointsList.ToArray();
            }

            var grid = new GridField(gridInfo);

            //хранилище для значений X на основании которых будем затем восстанавливать сигнал бикубическим сплайном
            var xBag = new ConcurrentBag<KeyValuePair<double, int>>();
            //хранилище для значений Y на основании которых будем затем восстанавливать сигнал бикубическим сплайном
            var yBag = new ConcurrentBag<KeyValuePair<double, int>>();


            Parallel.For(0, Environment.ProcessorCount,
                workerId => calculate(config, grid, semivarianseDelegate, workerId, allPoints, xBag, yBag, 0));


            try
            {
                alglib.spline2dinterpolant interpolant = getInterpolant(grid, xBag, yBag);
                if (blankPolygons != null && blankPolygons.Any())
                {
                    grid.fillNotCalculatedCell(blankPolygons, MASK_CELL_VALUE);
                }

                Parallel.For(0, Environment.ProcessorCount,
                    workerId => restoreGridCells(grid, interpolant, workerId));

            }
            catch (Exception e)
            {

                var t = e;
            }






            grid.fillDataNotNullable(config.NotDefinedValue);

            return grid;
        }