示例#1
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);
            }
        }
        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;
            }
        }