Example #1
0
        public static Canvas RenderStackedLabelLayer(IViewport viewport, LabelLayer layer)
        {
            var canvas = new Canvas();

            canvas.Opacity = layer.Opacity;

            //todo: take into account the priority
            var features = layer.GetFeaturesInView(viewport.Extent, viewport.Resolution);
            var margin   = viewport.Resolution * 50;

            foreach (var layerStyle in layer.Styles)
            {
                var style = layerStyle;

                var clusters = new List <Cluster>();
                //todo: repeat until there are no more merges
                ClusterFeatures(clusters, features, margin, layerStyle, viewport.Resolution);

                foreach (var cluster in clusters)
                {
                    Offset stackOffset = null;

                    foreach (var feature in cluster.Features.OrderBy(f => f.Geometry.GetBoundingBox().GetCentroid().Y))
                    {
                        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;
                        }

                        if (stackOffset == null) //first time
                        {
                            stackOffset = new Offset();
                            if (cluster.Features.Count > 1)
                            {
                                canvas.Children.Add(RenderBox(cluster.Box, viewport));
                            }
                        }
                        else
                        {
                            stackOffset.Y += 18;  //todo: get size from text, (or just pass stack nr)
                        }
                        if (!(style is LabelStyle))
                        {
                            throw new Exception("Style of label is not a LabelStyle");
                        }
                        var    labelStyle = style as LabelStyle;
                        string labelText  = layer.GetLabel(feature);
                        var    position   = new Mapsui.Geometries.Point(cluster.Box.GetCentroid().X, cluster.Box.Bottom);
                        canvas.Children.Add(RenderLabel(position, stackOffset, labelStyle, viewport, labelText));
                    }
                }
            }

            return(canvas);
        }
Example #2
0
        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);
        }
Example #3
0
        public static void Render(Graphics graphics, IViewport viewport, LabelLayer labelLayer)
        {
            var layerStyles = BaseLayer.GetLayerStyles(labelLayer);

            foreach (var layerStyle in layerStyles)
            {
                if (layerStyle.Enabled && labelLayer.MaxVisible >= viewport.Resolution && labelLayer.MinVisible < viewport.Resolution)
                {
                    if (labelLayer.DataSource == null)
                    {
                        throw (new ApplicationException("DataSource property not set"));
                    }

                    graphics.SmoothingMode = SmoothingMode.AntiAlias;

                    var features = labelLayer.GetFeaturesInView(viewport.Extent, viewport.Resolution);

                    //Initialize label collection
                    var labels = new List <Label>();

                    var style = layerStyle as LabelStyle;

                    //List<System.Drawing.Rectangle> LabelBoxes; //Used for collision detection
                    //Render labels
                    foreach (IFeature feature in features)
                    {
                        if (layerStyle is IThemeStyle)
                        {
                            style = (layerStyle as IThemeStyle).GetStyle(feature) as LabelStyle;
                        }

                        float rotation = 0;
                        if (!String.IsNullOrEmpty(labelLayer.RotationColumn))
                        {
                            rotation = float.Parse(feature[labelLayer.RotationColumn].ToString(), NumberStyles.Any, CultureInfo.InvariantCulture);
                        }

                        int priority = labelLayer.Priority;
                        if (labelLayer.PriorityDelegate != null)
                        {
                            priority = labelLayer.PriorityDelegate(feature);
                        }
                        else if (!String.IsNullOrEmpty(labelLayer.PriorityColumn))
                        {
                            priority = int.Parse(feature[labelLayer.PriorityColumn].ToString(), NumberStyles.Any, CultureInfo.InvariantCulture);
                        }

                        string text;

                        if (labelLayer.LabelStringDelegate != null)
                        {
                            text = labelLayer.LabelStringDelegate(feature);
                        }
                        else
                        {
                            text = feature[labelLayer.LabelColumn].ToString();
                        }

                        if (!string.IsNullOrEmpty(text))
                        {
                            if (feature.Geometry is GeometryCollection)
                            {
                                var geometryCollection = feature.Geometry as GeometryCollection;
                                if (labelLayer.MultipartGeometryBehaviour == LabelLayer.MultipartGeometryBehaviourEnum.All)
                                {
                                    foreach (var geometry in geometryCollection)
                                    {
                                        var label = CreateLabel(geometry, text, rotation, priority, style, viewport, graphics);
                                        if (label != null)
                                        {
                                            labels.Add(label);
                                        }
                                    }
                                }
                                else if (labelLayer.MultipartGeometryBehaviour == LabelLayer.MultipartGeometryBehaviourEnum.CommonCenter)
                                {
                                    var label = CreateLabel(feature.Geometry, text, rotation, priority, style, viewport, graphics);
                                    if (label != null)
                                    {
                                        labels.Add(label);
                                    }
                                }
                                else if (labelLayer.MultipartGeometryBehaviour == LabelLayer.MultipartGeometryBehaviourEnum.First)
                                {
                                    if ((feature.Geometry as GeometryCollection).Collection.Count > 0)
                                    {
                                        Label label = CreateLabel(geometryCollection.Collection[0], text, rotation, 0,
                                                                  style, viewport, graphics);
                                        if (label != null)
                                        {
                                            labels.Add(label);
                                        }
                                    }
                                }
                                else if (labelLayer.MultipartGeometryBehaviour == LabelLayer.MultipartGeometryBehaviourEnum.Largest)
                                {
                                    var coll = (feature.Geometry as GeometryCollection);
                                    if (coll.NumGeometries > 0)
                                    {
                                        double largestVal   = 0;
                                        int    idxOfLargest = 0;
                                        for (var j = 0; j < coll.NumGeometries; j++)
                                        {
                                            Geometry geom = coll.Geometry(j);
                                            if (geom is LineString && ((LineString)geom).Length > largestVal)
                                            {
                                                largestVal   = ((LineString)geom).Length;
                                                idxOfLargest = j;
                                            }
                                            if (geom is MultiLineString && ((MultiLineString)geom).Length > largestVal)
                                            {
                                                largestVal   = ((MultiLineString)geom).Length;
                                                idxOfLargest = j;
                                            }
                                            if (geom is Polygon && ((Polygon)geom).Area > largestVal)
                                            {
                                                largestVal   = ((Polygon)geom).Area;
                                                idxOfLargest = j;
                                            }
                                            if (geom is MultiPolygon && ((MultiPolygon)geom).Area > largestVal)
                                            {
                                                largestVal   = ((MultiPolygon)geom).Area;
                                                idxOfLargest = j;
                                            }
                                        }

                                        var label = CreateLabel(coll.Geometry(idxOfLargest), text, rotation, priority, style,
                                                                viewport, graphics);
                                        if (label != null)
                                        {
                                            labels.Add(label);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                var label = CreateLabel(feature.Geometry, text, rotation, priority, style, viewport, graphics);
                                if (label != null)
                                {
                                    labels.Add(label);
                                }
                            }
                        }
                    }

                    if (labels.Count > 0) //We have labels to render...
                    {
                        if ((layerStyle is LabelStyle) && (layerStyle as LabelStyle).CollisionDetection && labelLayer.LabelFilter != null)
                        {
                            labelLayer.LabelFilter(labels);
                        }
                        foreach (Label label in labels)
                        {
                            if (!label.Show)
                            {
                                continue;
                            }
                            LabelRenderer.DrawLabel(graphics, label.LabelPoint, label.Style.Offset, label.Style.Font,
                                                    label.Style.ForeColor, label.Style.BackColor, label.Halo, label.Rotation, label.Text, viewport);
                        }
                    }
                }
            }
        }
Example #4
0
        public static List <IFeature> RenderStackedLabelLayer(IViewport viewport, LabelLayer layer)
        {
            var renderedFeatures = new List <IFeature> ();
            var canvas           = new CALayer();

            canvas.Opacity = (float)layer.Opacity;

            //todo: take into account the priority
            var features = layer.GetFeaturesInView(viewport.Extent, viewport.Resolution);
            var margin   = viewport.Resolution * 50;

            if (layer.Style != null)
            {
                var clusters = new List <Cluster>();
                //todo: repeat until there are no more merges
                ClusterFeatures(clusters, features, margin, layer.Style, viewport.Resolution);

                foreach (var cluster in clusters)
                {
                    var feature = cluster.Features.OrderBy(f => f.Geometry.GetBoundingBox().GetCentroid().Y).FirstOrDefault();
                    //SetFeatureOutline (feature, layer.Name, cluster.Features.Count);
                    //var bb = RenderBox(cluster.Box, viewport);

                    //Zorg dat dit ALTIJD decimal zelfde ISet als ViewChanged is
                    //var feature = cluster.Features.FirstOrDefault ();

                    var styles = feature.Styles ?? Enumerable.Empty <IStyle>();
                    foreach (var style in styles)
                    {
                        if (feature.Styles != null && style.Enabled)
                        {
                            var styleKey         = layer.Name;                     //feature.GetHashCode ().ToString ();
                            var renderedGeometry = (feature[styleKey] != null) ? (CALayer)feature[styleKey] : null;
                            var labelText        = layer.GetLabelText(feature);

                            if (renderedGeometry == null)
                            {
                                //Mapsui.Geometries.Point point, Offset stackOffset, LabelStyle style, IFeature feature, IViewport viewport, string text)
                                renderedGeometry = RenderLabel(feature.Geometry as Mapsui.Geometries.Point,
                                                               style as LabelStyle, feature, viewport, labelText);

                                feature [styleKey] = renderedGeometry;
                                feature ["first"]  = true;
                            }
                            else
                            {
                                feature ["first"] = false;
                            }
                        }
                    }
                    renderedFeatures.Add(feature);

                    /*
                     * Offset stackOffset = null;
                     *
                     * foreach (var feature in cluster.Features.OrderBy(f => f.Geometry.GetBoundingBox().GetCentroid().Y))
                     * {
                     *      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;
                     *
                     *      if (stackOffset == null) //first time
                     *      {
                     *              stackOffset = new Offset();
                     *              if (cluster.Features.Count > 1)
                     *                      canvas.AddSublayer (RenderBox(cluster.Box, viewport));
                     *      }
                     *      else stackOffset.Y += 18; //todo: get size from text, (or just pass stack nr)
                     *
                     *      if (!(style is LabelStyle)) throw new Exception("Style of label is not a LabelStyle");
                     *      var labelStyle = style as LabelStyle;
                     *      string labelText = layer.GetLabel(feature);
                     *      var position = new Mapsui.Geometries.Point(cluster.Box.GetCentroid().X, cluster.Box.Bottom);
                     *      canvas.AddSublayer(RenderLabel(position, stackOffset, labelStyle, feature, viewport, labelText));
                     * }
                     */
                }
            }

            return(renderedFeatures);
        }
        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);
        }