/// <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)); }
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); }
/// <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); }
public Label2D Clone() { Label2D clone = new Label2D(Text, Location, Rotation, Priority, CollisionBuffer, Style); return(clone); }
/// <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); } }