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