private SharpMap.Rendering.Label CreateLabel(IGeometry feature, string text, float rotation, SharpMap.Styles.LabelStyle style, Map map, System.Drawing.Graphics g) { System.Drawing.SizeF size = g.MeasureString(text, style.Font); System.Drawing.PointF position = map.WorldToImage(feature.EnvelopeInternal.Centre); position.X = position.X - size.Width * (short)style.HorizontalAlignment * 0.5f; position.Y = position.Y - size.Height * (short)style.VerticalAlignment * 0.5f; if (position.X - size.Width > map.Size.Width || position.X + size.Width < 0 || position.Y - size.Height > map.Size.Height || position.Y + size.Height < 0) { return(null); } else { SharpMap.Rendering.Label lbl; if (!style.CollisionDetection) { lbl = new SharpMap.Rendering.Label(text, position, rotation, this.Priority, null, style); } else { //Collision detection is enabled so we need to measure the size of the string lbl = new SharpMap.Rendering.Label(text, position, rotation, this.Priority, new SharpMap.Rendering.LabelBox(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.GetType() == typeof(ILineString)) { ILineString line = feature as ILineString; if (line.Length / map.PixelSize > size.Width) //Only label feature if it is long enough { CalculateLabelOnLinestring(line, ref lbl, map); } else { return(null); } } return(lbl); } }
private void CalculateLabelOnLinestring(ILineString line, ref SharpMap.Rendering.Label label, Map map) { double dx, dy; double tmpx, tmpy; double angle = 0.0; // first find the middle segment of the line int midPoint = (line.Coordinates.Length - 1) / 2; if (line.Coordinates.Length > 2) { dx = line.Coordinates[midPoint + 1].X - line.Coordinates[midPoint].X; dy = line.Coordinates[midPoint + 1].Y - line.Coordinates[midPoint].Y; } else { midPoint = 0; dx = line.Coordinates[1].X - line.Coordinates[0].X; dy = line.Coordinates[1].Y - line.Coordinates[0].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 = (float)angle - 90; // -90 text orientation } tmpx = line.Coordinates[midPoint].X + (dx * 0.5); tmpy = line.Coordinates[midPoint].Y + (dy * 0.5); label.LabelPoint = map.WorldToImage(SharpMap.Converters.Geometries.GeometryFactory.CreateCoordinate(tmpx, tmpy)); }
private SharpMap.Rendering.Label CreateLabel(IGeometry feature,string text, float rotation, ILabelStyle style, IMap map, System.Drawing.Graphics g) { System.Drawing.SizeF size = g.MeasureString(text, style.Font); System.Drawing.PointF position = map.WorldToImage(feature.EnvelopeInternal.Centre); position.X = position.X - size.Width * (short)style.HorizontalAlignment * 0.5f; position.Y = position.Y - size.Height * (short)style.VerticalAlignment * 0.5f; if (position.X-size.Width > map.Size.Width || position.X+size.Width < 0 || position.Y-size.Height > map.Size.Height || position.Y+size.Height < 0) return null; else { SharpMap.Rendering.Label lbl; if (!style.CollisionDetection) lbl = new SharpMap.Rendering.Label(text, position, rotation, this.Priority, null, style); else { //Collision detection is enabled so we need to measure the size of the string lbl = new SharpMap.Rendering.Label(text, position, rotation, this.Priority, new SharpMap.Rendering.LabelBox(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.GetType() == typeof(ILineString)) { ILineString line = feature as ILineString; if (line.Length / map.PixelSize > size.Width) //Only label feature if it is long enough CalculateLabelOnLinestring(line, ref lbl, map); else return null; } return lbl; } }
public void RenderLayer(ILabelLayer layer, Map map, Graphics g) { if (layer.Style.Enabled && layer.Style.MaxVisible >= map.Zoom && layer.Style.MinVisible < map.Zoom) { if (layer.DataSource == null) { throw (new ApplicationException("DataSource property not set on layer '" + layer.LayerName + "'")); } g.TextRenderingHint = layer.TextRenderingHint; g.SmoothingMode = layer.SmoothingMode; SharpMap.Geometries.BoundingBox envelope = map.Envelope; //View to render if (layer.CoordinateTransformation != null) { envelope = GeometryTransform.TransformBox(envelope, layer.CoordinateTransformation.MathTransform.Inverse()); } FeatureDataSet ds = new FeatureDataSet(); layer.DataSource.Open(); layer.DataSource.ExecuteIntersectionQuery(envelope, ds); layer.DataSource.Close(); if (ds.Tables.Count == 0) { //base.Render(g, map); return; } FeatureDataTable features = (FeatureDataTable)ds.Tables[0]; //Initialize label collection List <Label> labels = new List <Label>(); LabelLayer.GetLabelMethod lblDelegate = layer.LabelStringDelegate; //List<System.Drawing.Rectangle> LabelBoxes; //Used for collision detection //Render labels for (int i = 0; i < features.Count; i++) { FeatureDataRow feature = features[i]; if (layer.CoordinateTransformation != null) { features[i].Geometry = GeometryTransform.TransformGeometry(features[i].Geometry, layer.CoordinateTransformation.MathTransform); } ILabelStyle style = null; if (layer.Theme != null) //If thematics is enabled, lets override the style { style = layer.Theme.GetStyle(feature); } else { style = layer.Style; } float rotation = 0; if (!String.IsNullOrEmpty(layer.RotationColumn)) { float.TryParse(feature[layer.RotationColumn].ToString(), NumberStyles.Any, Map.numberFormat_EnUS, out rotation); } string text; if (lblDelegate != null) { text = lblDelegate(feature); } else { text = feature[layer.LabelColumn].ToString(); } if (text != null && text != String.Empty) { if (feature.Geometry is GeometryCollection) { if (layer.MultipartGeometryBehaviour == SharpMap.Layers.LabelLayer.MultipartGeometryBehaviourEnum.All) { foreach (SharpMap.Geometries.Geometry geom in (feature.Geometry as GeometryCollection)) { SharpMap.Rendering.Label lbl = CreateLabel(layer, geom, text, rotation, style, map, g); if (lbl != null) { labels.Add(lbl); } } } else if (layer.MultipartGeometryBehaviour == SharpMap.Layers.LabelLayer.MultipartGeometryBehaviourEnum.CommonCenter) { Label lbl = CreateLabel(layer, feature.Geometry, text, rotation, style, map, g); if (lbl != null) { labels.Add(lbl); } } else if (layer.MultipartGeometryBehaviour == SharpMap.Layers.LabelLayer.MultipartGeometryBehaviourEnum.First) { if ((feature.Geometry as GeometryCollection).Collection.Count > 0) { SharpMap.Rendering.Label lbl = CreateLabel(layer, (feature.Geometry as GeometryCollection).Collection[0], text, rotation, style, map, g); if (lbl != null) { labels.Add(lbl); } } } else if (layer.MultipartGeometryBehaviour == SharpMap.Layers.LabelLayer.MultipartGeometryBehaviourEnum.Largest) { GeometryCollection coll = (feature.Geometry as GeometryCollection); if (coll.NumGeometries > 0) { double largestVal = 0; int idxOfLargest = 0; for (int j = 0; j < coll.NumGeometries; j++) { SharpMap.Geometries.Geometry geom = coll.Geometry(j); if (geom is Geometries.LineString && ((Geometries.LineString)geom).Length > largestVal) { largestVal = ((Geometries.LineString)geom).Length; idxOfLargest = j; } if (geom is Geometries.MultiLineString && ((Geometries.MultiLineString)geom).Length > largestVal) { largestVal = ((Geometries.LineString)geom).Length; idxOfLargest = j; } if (geom is Geometries.Polygon && ((Geometries.Polygon)geom).Area > largestVal) { largestVal = ((Geometries.Polygon)geom).Area; idxOfLargest = j; } if (geom is Geometries.MultiPolygon && ((Geometries.MultiPolygon)geom).Area > largestVal) { largestVal = ((Geometries.MultiPolygon)geom).Area; idxOfLargest = j; } } SharpMap.Rendering.Label lbl = CreateLabel(layer, coll.Geometry(idxOfLargest), text, rotation, style, map, g); if (lbl != null) { labels.Add(lbl); } } } } else { SharpMap.Rendering.Label lbl = CreateLabel(layer, feature.Geometry, text, rotation, style, map, g); if (lbl != null) { labels.Add(lbl); } } } } if (labels.Count > 0) //We have labels to render... { if (layer.Style.CollisionDetection && layer.LabelFilter != null) { layer.LabelFilter(labels); } for (int i = 0; i < labels.Count; i++) { VectorRenderer.DrawLabel(g, labels[i].LabelPoint, labels[i].Style.Offset, labels[i].Style.Font, labels[i].Style.ForeColor, labels[i].Style.BackColor, layer.Style.Halo, labels[i].Rotation, labels[i].Text, map); } } labels = null; } //base.Render(g, map); }
/// <summary> /// Renders the layer /// </summary> /// <param name="g">Graphics object reference</param> /// <param name="map">Map which is rendered</param> public override void OnRender(System.Drawing.Graphics g, Map map) { if (Style.Enabled && Style.MaxVisible >= map.Zoom && Style.MinVisible < map.Zoom) { if (DataSource == null) { throw (new ApplicationException("DataSource property not set on layer '" + Name + "'")); } g.TextRenderingHint = this.TextRenderingHint; g.SmoothingMode = this.SmoothingMode; IEnvelope envelope = map.Envelope; //View to render if (CoordinateTransformation != null) { envelope = CoordinateSystems.Transformations.GeometryTransform.TransformBox(envelope, this.CoordinateTransformation.MathTransform.Inverse()); } IList features = DataSource.GetFeatures(envelope); if (features.Count == 0) { return; } //Initialize label collection var labels = new List <Rendering.Label>(); //List<System.Drawing.Rectangle> LabelBoxes; //Used for collision detection //Render labels for (int i = 0; i < features.Count; i++) { IFeature feature = (IFeature)features[i]; if (this.CoordinateTransformation != null) { ((IFeature)features[i]).Geometry = SharpMap.CoordinateSystems.Transformations.GeometryTransform.TransformGeometry(((IFeature)features[i]).Geometry, this.CoordinateTransformation.MathTransform); } SharpMap.Styles.LabelStyle style = null; if (this.Theme != null) //If thematics is enabled, lets override the style { style = this.Theme.GetStyle(feature) as SharpMap.Styles.LabelStyle; } else { style = this.Style; } float rotation = 0; if (!String.IsNullOrEmpty(this.RotationColumn)) { rotation = FeatureAttributeAccessorHelper.GetAttributeValue <float>(feature, RotationColumn, 0f); } string text = GetText(feature); if (text != null && text != String.Empty) { if (feature.Geometry is IGeometryCollection) { if (this.MultipartGeometryBehaviour == MultipartGeometryBehaviourEnum.All) { foreach (IGeometry geom in (feature.Geometry as IGeometryCollection)) { SharpMap.Rendering.Label lbl = CreateLabel(geom, text, rotation, style, map, g); if (lbl != null) { labels.Add(lbl); } } } else if (this.MultipartGeometryBehaviour == MultipartGeometryBehaviourEnum.CommonCenter) { SharpMap.Rendering.Label lbl = CreateLabel(feature.Geometry, text, rotation, style, map, g); if (lbl != null) { labels.Add(lbl); } } else if (this.MultipartGeometryBehaviour == MultipartGeometryBehaviourEnum.First) { if ((feature.Geometry as IGeometryCollection).Geometries.Length > 0) { SharpMap.Rendering.Label lbl = CreateLabel((feature.Geometry as IGeometryCollection).Geometries[0], text, rotation, style, map, g); if (lbl != null) { labels.Add(lbl); } } } else if (this.MultipartGeometryBehaviour == MultipartGeometryBehaviourEnum.Largest) { IGeometryCollection coll = (feature.Geometry as IGeometryCollection); if (coll.NumGeometries > 0) { double largestVal = 0; int idxOfLargest = 0; for (int j = 0; j < coll.NumGeometries; j++) { IGeometry geom = coll.Geometries[j]; if (geom is ILineString && ((ILineString)geom).Length > largestVal) { largestVal = ((ILineString)geom).Length; idxOfLargest = j; } if (geom is IMultiLineString && ((IMultiLineString)geom).Length > largestVal) { largestVal = ((ILineString)geom).Length; idxOfLargest = j; } if (geom is IPolygon && ((IPolygon)geom).Area > largestVal) { largestVal = ((IPolygon)geom).Area; idxOfLargest = j; } if (geom is IMultiPolygon && ((IMultiPolygon)geom).Area > largestVal) { largestVal = ((IMultiPolygon)geom).Area; idxOfLargest = j; } } SharpMap.Rendering.Label lbl = CreateLabel(coll.Geometries[idxOfLargest], text, rotation, style, map, g); if (lbl != null) { labels.Add(lbl); } } } } else { SharpMap.Rendering.Label lbl = CreateLabel(feature.Geometry, text, rotation, style, map, g); if (lbl != null) { labels.Add(lbl); } } } } if (labels.Count > 0) //We have labels to render... { if (this.Style.CollisionDetection && this.labelFilter != null) { this.labelFilter(labels); } for (int i = 0; i < labels.Count; i++) { SharpMap.Rendering.VectorRenderingHelper.DrawLabel(g, labels[i].LabelPoint, labels[i].Style.Offset, labels[i].Style.Font, labels[i].Style.ForeColor, labels[i].Style.BackColor, Style.Halo, labels[i].Rotation, labels[i].Text, map); } } labels = null; } }