public static void Create(List <ISqlGeometryAware> points, Func <ISqlGeometryAware, double> valueFunc, int width, int height, Color minColor, Color maxColor, Color midColor, double?maxDistance)
        {
            var boundingBox = SqlGeometryExtensions.GetBoundingBox(points.Select(p => p.TheSqlGeometry).ToList());

            //scale
            var scaleX = width / boundingBox.Width;
            var scaleY = height / boundingBox.Height;
            var scale  = Math.Min(scaleX, scaleY);

            width  = (int)(scale * boundingBox.Width);
            height = (int)(scale * boundingBox.Height);

            //create empty raster
            Bitmap result = new Bitmap(width, height);

            List <Point3D> pointSet = points.Select(p => new Point3D(p.TheSqlGeometry.STX.Value, p.TheSqlGeometry.STY.Value, valueFunc(p))).ToList();

            var maxValue   = pointSet.Max(p => p.Z);
            var minValue   = pointSet.Min(p => p.Z);
            var rangeValue = maxValue - minValue;
            var midValue   = rangeValue / 2.0 + minValue;
            //var minR = minColor.R;
            //var maxR = maxColor.R;
            //var rangeR = maxR - minR;

            //var minG = minColor.G;
            //var maxG = maxColor.G;
            //var rangeG = maxG - minG;

            //var minB = minColor.B;
            //var maxB = maxColor.B;
            //var rangeB = maxB - minB;
            ColorInterpolation step1 = new ColorInterpolation(minColor, midColor);

            ColorInterpolation step2 = new ColorInterpolation(midColor, maxColor);

            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    var x     = boundingBox.XMin + j / scale;
                    var y     = boundingBox.YMax - i / scale;
                    var value = IRI.Msh.Common.Analysis.Interpolation.Idw.Calculate(pointSet, new Msh.Common.Primitives.Point(x, y), maxDistance);

                    //map value to color
                    //var r = (int)(minR + rangeR / rangeValue * (value - minValue));
                    //var g = (int)(minG + rangeG / rangeValue * (value - minValue));
                    //var b = (int)(minB + rangeB / rangeValue * (value - minValue));

                    Color color;

                    if (value.HasValue)
                    {
                        if (value < midValue)
                        {
                            color = step1.Interpolate(value.Value, minValue, maxValue);
                        }
                        else
                        {
                            color = step2.Interpolate(value.Value, minValue, maxValue);
                        }

                        //var color = Color.FromArgb(r, g, b);

                        result.SetPixel(j, i + 0, color); //result.SetPixel(j + 1, i + 0, color);
                    }

                    //result.SetPixel(j, i + 1, color); result.SetPixel(j + 1, i + 1, color);
                    //result.SetPixel(j, i + 2, color); result.SetPixel(j + 1, i + 2, color);
                    //result.SetPixel(j, i + 3, color); result.SetPixel(j + 1, i + 3, color);
                    //result.SetPixel(j, i + 4, color); result.SetPixel(j + 1, i + 4, color);

                    //result.SetPixel(j + 2, i + 0, color); result.SetPixel(j + 3, i + 0, color);
                    //result.SetPixel(j + 2, i + 1, color); result.SetPixel(j + 3, i + 1, color);
                    //result.SetPixel(j + 2, i + 2, color); result.SetPixel(j + 3, i + 2, color);
                    //result.SetPixel(j + 2, i + 3, color); result.SetPixel(j + 3, i + 3, color);
                    //result.SetPixel(j + 2, i + 4, color); result.SetPixel(j + 3, i + 4, color);

                    //result.SetPixel(j + 4, i + 0, color);
                    //result.SetPixel(j + 4, i + 1, color);
                    //result.SetPixel(j + 4, i + 2, color);
                    //result.SetPixel(j + 4, i + 3, color);
                    //result.SetPixel(j + 4, i + 4, color);
                }
            }

            result.Save("result.bmp");

            //return result;
        }