Beispiel #1
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);
            }
        }
Beispiel #2
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(IDataSource2D <double> field, Box2 regionBox, double iconSize)
        {
            System.Windows.Point[,] grid = field.Grid;

            Coordinate2D minCoordinate = new Coordinate2D(grid[0, 0].X, grid[0, 0].Y);
            Coordinate2D maxCoordinate = new Coordinate2D(grid[field.Width - 1, field.Height - 1].X, grid[field.Width - 1, field.Height - 1].Y);


            for (int j = 0; j < field.Height; j++)
            {
                for (int i = 0; i < field.Width; i++)
                {
                    if (grid[i, j].X < minCoordinate.X)
                    {
                        minCoordinate.X = grid[i, j].X;
                    }

                    if (grid[i, j].X > maxCoordinate.X)
                    {
                        maxCoordinate.X = grid[i, j].X;
                    }

                    if (grid[i, j].Y < minCoordinate.Y)
                    {
                        minCoordinate.Y = grid[i, j].Y;
                    }

                    if (grid[i, j].Y > maxCoordinate.Y)
                    {
                        maxCoordinate.Y = grid[i, j].Y;
                    }
                }
            }

            GeoRect gridBox = new GeoRect(
                minCoordinate.X,
                minCoordinate.Y,
                maxCoordinate.X - minCoordinate.X,
                maxCoordinate.Y - minCoordinate.Y);

            GeoRect tileBox = new GeoRect(
                regionBox.MinCoordinate.X,
                regionBox.MinCoordinate.Y,
                regionBox.MaxCoordinate.X - regionBox.MinCoordinate.X,
                regionBox.MaxCoordinate.Y - regionBox.MinCoordinate.Y);

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

            if (intersectionRect != null)
            {
                int      width        = 256;
                int      height       = 256;
                Bitmap   resultBitmap = new Bitmap(width, height);
                Graphics graphics     = Graphics.FromImage(resultBitmap);
                for (int i = 0; i < field.Width; i++)
                {
                    for (int j = 0; j < field.Height; j++)
                    {
                        GeoRect workingRect = new GeoRect(
                            field.Grid[i, j].X - iconSize / 2.0,
                            field.Grid[i, j].Y - iconSize / 2.0,
                            iconSize,
                            iconSize);
                        if (GeoRect.IntersectionExist(workingRect, intersectionRect))
                        {
                            int x0 = (int)(Math.Min(width, Math.Max(0, field.Grid[i, j].X - iconSize / 2.0 - tileBox.Left) / tileBox.Width * width));
                            int y0 = (int)(Math.Min(height, Math.Max(0, tileBox.Top - field.Grid[i, j].Y - iconSize / 2.0) / tileBox.Height * height));

                            int x1 = (int)(Math.Min(width, Math.Max(0, field.Grid[i, j].X + iconSize / 2.0 - tileBox.Left) / tileBox.Width * width));
                            int y1 = (int)(Math.Min(height, Math.Max(0, tileBox.Top - field.Grid[i, j].Y + iconSize / 2.0) / tileBox.Height * height));

                            double widthX  = Math.Min(tileBox.Width, iconSize);
                            double heightY = Math.Min(tileBox.Height, iconSize);


                            lock (icon)
                            {
                                int x2 = 0;
                                if (field.Grid[i, j].X - iconSize / 2.0 < tileBox.Left)
                                {
                                    x2 = icon.Width - (int)((double)(x1 - x0) * icon.Width / (widthX / tileBox.Width * width));
                                }

                                int y2 = 0;
                                if (tileBox.Top - field.Grid[i, j].Y - iconSize / 2.0 < 0)
                                {
                                    y2 = icon.Height - (int)((double)(y1 - y0) * icon.Height / (heightY / tileBox.Height * height));
                                }

                                graphics.DrawImage(
                                    icon,
                                    new Rectangle(x0, y0, x1 - x0, y1 - y0),
                                    x2,
                                    y2,
                                    (int)((double)(x1 - x0) * icon.Width / (widthX / tileBox.Width * width)),
                                    (int)((double)(y1 - y0) * icon.Height / (heightY / tileBox.Height * height)),
                                    GraphicsUnit.Pixel);
                            }
                        }
                    }
                }
                return(new RasterPatch2(
                           regionBox,
                           resultBitmap,
                           Wgs84CoordinateReferenceSystem.Instance));
            }
            else
            {
                return(null);
            }
        }