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); } }
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); } }