/// <summary>
        /// Test whether label collides.
        /// </summary>
        /// <param name="newLabel"></param>
        /// <returns>true if label collided with another (more important or earlier) label</returns>
        public Boolean SimpleCollisionTest(Label2D newLabel)
        {
            if (labelList.Contains(newLabel))
            {
                return(false);
            }

            Size2D newSize = TextRenderer.MeasureString(newLabel.Text, newLabel.Font);

            newSize = new Size2D(newSize.Width + 2 * newLabel.CollisionBuffer.Width, newSize.Height + 2 * newLabel.CollisionBuffer.Height);
            Rectangle2D newRect = new Rectangle2D(new Point2D(newLabel.Location.X - newLabel.CollisionBuffer.Width, newLabel.Location.Y - newLabel.CollisionBuffer.Height), newSize);

            foreach (Label2D label in labelList)
            {
                Size2D size = TextRenderer.MeasureString(label.Text, label.Font);
                size = new Size2D(size.Width + 2 * label.CollisionBuffer.Width, size.Height + 2 * label.CollisionBuffer.Height);
                Rectangle2D rect =
                    new Rectangle2D(
                        new Point2D(label.Location.X - newLabel.CollisionBuffer.Width, label.Location.Y - label.CollisionBuffer.Height),
                        size);

                if (newRect.Intersects(rect))
                {
                    return(true);
                }
            }

            labelList.Add(newLabel);

            return(false);
        }
 /// <summary>
 /// Test whether label collides.
 /// </summary>
 /// <param name="newLabel"></param>
 /// <returns>true if label collided with another (more important or earlier) label</returns>
 public Boolean AdvancedCollisionTest(Label2D newLabel)
 {
     if (labelList.Contains(newLabel))
     {
         return(false);
     }
     return(AdvancedCollisionTest(newLabel, 0));
 }
        ///// <summary>
        ///// Renders the layer to the <paramref name="view"/>.
        ///// </summary>
        ///// <param name="view"><see cref="IMapView2D"/> to render layer on.</param>
        ///// <param name="region">Area of the map to render.</param>
        //protected void Render(BoundingBox region)
        //{
        //    LabelLayer layer = null;

        //    if (Style.Enabled && Style.MaxVisible >= ViewTransformer.Zoom && Style.MinVisible < ViewTransformer.Zoom)
        //    {
        //        if (layer.DataSource == null)
        //            throw new InvalidOperationException("DataSource property not set on layer '" + layer.LayerName + "'");

        //        TextRenderingHint = Style.TextRenderingHint;
        //        StyleRenderingMode = Style.SmoothingMode;

        //        BoundingBox envelope = ViewTransformer.ViewEnvelope; //View to render

        //        if (layer.CoordinateTransformation != null)
        //            envelope = GeometryTransform.TransformBox(envelope, layer.CoordinateTransformation.MathTransform.Inverse());

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

        //        //Render labels
        //        foreach (FeatureDataRow feature in layer.GetFeatures(region))
        //        {
        //            if (layer.CoordinateTransformation != null)
        //                feature.Geometry = GeometryTransform.TransformGeometry(feature.Geometry, layer.CoordinateTransformation.MathTransform);

        //            LabelStyle style = null;

        //            if (this.Theme != null) //If thematics is enabled, lets override the style
        //                style = this.Theme.GetStyle(feature) as LabelStyle;
        //            else
        //                style = this.Style;

        //            Single rotation = 0;

        //            if (layer.RotationColumn != null && layer.RotationColumn != "")
        //                Single.TryParse(feature[layer.RotationColumn].ToString(), NumberStyles.Any, Map.NumberFormat_EnUS, out rotation);

        //            String text = layer.GetLabelText(feature);

        //            if (!String.IsNullOrEmpty(text))
        //            {
        //                if (feature.Geometry is GeometryCollection)
        //                {
        //                    if (layer.MultipartGeometryBehaviour == MultipartGeometryBehaviourEnum.All)
        //                    {
        //                        foreach (Geometry geom in (feature.Geometry as Geometries.GeometryCollection))
        //                        {
        //                            Label lbl = CreateLabel(geom, text, rotation, style);

        //                            if (lbl != null)
        //                                labels.Add(lbl);
        //                        }
        //                    }
        //                    else if (layer.MultipartGeometryBehaviour == MultipartGeometryBehaviourEnum.CommonCenter)
        //                    {
        //                        Label lbl = CreateLabel(feature.Geometry, text, rotation, style);

        //                        if (lbl != null)
        //                            labels.Add(lbl);
        //                    }
        //                    else if (layer.MultipartGeometryBehaviour == MultipartGeometryBehaviourEnum.First)
        //                    {
        //                        if ((feature.Geometry as GeometryCollection).Collection.Count > 0)
        //                        {
        //                            Label lbl = CreateLabel((feature.Geometry as GeometryCollection).Collection[0], text, rotation, style);

        //                            if (lbl != null)
        //                                labels.Add(lbl);
        //                        }
        //                    }
        //                    else if (layer.MultipartGeometryBehaviour == MultipartGeometryBehaviourEnum.Largest)
        //                    {
        //                        GeometryCollection coll = (feature.Geometry as GeometryCollection);
        //                        if (coll.NumGeometries > 0)
        //                        {
        //                            Double largestVal = 0;
        //                            Int32 idxOfLargest = 0;

        //                            for (Int32 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 = ((LineString)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;
        //                                }
        //                            }

        //                            Label lbl = CreateLabel(coll.Geometry(idxOfLargest), text, rotation, style);

        //                            if (lbl != null)
        //                                labels.Add(lbl);
        //                        }
        //                    }
        //                }
        //                else
        //                {
        //                    Label lbl = CreateLabel(feature.Geometry, text, rotation, style);
        //                    if (lbl != null)
        //                        labels.Add(lbl);
        //                }
        //            }
        //        }

        //        if (labels.Count > 0) //We have labels to render...
        //        {
        //            if (this.Style.CollisionDetection && layer.LabelFilter != null)
        //                layer.LabelFilter(labels);

        //            foreach (Label label in labels)
        //                DrawLabel(label);
        //        }

        //        labels = null;
        //    }

        //    //base.Render(view, region);
        //}

        ///// <summary>
        ///// Renders a label to the <paramref name="view"/>.
        ///// </summary>
        ///// <param name="text">Text to render.</param>
        ///// <param name="location">Location of the upper left corner of the label.</param>
        ///// <param name="offset">Offset of label in view coordinates from the <paramref name="location"/>.</param>
        ///// <param name="font">Font used for rendering.</param>
        ///// <param name="foreColor">Font color.</param>
        ///// <param name="backColor">Background color.</param>
        ///// <param name="halo">Halo to be drawn around the label text.</param>
        ///// <param name="rotation">Text rotation in degrees.</param>
        //public void DrawLabel(String text, Point2D location, Point2D offset, StyleFont font,
        //    StyleColor foreColor, StyleBrush backColor, StylePen halo, Single rotation)
        //{
        //    DrawLabel(text, location, offset, font, foreColor, backColor, halo, rotation);
        //}

        //private Label CreateLabel(Geometry feature, String text, Single rotation, LabelStyle style)
        //{
        //    LabelLayer layer = null;
        //    Size2D size = MeasureString(text, style.Font);

        //    Point2D position = ViewTransformer.WorldToView(feature.GetBoundingBox().GetCentroid());
        //    Double x = position.X - size.Width * (Int16)style.HorizontalAlignment * 0.5f;
        //    Double y = position.Y - size.Height * (Int16)style.VerticalAlignment * 0.5f;

        //    position = new Point2D(x, y);

        //    if (position.X - size.Width > ViewTransformer.ViewSize.Width || position.X + size.Width < 0 ||
        //        position.Y - size.Height > ViewTransformer.ViewSize.Height || position.Y + size.Height < 0)
        //    {
        //        return null;
        //    }

        //    Label label;

        //    if (!style.CollisionDetection)
        //    {
        //        label = new Label(text, position, rotation, layer.Priority, null, style);
        //    }
        //    else
        //    {
        //        //Collision detection is enabled so we need to measure the size of the String
        //        label = new Label(text, position, rotation, layer.Priority,
        //            new Rectangle2D(position.X - size.Width * 0.5f - style.CollisionBuffer.Width, position.Y + size.Height * 0.5f + style.CollisionBuffer.Height,
        //            size.Width + 2f * style.CollisionBuffer.Width, size.Height + style.CollisionBuffer.Height * 2f), style);
        //    }

        //    if (feature is LineString)
        //    {
        //        LineString line = feature as LineString;

        //        if (line.Length / ViewTransformer.PixelSize > size.Width) //Only label feature if it is Int64 enough
        //            CalculateLabelOnLineString(line, ref label);
        //        else
        //            return null;
        //    }

        //    return label;
        //}

        private void calculateLabelOnLineString(ILineString line, ref Label2D label)
        {
            Double dx, dy;
            Double tmpx, tmpy;
            Double angle = 0.0;



            // first find the middle segment of the line
            Int32 midPoint = (line.Coordinates.Count - 1) / 2;

            if (line.Coordinates.Count > 2)
            {
                dx = line.Coordinates[midPoint + 1, Ordinates.X]
                     - line.Coordinates[midPoint, Ordinates.X];

                dy = line.Coordinates[midPoint + 1, Ordinates.Y]
                     - line.Coordinates[midPoint, Ordinates.Y];
            }
            else
            {
                midPoint = 0;
                dx       = line.Coordinates[1, Ordinates.X] - line.Coordinates[0, Ordinates.X];
                dy       = line.Coordinates[1, Ordinates.Y] - line.Coordinates[0, Ordinates.Y];
            }

            if (dy == 0)
            {
                label.Rotation = 0;
            }
            else if (dx == 0)
            {
                label.Rotation = 90;
            }
            else
            {
                // calculate angle of line
                angle          = -Math.Atan(dy / dx) + Math.PI * 0.5;
                angle         *= (180d / Math.PI);   // convert radians to degrees
                label.Rotation = (Single)angle - 90; // -90 text orientation
            }

            tmpx = line.Coordinates[midPoint, Ordinates.X] + (dx * 0.5);
            tmpy = line.Coordinates[midPoint, Ordinates.Y] + (dy * 0.5);

            label.Location = new Point2D(tmpx, tmpy);
            return;

#warning figure out label positioning
            throw new NotImplementedException();
            //label.LabelPoint = map.WorldToImage(new SharpMap.Geometries.Point(tmpx, tmpy));
        }
Beispiel #4
0
        private static Matrix2D createTransformFromLabel(Label2D label)
        {
            Matrix2D transform = new Matrix2D();

            if (label.Rotation != 0)
            {
                transform.Rotate(label.Rotation);
            }

            if (!label.Offset.IsEmpty)
            {
                transform.Translate(label.Offset);
            }

            return(transform);
        }
Beispiel #5
0
 /// <summary>
 /// Tests if two label boxes intersects
 /// </summary>
 /// <param name="other"></param>
 /// <returns></returns>
 public Int32 CompareTo(Label2D other)
 {
     if (this == other || (_collisionBuffer == Size2D.Empty && other.CollisionBuffer == Size2D.Empty))
     {
         return(0);
     }
     else if (_collisionBuffer == Size2D.Empty)
     {
         return(-1);
     }
     else if (other.CollisionBuffer == Size2D.Empty)
     {
         return(1);
     }
     else
     {
         return(_collisionBuffer.CompareTo(other.CollisionBuffer));
     }
 }
        private Boolean AdvancedCollisionTest(Label2D newLabel, Int32 depth)
        {
            //newLabel.Style.Halo = new StylePen(newLabel.Style.Foreground, 1);

            Size2D newSize = TextRenderer.MeasureString(newLabel.Text, newLabel.Font);

            newSize = new Size2D(newSize.Width + 2 * newLabel.CollisionBuffer.Width, newSize.Height + 2 * newLabel.CollisionBuffer.Height);
            Rectangle2D newRect = new Rectangle2D(new Point2D(newLabel.Location.X - newLabel.CollisionBuffer.Width, newLabel.Location.Y - newLabel.CollisionBuffer.Height), newSize);

            foreach (Label2D label in labelList)
            {
                Size2D size = TextRenderer.MeasureString(label.Text, label.Font);
                size = new Size2D(size.Width + 2 * label.CollisionBuffer.Width, size.Height + 2 * label.CollisionBuffer.Height);
                Rectangle2D rect = new Rectangle2D(new Point2D(label.Location.X - newLabel.CollisionBuffer.Width, label.Location.Y - label.CollisionBuffer.Height), size);

                if (newRect.Intersects(rect))
                {
                    if (label.Text == newLabel.Text)
                    {
                        return(true);
                    }

                    if (depth == 5)
                    {
                        /* *
                         * StyleFont font = newLabel.Font;
                         * newLabel.Style.Foreground = new SolidStyleBrush(StyleColor.Yellow);
                         * newLabel.Style.Halo = new StylePen(newLabel.Style.Foreground, 1);
                         * newLabel.Font = new StyleFont(font.FontFamily, new Size2D(font.Size.Width / 3.0, font.Size.Height / 3.0), font.Style);
                         * newLabel.Text = newLabel.Text + ":" + label.Text;
                         * labelList.Add(newLabel);
                         * /*/

                        // give up on this label after 5 tries at moving it
                        return(true);

                        /* */
                    }
                    else
                    {
                        if (newRect.Location.Y > (rect.Location.Y + rect.Height / 2.0))
                        {
                            newLabel.Location = new Point2D(newLabel.Location.X, rect.Location.Y + rect.Height + 3);
                        }
                        else
                        {
                            newLabel.Location = new Point2D(newLabel.Location.X, rect.Location.Y - newRect.Height - 3);
                        }
                        //newLabel.Style.Foreground = new SolidStyleBrush(StyleColor.Blue);
                        ////StyleFont font = newLabel.Font;
                        ////newLabel.Font = new StyleFont(font.FontFamily, new Size2D(font.Size.Width / depth, font.Size.Height / depth), font.Style);
                        //newLabel.Style.Halo = new StylePen(newLabel.Style.Foreground, 1);
                        return(AdvancedCollisionTest(newLabel, depth + 1));
                    }
                }
                //else
                //{
                //    newLabel.Style.Halo = new StylePen(new SolidStyleBrush(StyleColor.Purple), 1);
                //}
            }

            labelList.Add(newLabel);

            return(false);
        }
Beispiel #7
0
        public Label2D Clone()
        {
            Label2D clone = new Label2D(Text, Location, Rotation, Priority, CollisionBuffer, Style);

            return(clone);
        }
Beispiel #8
0
 /// <summary>
 /// Checks if two labels intersect
 /// </summary>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <returns></returns>
 public Int32 Compare(Label2D x, Label2D y)
 {
     return(x.CompareTo(y));
 }
        public virtual IEnumerable <TRenderObject> RenderLabel(Label2D label)
        {
            Size2D textSize = TextRenderer.MeasureString(label.Text, label.Font);
            //Size2D size = new Size2D(textSize.Width + 2*label.CollisionBuffer.Width, textSize.Height + 2*label.CollisionBuffer.Height);
            //Rectangle2D layoutRectangle =
            //    new Rectangle2D(new Point2D(label.Location.X-label.CollisionBuffer.Width, label.Location.Y-label.CollisionBuffer.Height), size);

            LabelStyle style = label.Style;
            Int32      x = 0, y = 0;

            if (style.HorizontalAlignment != HorizontalAlignment.Right || style.VerticalAlignment != VerticalAlignment.Bottom)
            {
                switch (style.HorizontalAlignment)
                {
                case HorizontalAlignment.Center:
                    x -= (Int32)(textSize.Width / 2.0f);
                    break;

                case HorizontalAlignment.Left:
                    x -= (Int32)textSize.Width;
                    break;

                default:
                    break;
                }

                switch (style.VerticalAlignment)
                {
                case VerticalAlignment.Middle:
                    y += (Int32)(textSize.Height / 2.0f);
                    break;

                case VerticalAlignment.Top:
                    y += (Int32)textSize.Height;
                    break;

                default:
                    break;
                }
            }

            Point2D     location        = RenderTransform.TransformVector(label.Location.X, label.Location.Y).Add(new Point2D(x, y));
            Rectangle2D layoutRectangle = new Rectangle2D(location, textSize);

            if (label.Style.Halo != null)
            {
                StylePen   halo       = label.Style.Halo;
                StyleBrush background = label.Style.Background;

                IEnumerable <TRenderObject> haloPath = VectorRenderer.RenderPaths(
                    generateHaloPath(layoutRectangle), background, background, background,
                    halo, halo, halo, RenderState.Normal);

                foreach (TRenderObject ro in haloPath)
                {
                    yield return(ro);
                }
            }

            IEnumerable <TRenderObject> renderedText = TextRenderer.RenderText(
                label.Text, label.Font, layoutRectangle, label.FlowPath, label.Style.Foreground, label.Transform);

            foreach (TRenderObject ro in renderedText)
            {
                yield return(ro);
            }
        }
        protected override IEnumerable <TRenderObject> DoRenderFeature(IFeatureDataRecord inFeature,
                                                                       LabelStyle style,
                                                                       RenderState renderState,
                                                                       ILayer inLayer)
        {
            FeatureDataRow feature = inFeature as FeatureDataRow;
            LabelLayer     layer   = inLayer as LabelLayer;

            if (style == null)
            {
                throw new ArgumentNullException("style", "LabelStyle is a required argument " +
                                                "to properly render the label");
            }

            Label2D newLabel = null;

            LabelLayer.LabelTextFormatter formatter = null;
            LabelCollisionDetection2D     collisionDetector;

            if (layer != null)
            {
                if (!layer.RenderCache.TryGetValue(feature.GetOid(), out newLabel))
                {
                    formatter = layer.TextFormatter;
                }

                collisionDetector = layer.CollisionDetector;
                collisionDetector.TextRenderer = TextRenderer;
            }
            else
            {
                if (!textFormatters.TryGetValue(style, out formatter))
                {
                    // setup formatter based on style.LabelFormatExpression
                    formatter = delegate(FeatureDataRow row)
                    {
                        return(row.Evaluate(style.LabelExpression));
                    };

                    textFormatters.Add(style, formatter);
                }

                if (!collisionDetectors.TryGetValue(style, out collisionDetector))
                {
                    collisionDetector = new LabelCollisionDetection2D();
                    collisionDetector.TextRenderer = TextRenderer;
                    collisionDetectors.Add(style, collisionDetector);
                }
            }

            if (newLabel == null)
            {
                String labelText = formatter.Invoke(feature);
                if (feature.Geometry is ILineString)

                {
                    newLabel = new Label2D(labelText, new Point2D(), style);
                    calculateLabelOnLineString(feature.Geometry as ILineString, ref newLabel);
                }
                else
                {
                    ICoordinate p = feature.Geometry.Extents.Center;
                    Double      x = p[Ordinates.X], y = p[Ordinates.Y];


                    /* Moved to RenderLabel function
                     * if (style.HorizontalAlignment != HorizontalAlignment.Right || style.VerticalAlignment != VerticalAlignment.Bottom)
                     * {
                     * Size2D size = TextRenderer.MeasureString(labelText, style.Font);
                     * //Point2D pt = RenderTransform.TransformVector(Math.Ceiling(size.Width), Math.Ceiling(size.Height));
                     * size = new Size2D(size.Width / (Double)RenderTransform[0,0], size.Height / (Double)RenderTransform[1,1]);
                     * switch (style.HorizontalAlignment)
                     * {
                     *  case HorizontalAlignment.Center:
                     *      x -= (Int32)(size.Width / 2.0f);
                     *      break;
                     *  case HorizontalAlignment.Left:
                     *      x -= size.Width;
                     *      break;
                     *  default:
                     *      break;
                     * }
                     *
                     * switch (style.VerticalAlignment)
                     * {
                     *  case VerticalAlignment.Middle:
                     *      y += (Int32)(size.Height / 2.0f);
                     *      break;
                     *  case VerticalAlignment.Top:
                     *      y += size.Height;
                     *      break;
                     *  default:
                     *      break;
                     * }
                     * }
                     */

                    newLabel = new Label2D(labelText, new Point2D(x, y), style);
                }

                if (layer != null)
                {
                    layer.RenderCache.Add(feature.GetOid(), newLabel);
                }
            }

            // now find out if we even need to render this label...
            if (style.CollisionDetectionType != CollisionDetectionType.None)
            {
                if (style.CollisionDetectionType == CollisionDetectionType.Simple)
                {
                    if (collisionDetector.SimpleCollisionTest(newLabel))
                    {
                        // we are not going to render this label
                        if (layer != null)
                        {
                            layer.RenderCache.Remove(newLabel);
                        }

                        yield break;
                    }
                }
                else if (style.CollisionDetectionType == CollisionDetectionType.Advanced)
                {
                    if (collisionDetector.AdvancedCollisionTest(newLabel))
                    {
                        // we are not going to render this label
                        if (layer != null)
                        {
                            layer.RenderCache.Remove(newLabel);
                        }

                        yield break;
                    }
                }
            }

            foreach (TRenderObject ro in RenderLabel(newLabel))
            {
                yield return(ro);
            }
        }