protected override PrimitiveSpatialResult QueryPrimitivesInternal(PrimitiveSpatialQuery specification, bool uniqueEntities, DataSource.QueryProgress progress)
        {
            GeometryQueryRegion region = specification.SpatialFilter.Region as GeometryQueryRegion;

            TileLevelOfDetail tileLevel = (TileLevelOfDetail)host.WorldEngine.ScaleRanges.ScaleToTileLevelOfDetailValue(specification.SpatialFilter.GeometryOptions.Scale);


            if (region != null)
            {
                Box2 regionBox = region.Geometry as Box2;
                if (regionBox != null)
                {
                    int    levelValue = (int)tileLevel.Value > 5 ? (int)tileLevel.Value : 5;
                    double iconSize   = 64.0 / Math.Pow(2, levelValue);
                    this.step = iconSize / 2.0;

                    RasterPatch2 rasterPatch = probesHelper.GetTilePatch(pointSet, regionBox, iconSize);

                    if (rasterPatch != null)
                    {
                        PrimitiveSpecification spec = new PrimitiveSpecification(entity,
                                                                                 this.Ontology.PrimitiveTypes["RasterPatch"], rasterPatch);
                        SimplePrimitive primitive = new SimplePrimitive(this, spec);
                        return(new SingleImageResult(primitive));
                    }
                }
            }

            return(new SingleImageResult(null));
        }
Exemplo n.º 2
0
        protected override PrimitiveSpatialResult QueryPrimitivesInternal(PrimitiveSpatialQuery specification, bool uniqueEntities, DataSource.QueryProgress progress)
        {
            GeometryQueryRegion region = specification.SpatialFilter.Region as GeometryQueryRegion;

            if (region != null)
            {
                Box2 regionBox = region.Geometry as Box2;
                if (regionBox != null)
                {
                    RasterPatch2 rasterPatch = null;
                    if (isWarped)
                    {
                        colorMapHelper = new ColorMapHelper(wfield, regionBox, minT, maxT);
                        rasterPatch    = colorMapHelper.GetWarpedTilePatch();

                        minT = colorMapHelper.MinT;
                        maxT = colorMapHelper.MaxT;
                    }
                    else
                    {
                        colorMapHelper = new ColorMapHelper(field, regionBox, minT, maxT);
                        rasterPatch    = colorMapHelper.GetTilePatch();

                        minT = colorMapHelper.MinT;
                        maxT = colorMapHelper.MaxT;
                    }
                    if (rasterPatch != null)
                    {
                        PrimitiveSpecification spec = new PrimitiveSpecification(entity,
                                                                                 this.Ontology.PrimitiveTypes["RasterPatch"], rasterPatch);
                        SimplePrimitive primitive = new SimplePrimitive(this, spec);
                        return(new SingleImageResult(primitive));
                    }
                }
            }
            else
            {
            }

            return(new SingleImageResult(null));
        }
Exemplo n.º 3
0
        public RasterPatch2 GetTilePatch()
        {
            int width  = 256;
            int height = 256;

            GeoRect intersectionRect = GeoRect.Intersect(gridBox, tileBox);

            if (intersectionRect != null)
            {
                int startPointX = (int)(width * (intersectionRect.Left - tileBox.Left) / tileBox.Width);
                int startPointY = (int)(height * (tileBox.Top - intersectionRect.Top) / tileBox.Height);

                int endPointX = (int)(width * (intersectionRect.Right - tileBox.Left) / tileBox.Width);
                int endPointY = (int)(height * (tileBox.Top - intersectionRect.Bottom) / tileBox.Height);

                const int bitsPerPixel = 32;
                int       stride       = (endPointX - startPointX) * ((bitsPerPixel + 7) / 8);
                int       arraySize    = stride * (endPointY - startPointY);
                byte[]    pixels       = new byte[arraySize];
                int       index        = 0;


                // Get data and min/max.
                double[,] data = field.Data;
                double minT, maxT;

                MathHelper.GetMaxMin(field.Data, out maxT, out minT);

                this.minT = minT;
                this.maxT = maxT;


                double k = 1.0 / (maxT - minT);

                GeoToBitmap[] latToBitmap = new GeoToBitmap[endPointY - startPointY];
                for (int i = 0; i < endPointY - startPointY; i++)
                {
                    double y = intersectionRect.Top - (i + 0.5) * intersectionRect.Height / (endPointY - startPointY);
                    for (int j = 1; j < field.Height; j++)
                    {
                        if (y < field.Y[j])
                        {
                            latToBitmap[i] = new GeoToBitmap {
                                Knot = j, Proportion = ((y - field.Y[j - 1]) / (field.Y[j] - field.Y[j - 1]))
                            };
                            break;
                        }
                    }
                }

                GeoToBitmap[] lonToBitmap = new GeoToBitmap[endPointX - startPointX];
                for (int i = 0; i < endPointX - startPointX; i++)
                {
                    double x = ((i + 0.5) * intersectionRect.Width / (endPointX - startPointX)) + intersectionRect.Left;
                    for (int j = 1; j < field.Width; j++)
                    {
                        if (x < field.X[j])
                        {
                            lonToBitmap[i] = new GeoToBitmap {
                                Knot = j, Proportion = ((x - field.X[j - 1]) / (field.X[j] - field.X[j - 1]))
                            };
                            break;
                        }
                    }
                }

                for (int j = 0; j < endPointY - startPointY; j++)
                {
                    for (int i = 0; i < endPointX - startPointX; i++)
                    {
                        int knotY = latToBitmap[j].Knot;
                        int knotX = lonToBitmap[i].Knot;

                        double proportionY = latToBitmap[j].Proportion;
                        double proportionX = lonToBitmap[i].Proportion;

                        double colorValue = Interpolate(
                            data[knotX - 1, knotY - 1],
                            data[knotX - 1, knotY],
                            data[knotX, knotY - 1],
                            data[knotX, knotY],
                            proportionX,
                            proportionY);

                        System.Windows.Media.Color color = palette.GetColor((colorValue - minT) * k);

                        //byte b1, b2;
                        //ConvertColor(color,out b1,out b2);
                        //pixels[index++] = b2;
                        //pixels[index++] = b1;

                        pixels[index++] = color.B;
                        pixels[index++] = color.G;
                        pixels[index++] = color.R;
                        pixels[index++] = (byte)255;
                    }
                }

                index = 0;
                bool need = true;
                for (int j = 0; j < endPointY - startPointY; j++)
                {
                    for (int i = 0; i < endPointX - startPointX; i++)
                    {
                        int currentIndex = index;

                        System.Windows.Media.Color oldColor = new System.Windows.Media.Color()
                        {
                            A = pixels[currentIndex + 3],
                            R = pixels[currentIndex + 2],
                            G = pixels[currentIndex + 1],
                            B = pixels[currentIndex]
                        };
                        System.Windows.Media.Color newColor = FindClosestColor(oldColor);
                        QuantError quant_error = new QuantError
                        {
                            A = oldColor.A,
                            B = (int)oldColor.B - (int)newColor.B,
                            G = (int)oldColor.G - (int)newColor.G,
                            R = (int)oldColor.R - (int)newColor.R
                        };

                        //pixels[i,j]
                        pixels[currentIndex]     = newColor.B;
                        pixels[currentIndex + 1] = newColor.G;
                        pixels[currentIndex + 2] = newColor.R;
                        pixels[currentIndex + 3] = newColor.A;

                        if (need)
                        {
                            int newValue   = 0;
                            int maxValueRB = 255;

                            if (i < endPointX - startPointX - 1)
                            {
                                //pixels[i+1,j]
                                newValue = (int)pixels[currentIndex + 4] + ((quant_error.B * 7) >> 4);
                                pixels[currentIndex + 4] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));


                                newValue = (int)pixels[currentIndex + 4 + 1] + ((quant_error.G * 7) >> 4);
                                pixels[currentIndex + 4 + 1] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));


                                newValue = (int)pixels[currentIndex + 4 + 2] + ((quant_error.R * 7) >> 4);
                                pixels[currentIndex + 4 + 2] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));
                            }

                            if (j < endPointY - startPointY - 1)
                            {
                                //pixels[i,j+1]
                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX)] + ((quant_error.B * 5) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX)] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));

                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) + 1] + ((quant_error.G * 5) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) + 1] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));

                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) + 2] + ((quant_error.R * 5) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) + 2] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));
                            }

                            if (i > 0 && j < (endPointY - startPointY - 1))
                            {
                                //pixels[i-1,j+1]
                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) - 4] + ((quant_error.B * 3) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) - 4] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));

                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) - 4 + 1] + ((quant_error.G * 3) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) - 4 + 1] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));

                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) - 4 + 2] + ((quant_error.R * 3) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) - 4 + 2] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));
                            }

                            if (i < (endPointX - startPointX - 1) && j < (endPointY - startPointY - 1))
                            {
                                //pixels[i+1, j+1]
                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) + 4] + ((quant_error.B * 1) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) + 4] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));

                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) + 4 + 1] + ((quant_error.G * 1) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) + 4 + 1] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));

                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) + 4 + 2] + ((quant_error.R * 1) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) + 4 + 2] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));
                            }
                        }

                        index += 4;
                    }
                }

                index = 0;
                for (int j = 0; j < endPointY - startPointY; j++)
                {
                    for (int i = 0; i < endPointX - startPointX; i++)
                    {
                        System.Windows.Media.Color color = new System.Windows.Media.Color()
                        {
                            B = pixels[index],
                            G = pixels[index + 1],
                            R = pixels[index + 2]
                        };
                        color             = FindClosestColor(color);
                        pixels[index]     = color.B;
                        pixels[index + 1] = color.G;
                        pixels[index + 2] = color.R;
                        index            += 4;
                    }
                }

                RasterPatch2 patch = new RasterPatch2(
                    new Box2(Wgs84CoordinateReferenceSystem.Instance, new Coordinate2D(intersectionRect.X, intersectionRect.Y), new Coordinate2D(intersectionRect.Right, intersectionRect.Top)),
                    pixels,
                    PatchPixelFormat.Format32bppArgb,
                    endPointX - startPointX,
                    endPointY - startPointY,
                    stride,
                    Wgs84CoordinateReferenceSystem.Instance);

                return(patch);
            }
            else
            {
                return(null);
            }
        }
Exemplo n.º 4
0
        public RasterPatch2 GetWarpedTilePatch()
        {
            int width  = 256;
            int height = 256;

            GeoRect intersectionRect = GeoRect.Intersect(gridBox, tileBox);

            if (intersectionRect != null)
            {
                PixelArray plane = new PixelArray(width, height);
                GeoRect    workingRect;

                // Get data and min/max.
                double[,] data = warpedField.Data;
                double minT, maxT;


                MathHelper.GetMaxMin(data, out maxT, out minT);

                this.minT = minT;
                this.maxT = maxT;

                double k = 1.0 / (maxT - minT);

                System.Windows.Point[,] grid = warpedField.Grid;
                for (int i = 0; i < warpedField.Width - 1; i++)
                {
                    for (int j = 0; j < warpedField.Height - 1; j++)
                    {
                        workingRect = new GeoRect(
                            new System.Windows.Point(grid[i, j].X, grid[i, j].Y),
                            new System.Windows.Point(grid[i + 1, j].X, grid[i + 1, j].Y),
                            new System.Windows.Point(grid[i, j + 1].X, grid[i, j + 1].Y));

                        if (GeoRect.IntersectionExist(workingRect, intersectionRect))
                        {
                            System.Windows.Media.Color color = palette.GetColor((data[i, j] - minT) * k);
                            workingTriangle.Point1 = new VertexPositionColor2D(
                                new System.Drawing.Point(
                                    (int)((grid[i, j].X - tileBox.Left) * width / tileBox.Width),
                                    (int)(height - (grid[i, j].Y - tileBox.Bottom) * height / tileBox.Height)),
                                color);

                            color = palette.GetColor((data[i + 1, j] - minT) * k);
                            workingTriangle.Point2 = new VertexPositionColor2D(
                                new System.Drawing.Point(
                                    (int)((grid[i + 1, j].X - tileBox.Left) * width / tileBox.Width),
                                    (int)(height - (grid[i + 1, j].Y - tileBox.Bottom) * height / tileBox.Height)),
                                color);

                            color = palette.GetColor((data[i, j + 1] - minT) * k);
                            workingTriangle.Point3 = new VertexPositionColor2D(
                                new System.Drawing.Point(
                                    (int)((grid[i, j + 1].X - tileBox.Left) * width / tileBox.Width),
                                    (int)(height - (grid[i, j + 1].Y - tileBox.Bottom) * height / tileBox.Height)),
                                color);

                            workingTriangle.FillGouraud(plane);
                        }

                        workingRect = new GeoRect(
                            new System.Windows.Point(grid[i + 1, j].X, grid[i + 1, j].Y),
                            new System.Windows.Point(grid[i, j + 1].X, grid[i, j + 1].Y),
                            new System.Windows.Point(grid[i + 1, j + 1].X, grid[i + 1, j + 1].Y));

                        if (GeoRect.IntersectionExist(workingRect, intersectionRect))
                        {
                            System.Windows.Media.Color color = palette.GetColor((data[i + 1, j] - minT) * k);
                            workingTriangle.Point1 = new VertexPositionColor2D(
                                new System.Drawing.Point(
                                    (int)((grid[i + 1, j].X - tileBox.Left) * width / tileBox.Width),
                                    (int)(height - (grid[i + 1, j].Y - tileBox.Bottom) * height / tileBox.Height)),
                                color);

                            color = palette.GetColor((data[i, j + 1] - minT) * k);
                            workingTriangle.Point2 = new VertexPositionColor2D(
                                new System.Drawing.Point(
                                    (int)((grid[i, j + 1].X - tileBox.Left) * width / tileBox.Width),
                                    (int)(height - (grid[i, j + 1].Y - tileBox.Bottom) * height / tileBox.Height)),
                                color);

                            color = palette.GetColor((data[i + 1, j + 1] - minT) * k);
                            workingTriangle.Point3 = new VertexPositionColor2D(
                                new System.Drawing.Point(
                                    (int)((grid[i + 1, j + 1].X - tileBox.Left) * width / tileBox.Width),
                                    (int)(height - (grid[i + 1, j + 1].Y - tileBox.Bottom) * height / tileBox.Height)),
                                color);

                            workingTriangle.FillGouraud(plane);
                        }
                    }
                }

                const int bitsPerPixel = 32;
                int       stride       = width * ((bitsPerPixel + 7) / 8);
                int       arraySize    = stride * height;
                byte[]    pixels       = new byte[arraySize];
                int       index        = 0;

                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        pixels[index++] = plane.Pixels[j, i].B;
                        pixels[index++] = plane.Pixels[j, i].G;
                        pixels[index++] = plane.Pixels[j, i].R;
                        pixels[index++] = plane.Pixels[j, i].A;
                    }
                }

                RasterPatch2 patch = new RasterPatch2(
                    regionBox,
                    pixels,
                    PatchPixelFormat.Format32bppArgb,
                    width,
                    height,
                    stride,
                    Wgs84CoordinateReferenceSystem.Instance);

                return(patch);
            }
            else
            {
                return(null);
            }
        }
        public RasterPatch2 GetWarpedTilePatch()
        {
            int width = 256;
            int height = 256;

            GeoRect intersectionRect = GeoRect.Intersect(gridBox, tileBox);

            if (intersectionRect != null)
            {
                PixelArray plane = new PixelArray(width, height);
                GeoRect workingRect;

                // Get data and min/max.
                double[,] data = warpedField.Data;
                double minT, maxT;


                MathHelper.GetMaxMin(data, out maxT, out minT);

                this.minT = minT;
                this.maxT = maxT;
                
                double k = 1.0 / (maxT - minT);

                System.Windows.Point[,] grid = warpedField.Grid;
                for (int i = 0; i < warpedField.Width - 1; i++)
                {
                    for (int j = 0; j < warpedField.Height - 1; j++)
                    {
                        workingRect = new GeoRect(
                            new System.Windows.Point(grid[i, j].X, grid[i, j].Y),
                            new System.Windows.Point(grid[i + 1, j].X, grid[i + 1, j].Y),
                            new System.Windows.Point(grid[i, j + 1].X, grid[i, j + 1].Y));

                        if (GeoRect.IntersectionExist(workingRect, intersectionRect))
                        {
                            System.Windows.Media.Color color = palette.GetColor((data[i, j] - minT) * k);
                            workingTriangle.Point1 = new VertexPositionColor2D(
                                new System.Drawing.Point(
                                    (int)((grid[i, j].X - tileBox.Left) * width / tileBox.Width),
                                    (int)(height - (grid[i, j].Y - tileBox.Bottom) * height / tileBox.Height)),
                                    color);
                            
                            color = palette.GetColor((data[i + 1, j] - minT) * k);
                            workingTriangle.Point2 = new VertexPositionColor2D(
                                new System.Drawing.Point(
                                    (int)((grid[i + 1, j].X - tileBox.Left) * width / tileBox.Width),
                                    (int)(height - (grid[i + 1, j].Y - tileBox.Bottom) * height / tileBox.Height)),
                                    color);
                            
                            color = palette.GetColor((data[i, j + 1] - minT) * k);
                            workingTriangle.Point3 = new VertexPositionColor2D(
                                new System.Drawing.Point(
                                    (int)((grid[i, j + 1].X - tileBox.Left) * width / tileBox.Width),
                                    (int)(height - (grid[i, j + 1].Y - tileBox.Bottom) * height / tileBox.Height)),
                                    color);
                            
                            workingTriangle.FillGouraud(plane);

                        }

                        workingRect = new GeoRect(
                            new System.Windows.Point(grid[i + 1, j].X, grid[i + 1, j].Y),
                            new System.Windows.Point(grid[i, j + 1].X, grid[i, j + 1].Y),
                            new System.Windows.Point(grid[i + 1, j + 1].X, grid[i + 1, j + 1].Y));

                        if (GeoRect.IntersectionExist(workingRect, intersectionRect))
                        {
                            System.Windows.Media.Color color = palette.GetColor((data[i + 1, j] - minT) * k);
                            workingTriangle.Point1 = new VertexPositionColor2D(
                                new System.Drawing.Point(
                                    (int)((grid[i + 1, j].X - tileBox.Left) * width / tileBox.Width),
                                    (int)(height - (grid[i + 1, j].Y - tileBox.Bottom) * height / tileBox.Height)),
                                    color);
                            
                            color = palette.GetColor((data[i, j + 1] - minT) * k);
                            workingTriangle.Point2 = new VertexPositionColor2D(
                                new System.Drawing.Point(
                                    (int)((grid[i, j + 1].X - tileBox.Left) * width / tileBox.Width),
                                    (int)(height - (grid[i, j + 1].Y - tileBox.Bottom) * height / tileBox.Height)),
                                    color);
                            
                            color = palette.GetColor((data[i + 1, j + 1] - minT) * k);
                            workingTriangle.Point3 = new VertexPositionColor2D(
                                new System.Drawing.Point(
                                    (int)((grid[i + 1, j + 1].X - tileBox.Left) * width / tileBox.Width),
                                    (int)(height - (grid[i + 1, j + 1].Y - tileBox.Bottom) * height / tileBox.Height)),
                                    color);
                            
                            workingTriangle.FillGouraud(plane);

                        }

                    }
                }

                const int bitsPerPixel = 32;
                int stride = width * ((bitsPerPixel + 7) / 8);
                int arraySize = stride * height;
                byte[] pixels = new byte[arraySize];
                int index = 0;

                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        pixels[index++] = plane.Pixels[j, i].B;
                        pixels[index++] = plane.Pixels[j, i].G;
                        pixels[index++] = plane.Pixels[j, i].R;
                        pixels[index++] = plane.Pixels[j, i].A;

                    }
                }

                RasterPatch2 patch = new RasterPatch2(
                    regionBox,
                    pixels,
                    PatchPixelFormat.Format32bppArgb,
                    width,
                    height,
                    stride,
                    Wgs84CoordinateReferenceSystem.Instance);

                return patch;
            }
            else
            {
                return null;
            }
        }
        public RasterPatch2 GetTilePatch()
        {
            int width = 256;
            int height = 256;

            GeoRect intersectionRect = GeoRect.Intersect(gridBox, tileBox);

            if (intersectionRect != null)
            {
                int startPointX = (int)(width * (intersectionRect.Left - tileBox.Left) / tileBox.Width);
                int startPointY = (int)(height * (tileBox.Top - intersectionRect.Top) / tileBox.Height);

                int endPointX = (int)(width * (intersectionRect.Right - tileBox.Left) / tileBox.Width);
                int endPointY = (int)(height * (tileBox.Top - intersectionRect.Bottom) / tileBox.Height);

                const int bitsPerPixel = 32;
                int stride = (endPointX - startPointX) * ((bitsPerPixel + 7) / 8);
                int arraySize = stride * (endPointY - startPointY);
                byte[] pixels = new byte[arraySize];
                int index = 0;


                // Get data and min/max.
                double[,] data = field.Data;
                double minT, maxT;

                MathHelper.GetMaxMin(field.Data, out maxT, out minT);

                this.minT = minT;
                this.maxT = maxT;


                double k = 1.0 / (maxT - minT);

                GeoToBitmap[] latToBitmap = new GeoToBitmap[endPointY - startPointY];
                for (int i = 0; i < endPointY - startPointY; i++)
                {
                    double y = intersectionRect.Top - (i + 0.5) * intersectionRect.Height / (endPointY - startPointY);
                    for (int j = 1; j < field.Height; j++)
                    {
                        if (y < field.Y[j])
                        {
                            latToBitmap[i] = new GeoToBitmap { Knot = j, Proportion = ((y - field.Y[j - 1]) / (field.Y[j] - field.Y[j - 1])) };
                            break;
                        }
                    }
                }

                GeoToBitmap[] lonToBitmap = new GeoToBitmap[endPointX - startPointX];
                for (int i = 0; i < endPointX - startPointX; i++)
                {
                    double x = ((i + 0.5) * intersectionRect.Width / (endPointX - startPointX)) + intersectionRect.Left;
                    for (int j = 1; j < field.Width; j++)
                    {
                        if (x < field.X[j])
                        {
                            lonToBitmap[i] = new GeoToBitmap { Knot = j, Proportion = ((x - field.X[j - 1]) / (field.X[j] - field.X[j - 1])) };
                            break;
                        }
                    }
                }

                for (int j = 0; j < endPointY - startPointY; j++)
                {
                    for (int i = 0; i < endPointX - startPointX; i++)
                    {
                        int knotY = latToBitmap[j].Knot;
                        int knotX = lonToBitmap[i].Knot;

                        double proportionY = latToBitmap[j].Proportion;
                        double proportionX = lonToBitmap[i].Proportion;

                        double colorValue = Interpolate(
                            data[knotX - 1, knotY - 1],
                            data[knotX - 1, knotY],
                            data[knotX, knotY - 1],
                            data[knotX, knotY],
                            proportionX,
                            proportionY);

                        System.Windows.Media.Color color = palette.GetColor((colorValue - minT) * k);

                        //byte b1, b2;
                        //ConvertColor(color,out b1,out b2);
                        //pixels[index++] = b2;
                        //pixels[index++] = b1;

                        pixels[index++] = color.B;
                        pixels[index++] = color.G;
                        pixels[index++] = color.R;
                        pixels[index++] = (byte)255;
                    }
                }

                index = 0;
                bool need = true;
                for (int j = 0; j < endPointY - startPointY; j++)
                {
                    for (int i = 0; i < endPointX - startPointX; i++)
                    {
                        int currentIndex = index;

                        System.Windows.Media.Color oldColor = new System.Windows.Media.Color()
                        {
                            A = pixels[currentIndex + 3],
                            R = pixels[currentIndex + 2],
                            G = pixels[currentIndex + 1],
                            B = pixels[currentIndex]
                        };
                        System.Windows.Media.Color newColor = FindClosestColor(oldColor);
                        QuantError quant_error = new QuantError
                        {
                            A = oldColor.A,
                            B = (int)oldColor.B - (int)newColor.B,
                            G = (int)oldColor.G - (int)newColor.G,
                            R = (int)oldColor.R - (int)newColor.R
                        };

                        //pixels[i,j]
                        pixels[currentIndex] = newColor.B;
                        pixels[currentIndex + 1] = newColor.G;
                        pixels[currentIndex + 2] = newColor.R;
                        pixels[currentIndex + 3] = newColor.A;

                        if (need)
                        {
                            int newValue = 0;
                            int maxValueRB = 255;

                            if (i < endPointX - startPointX - 1)
                            {

                                //pixels[i+1,j]
                                newValue = (int)pixels[currentIndex + 4] + ((quant_error.B * 7) >> 4);
                                pixels[currentIndex + 4] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));


                                newValue = (int)pixels[currentIndex + 4 + 1] + ((quant_error.G * 7) >> 4);
                                pixels[currentIndex + 4 + 1] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));


                                newValue = (int)pixels[currentIndex + 4 + 2] + ((quant_error.R * 7) >> 4);
                                pixels[currentIndex + 4 + 2] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));
                            }

                            if (j < endPointY - startPointY - 1)
                            {

                                //pixels[i,j+1]
                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX)] + ((quant_error.B * 5) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX)] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));

                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) + 1] + ((quant_error.G * 5) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) + 1] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));

                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) + 2] + ((quant_error.R * 5) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) + 2] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));
                            }

                            if (i > 0 && j < (endPointY - startPointY - 1))
                            {
                                //pixels[i-1,j+1]
                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) - 4] + ((quant_error.B * 3) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) - 4] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));

                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) - 4 + 1] + ((quant_error.G * 3) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) - 4 + 1] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));

                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) - 4 + 2] + ((quant_error.R * 3) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) - 4 + 2] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));
                            }

                            if (i < (endPointX - startPointX - 1) && j < (endPointY - startPointY - 1))
                            {
                                //pixels[i+1, j+1]
                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) + 4] + ((quant_error.B * 1) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) + 4] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));

                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) + 4 + 1] + ((quant_error.G * 1) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) + 4 + 1] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));

                                newValue = (int)pixels[currentIndex + 4 * (endPointX - startPointX) + 4 + 2] + ((quant_error.R * 1) >> 4);
                                pixels[currentIndex + 4 * (endPointX - startPointX) + 4 + 2] = (byte)Math.Max(0, Math.Min(maxValueRB, newValue));
                            }
                        }

                        index += 4;
                    }
                }

                index = 0;
                for (int j = 0; j < endPointY - startPointY; j++)
                {
                    for (int i = 0; i < endPointX - startPointX; i++)
                    {


                        System.Windows.Media.Color color = new System.Windows.Media.Color()
                        {
                            B = pixels[index],
                            G = pixels[index + 1],
                            R = pixels[index + 2]
                        };
                        color = FindClosestColor(color);
                        pixels[index] = color.B;
                        pixels[index + 1] = color.G;
                        pixels[index + 2] = color.R;
                        index += 4;
                    }
                }

                RasterPatch2 patch = new RasterPatch2(
                    new Box2(Wgs84CoordinateReferenceSystem.Instance, new Coordinate2D(intersectionRect.X, intersectionRect.Y), new Coordinate2D(intersectionRect.Right, intersectionRect.Top)),
                    pixels,
                    PatchPixelFormat.Format32bppArgb,
                    endPointX - startPointX,
                    endPointY - startPointY,
                    stride,
                    Wgs84CoordinateReferenceSystem.Instance);

                return patch;

            }
            else
            {
                return null;
            }
        }