private static void RenderFeature(IViewport viewport, Canvas canvas, IFeature feature, IStyle style, bool rasterizing, BrushCache brushCache = null) { if (style is LabelStyle) { var labelStyle = (LabelStyle)style; canvas.Children.Add(SingleLabelRenderer.RenderLabel(feature.Geometry.GetBoundingBox().GetCentroid(), labelStyle, viewport, labelStyle.GetLabelText(feature))); } else { var renderedGeometry = feature.RenderedGeometry.ContainsKey(style) ? feature.RenderedGeometry[style] as Shape : null; if (renderedGeometry == null) { renderedGeometry = RenderGeometry(viewport, style, feature, brushCache); if (!rasterizing) { feature.RenderedGeometry[style] = renderedGeometry; } } else { PositionGeometry(renderedGeometry, viewport, style, feature); } if (!canvas.Children.Contains(renderedGeometry)) { // Adding twice can happen when a single feature has two identical styles canvas.Children.Add(renderedGeometry); } } }
private static void RenderFeature(IViewport viewport, Canvas canvas, IFeature feature, IStyle style, SymbolCache symbolCache, bool rasterizing) { if (style is LabelStyle) { var labelStyle = (LabelStyle)style; canvas.Children.Add(SingleLabelRenderer.RenderLabel(feature.Geometry.GetBoundingBox().GetCentroid(), labelStyle, viewport, labelStyle.GetLabelText(feature))); } else { Shape renderedGeometry; object cachedObject; if (feature.RenderedGeometry.TryGetValue(style, out 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); } } }
public static Canvas RenderLabelLayer(IViewport viewport, LabelLayer layer) { var canvas = new Canvas { Opacity = layer.Opacity }; // todo: take into account the priority var features = layer.GetFeaturesInView(viewport.Extent, viewport.Resolution).ToList(); var layerStyles = BaseLayer.GetLayerStyles(layer); foreach (var layerStyle in layerStyles) { foreach (var feature in features) { var style = (layerStyle is IThemeStyle) ? (layerStyle as IThemeStyle).GetStyle(feature) : layerStyle; if ((style == null) || (style.Enabled == false) || (style.MinVisible > viewport.Resolution) || (style.MaxVisible < viewport.Resolution)) { continue; } if (!(style is LabelStyle)) { throw new Exception("Style of label is not a LabelStyle"); } var labelStyle = style as LabelStyle; labelStyle.Text = layer.GetLabelText(feature); var postion = feature.Geometry.GetBoundingBox().GetCentroid(); var labelText = labelStyle.GetLabelText(feature); canvas.Children.Add(SingleLabelRenderer.RenderLabel(postion, labelStyle, viewport, labelText)); } } return(canvas); }
public static Canvas Render(IViewport viewport, LabelLayer layer) { // todo: Move stack functionality to Mapsui core. // step 1) Split RenderStackedLabelLayer into a method // GetFeaturesInViewStacked en a RenderStackedLabel // which can later be replace by normal label rendering. // The method GetFeaturesInViewStacked // returns a style with an offset determined by the stackoffset // and a position determined by CenterX en Cluster.Box.Bottom. // step 2) Move GetFeaturesInViewStacked to a GetFeaturesInView // method of a new StackedLabelLayed. var canvas = new Canvas { Opacity = layer.Opacity }; // todo: take into account the priority var features = layer.GetFeaturesInView(viewport.Extent, viewport.Resolution).ToArray(); var margin = viewport.Resolution * 50; const int symbolSize = 32; // todo: determine margin by symbol size const int boxMargin = symbolSize / 2; var clusters = new List <Cluster>(); //todo: repeat until there are no more merges ClusterFeatures(clusters, features, margin, layer.Style, viewport.Resolution); const int textHeight = 18; foreach (var cluster in clusters) { var stackOffsetY = double.NaN; var orderedFeatures = cluster.Features.OrderBy(f => f.Geometry.GetBoundingBox().GetCentroid().Y); if (cluster.Features.Count > 1) { canvas.Children.Add(RenderBox(cluster.Box, viewport)); } foreach (var feature in orderedFeatures) { if (double.IsNaN(stackOffsetY)) // first time { stackOffsetY = textHeight * 0.5 + boxMargin; } else { stackOffsetY += textHeight; //todo: get size from text (or just pass stack nr) } LabelStyle style; if (layer.Style is IThemeStyle) { style = (LabelStyle)((IThemeStyle)layer.Style).GetStyle(feature); } else { style = (LabelStyle)layer.Style; } var labelStyle = new LabelStyle(style) { Text = layer.GetLabelText(feature) //we only use the layer for the text, this should be returned by style }; labelStyle.Offset.Y += stackOffsetY; // Since the box can be rotated, find the minimal Y value of all 4 corners var rotatedBox = cluster.Box.Rotate(-viewport.Rotation); var minY = rotatedBox.Vertices.Select(v => v.Y).Min(); var position = new Point(cluster.Box.GetCentroid().X, minY); var labelText = labelStyle.GetLabelText(feature); canvas.Children.Add(SingleLabelRenderer.RenderLabel(position, labelStyle, viewport, labelText)); } } return(canvas); }