/// <summary> /// Handles the RunWorkerCompleted event of the renderThread control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.ComponentModel.RunWorkerCompletedEventArgs"/> instance containing the event data.</param> private void renderThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { if (enqueueExport != null) //cancelled because new image was requested. Create new image { GetSource(enqueueExport, enqueueOnComplete); enqueueExport = null; enqueueOnComplete = null; } return; } enqueueExport = null; enqueueOnComplete = null; if (e.Result == null) { return; } object[] result = (object[])e.Result; int width = (int)result[1]; int height = (int)result[2]; Envelope extent = (Envelope)result[3]; OnImageComplete onComplete = (OnImageComplete)result[4]; #if SILVERLIGHT BitmapImage image = new BitmapImage(); PngEncoder ei = (PngEncoder)result[0]; image.SetSource(ei.GetImageStream()); #else List <Color> colors = new List <Color>(); colors.Add(Colors.Violet); colors.Add(Colors.Yellow); BitmapPalette palette = new BitmapPalette(colors); System.Windows.Media.PixelFormat pf = System.Windows.Media.PixelFormats.Bgra32; int stride = width * (pf.BitsPerPixel / 8); BitmapSource image = BitmapSource.Create(width, height, 96, 96, pf, palette, (int[])result[0], stride); #endif onComplete(image, new ImageResult(extent)); }
/// <summary> /// Handles the DoWork event of the renderThread control. This is where we /// render the heatmap outside the UI thread. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.ComponentModel.DoWorkEventArgs"/> instance /// containing the event data.</param> private void renderThread_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = (BackgroundWorker)sender; object[] args = (object[])e.Argument; Envelope extent = (Envelope)args[0]; int width = (int)args[1]; int height = (int)args[2]; int size = (int)args[3]; List <ThreadSafeGradientStop> stops = (List <ThreadSafeGradientStop>)args[4]; List <HeatPoint> points = (List <HeatPoint>)args[5]; OnImageComplete onComplete = (OnImageComplete)args[6]; size = size * 2 + 1; ushort[] matrix = CreateDistanceMatrix(size); int[] output = new int[width * height]; foreach (HeatPoint p in points) { AddPoint(matrix, size, p.X, p.Y, output, width); if (worker.CancellationPending) { e.Cancel = true; e.Result = null; return; } } matrix = null; int max = 0; foreach (int val in output) //find max - used for scaling the intensity { if (max < val) { max = val; } } //If we only have single points in the view, don't show them with too much intensity. if (max < 2) { max = 2; } #if SILVERLIGHT PngEncoder ei = new PngEncoder(width, height); #else int[] pixels = new int[height * width]; #endif for (int idx = 0; idx < height; idx++) // Height (y) { #if SILVERLIGHT int rowstart = ei.GetRowStart(idx); #endif for (int jdx = 0; jdx < width; jdx++) // Width (x) { Color c = InterpolateColor(output[idx * width + jdx] / (float)max, stops); #if SILVERLIGHT ei.SetPixelAtRowStart(jdx, rowstart, c.R, c.G, c.B, c.A); #else int color = (c.A << 24) + (c.R << 16) + (c.G << 8) + c.B; pixels[idx * width + jdx] = color; #endif } if (worker.CancellationPending) { e.Cancel = true; e.Result = null; output = null; #if SILVERLIGHT ei = null; #else pixels = null; #endif return; } //Raise the progress event for each line rendered worker.ReportProgress((idx + 1) * 100 / height); } stops.Clear(); output = null; // Get stream and set image source #if SILVERLIGHT e.Result = new object[] { ei, width, height, extent, onComplete }; #else e.Result = new object[] { pixels, width, height, extent, onComplete }; #endif }
/// <summary> /// Handles the DoWork event of the renderThread control. This is where we /// render the heatmap outside the UI thread. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.ComponentModel.DoWorkEventArgs"/> instance /// containing the event data.</param> private void renderThread_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = (BackgroundWorker)sender; object[] args = (object[])e.Argument; Envelope extent = (Envelope)args[0]; int width = (int)args[1]; int height = (int)args[2]; int size = (int)args[3]; List<ThreadSafeGradientStop> stops = (List<ThreadSafeGradientStop>)args[4]; List<HeatPoint> points = (List<HeatPoint>)args[5]; OnImageComplete onComplete = (OnImageComplete)args[6]; size = size * 2 + 1; ushort[] matrix = CreateDistanceMatrix(size); int[] output = new int[width * height]; foreach (HeatPoint p in points) { AddPoint(matrix, size, p.X, p.Y, output, width); if (worker.CancellationPending) { e.Cancel = true; e.Result = null; return; } } matrix = null; int max = 0; foreach (int val in output) //find max - used for scaling the intensity if (max < val) max = val; //If we only have single points in the view, don't show them with too much intensity. if (max < 2) max = 2; #if SILVERLIGHT PngEncoder ei = new PngEncoder(width, height); #else int[] pixels = new int[height*width]; #endif for (int idx = 0; idx < height; idx++) // Height (y) { #if SILVERLIGHT int rowstart = ei.GetRowStart(idx); #endif for (int jdx = 0; jdx < width; jdx++) // Width (x) { Color c = InterpolateColor(output[idx * width + jdx] / (float)max, stops); #if SILVERLIGHT ei.SetPixelAtRowStart(jdx, rowstart, c.R, c.G, c.B, c.A); #else int color = (c.A << 24) + (c.R << 16) + (c.G << 8) + c.B; pixels[idx * width + jdx] = color; #endif } if (worker.CancellationPending) { e.Cancel = true; e.Result = null; output = null; #if SILVERLIGHT ei = null; #else pixels = null; #endif return; } //Raise the progress event for each line rendered worker.ReportProgress((idx + 1) * 100 / height); } stops.Clear(); output = null; // Get stream and set image source #if SILVERLIGHT e.Result = new object[] { ei, width, height, extent, onComplete }; #else e.Result = new object[] { pixels, width, height, extent, onComplete }; #endif }