private void Render(SKCanvas canvas, IReadOnlyViewport viewport, IEnumerable <ILayer> layers) { try { layers = layers.ToList(); VisibleFeatureIterator.IterateLayers(viewport, layers, (v, l, s, f, o) => { RenderFeature(canvas, v, l, s, f, o); }); RemovedUnusedBitmapsFromCache(); _currentIteration++; } catch (Exception exception) { Logger.Log(LogLevel.Error, "Unexpected error in skia renderer", exception); } }
public MapInfo GetMapInfo(double x, double y, IReadOnlyViewport viewport, IEnumerable <ILayer> layers, int margin = 0) { // todo: use margin to increase the pixel area // todo: We will need to select on style instead of layer layers = layers .Select(l => (l is RasterizingLayer rl) ? rl.ChildLayer : l) .Where(l => l.IsMapInfoLayer); var list = new List <MapInfoRecord>(); var result = new MapInfo() { ScreenPosition = new Point(x, y), WorldPosition = viewport.ScreenToWorld(x, y), Resolution = viewport.Resolution }; try { var width = (int)viewport.Width; var height = (int)viewport.Height; var imageInfo = new SKImageInfo(width, height, SKImageInfo.PlatformColorType, SKAlphaType.Unpremul); var intX = (int)x; var intY = (int)y; using (var surface = SKSurface.Create(imageInfo)) { if (surface == null) { return(null); } surface.Canvas.ClipRect(new SKRect((float)(x - 1), (float)(y - 1), (float)(x + 1), (float)(y + 1))); surface.Canvas.Clear(SKColors.Transparent); var pixmap = surface.PeekPixels(); var color = pixmap.GetPixelColor(intX, intY); VisibleFeatureIterator.IterateLayers(viewport, layers, (v, layer, style, feature, opacity) => { surface.Canvas.Save(); // 1) Clear the entire bitmap surface.Canvas.Clear(SKColors.Transparent); // 2) Render the feature to the clean canvas RenderFeature(surface.Canvas, v, layer, style, feature, opacity); // 3) Check if the pixel has changed. if (color != pixmap.GetPixelColor(intX, intY)) { // 4) Add feature and style to result list.Add(new MapInfoRecord(feature, style, layer)); } surface.Canvas.Restore(); }); } if (list.Count == 0) { return(result); } list.Reverse(); var itemDrawnOnTop = list.First(); result.Feature = itemDrawnOnTop.Feature; result.Style = itemDrawnOnTop.Style; result.Layer = itemDrawnOnTop.Layer; result.MapInfoRecords = list; } catch (Exception exception) { Logger.Log(LogLevel.Error, "Unexpected error in skia renderer", exception); } return(result); }