public static System.Windows.Shapes.Shape RenderPolygon(Polygon polygon, IStyle style, IViewport viewport, SymbolCache symbolCache) { if (!(style is VectorStyle)) { throw new ArgumentException("Style is not of type VectorStyle"); } var vectorStyle = style as VectorStyle; System.Windows.Shapes.Path path = CreatePolygonPath(vectorStyle, viewport.Resolution, symbolCache, (float)viewport.Rotation); path.Data = polygon.ToXaml(); var matrixTransform = new System.Windows.Media.MatrixTransform { Matrix = GeometryRenderer.CreateTransformMatrix1(viewport) }; path.RenderTransform = matrixTransform; if (path.Fill != null) { path.Fill.Transform = matrixTransform.Inverse as System.Windows.Media.MatrixTransform; } path.UseLayoutRounding = true; return(path); }
private static XamlShapes.Shape CreateSymbolFromBitmap(int bitmapId, double opacity, SymbolCache symbolCache) { var imageBrush = symbolCache.GetOrCreate(bitmapId).ToImageBrush(); // note: It probably makes more sense to use PixelWidth here: var width = imageBrush.ImageSource.Width; var height = imageBrush.ImageSource.Height; var path = new XamlShapes.Path { Data = new XamlMedia.RectangleGeometry { Rect = new Rect(-width * 0.5, -height * 0.5, width, height) }, Fill = imageBrush, Opacity = opacity }; return(path); }
private static XamlMedia.Brush ToXaml(Brush brush, SymbolCache symbolCache, float rotate = 0f) { return(brush != null && (brush.Color != null || brush.BitmapId != -1) ? brush.ToXaml(symbolCache, rotate) : new XamlMedia.SolidColorBrush(XamlColors.Transparent)); }
public static System.Windows.Shapes.Path CreatePolygonPath(VectorStyle style, double resolution, SymbolCache symbolCache, float rotate = 0f) { var path = new System.Windows.Shapes.Path { Opacity = style.Opacity }; if (style.Outline != null) { path.Stroke = new System.Windows.Media.SolidColorBrush(style.Outline.Color.ToXaml()); path.StrokeThickness = style.Outline.Width * resolution; path.StrokeDashArray = style.Outline.PenStyle.ToXaml(style.Outline.DashArray); path.StrokeLineJoin = style.Outline.StrokeJoin.ToXaml(); path.StrokeMiterLimit = style.Outline.StrokeMiterLimit; path.Tag = style.Outline.Width; // see #linewidthhack } path.Fill = style.Fill.ToXaml(symbolCache, rotate); path.IsHitTestVisible = false; return(path); }
public static Media.Brush ToXaml(this Brush brush, SymbolCache symbolCache = null) { return(StyleConverter.MapsuiBrushToXaml(brush, symbolCache)); }
private static XamlShapes.Shape CreateSymbolFromVectorStyle(VectorStyle style, double opacity = 1, SymbolType symbolType = SymbolType.Ellipse, SymbolCache symbolCache = null, float rotate = 0f) { // The SL StrokeThickness default is 1 which causes blurry bitmaps var path = new XamlShapes.Path { StrokeThickness = 0, Fill = ToXaml(style.Fill, symbolCache, rotate) }; if (style.Outline != null) { path.Stroke = new XamlMedia.SolidColorBrush(style.Outline.Color.ToXaml()); path.StrokeThickness = style.Outline.Width; path.StrokeDashArray = style.Outline.PenStyle.ToXaml(style.Outline.DashArray); } switch (symbolType) { case SymbolType.Ellipse: path.Data = CreateEllipse(SymbolStyle.DefaultWidth, SymbolStyle.DefaultHeight); break; case SymbolType.Rectangle: path.Data = CreateRectangle(SymbolStyle.DefaultWidth, SymbolStyle.DefaultHeight); break; case SymbolType.Triangle: path.Data = CreateTriangle(SymbolStyle.DefaultWidth); break; default: // Invalid value throw new ArgumentOutOfRangeException(); } path.Opacity = opacity; return(path); }
private static void RenderFeature(IViewport viewport, Canvas canvas, IFeature feature, IStyle style, SymbolCache symbolCache, bool rasterizing) { if (style is LabelStyle) { var labelStyle = (LabelStyle)style; var labelText = labelStyle.GetLabelText(feature); if (string.IsNullOrEmpty(labelText)) { return; } canvas.Children.Add(LabelRenderer.RenderLabel(feature.Geometry.GetBoundingBox().GetCentroid(), labelStyle, viewport, labelText)); } else { Shape renderedGeometry; if (feature.RenderedGeometry.TryGetValue(style, out var cachedObject)) { renderedGeometry = (Shape)cachedObject; // Has to be Shape PositionGeometry(renderedGeometry, viewport, style, feature); } else { renderedGeometry = RenderGeometry(viewport, style, feature, symbolCache); if (!rasterizing) { feature.RenderedGeometry[style] = renderedGeometry; } } if (!canvas.Children.Contains(renderedGeometry)) { // Adding twice can happen when a single feature has two identical styles canvas.Children.Add(renderedGeometry); } } }
private static Canvas RenderLayerStatic(IViewport viewport, ILayer layer, SymbolCache symbolCache, bool rasterizing = false) { // todo: // find solution for try catch. Sometimes this method will throw an exception // when clearing and adding features to a layer while rendering var canvas = new Canvas { Opacity = layer.Opacity, IsHitTestVisible = false }; try { var features = layer.GetFeaturesInView(viewport.Extent, viewport.Resolution).ToList(); var layerStyles = BaseLayer.GetLayerStyles(layer); // If rasterizing (which is usually on a background thread) create a new SymbolCache // just for this rendering because cross thread access is not allowed in WPF. if (rasterizing) { symbolCache = new SymbolCache(); } foreach (var layerStyle in layerStyles) { var style = layerStyle; // This is the default that could be overridden by an IThemeStyle foreach (var feature in features) { if (layerStyle is IThemeStyle) { style = (layerStyle as IThemeStyle).GetStyle(feature); } if (style == null || style.Enabled == false || style.MinVisible > viewport.Resolution || style.MaxVisible < viewport.Resolution) { continue; } RenderFeature(viewport, canvas, feature, style, symbolCache, rasterizing); } } foreach (var feature in features) { var styles = feature.Styles ?? Enumerable.Empty <IStyle>(); foreach (var style in styles) { if (feature.Styles != null && style.Enabled) { RenderFeature(viewport, canvas, feature, style, symbolCache, rasterizing); } } } return(canvas); } catch (Exception ex) { Logger.Log(LogLevel.Error, "Unexpected error in xaml renderer", ex); return(canvas); // If exception happens inside RenderFeature function after // at -least one child has been added to the canvas, // returning new canvas will leave the previously created (but // not yet added to parent canvas) canvas abandoned, that will // cause the exception when resuing RenderedGeometry object, because // at -least one RenderedGeometry was attached to that abandoned canvas. // returning the same canvas will solve this error, as it will // be clear this canvas childs on next render call. // return new Canvas { IsHitTestVisible = false }; } }
public static void RenderLayer(Canvas target, IViewport viewport, ILayer layer, SymbolCache symbolCache, bool rasterizing = false) { if (layer.Enabled == false) { return; } target.Children.Add(RenderLayerStatic(viewport, layer, symbolCache, rasterizing)); }
private static MemoryStream RenderToBitmapStreamStatic(IViewport viewport, IEnumerable <ILayer> layers, SymbolCache symbolCache) { var canvas = new Canvas(); Render(canvas, viewport, layers, symbolCache, true); var bitmapStream = BitmapRendering.BitmapConverter.ToBitmapStream(canvas, (int)viewport.Width, (int)viewport.Height); canvas.Children.Clear(); canvas.Dispatcher.InvokeShutdown(); return(bitmapStream); }
private static BitmapImage GetOrCreateBitmapImage(Styles.Brush brush, SymbolCache symbolCache = null) { return(symbolCache != null? symbolCache.GetOrCreate(brush.BitmapId) : BitmapRegistry.Instance.Get(brush.BitmapId).ToBitmapImage()); }