Index: src/Common/SharpMap/Layers/LabelLayer.cs =================================================================== diff -u -r8f6ae890fed8e8eae3a32f9c0498a10f82e0ddf9 -r5fc71a385897af92ccb092f2f969b5709afab85a --- src/Common/SharpMap/Layers/LabelLayer.cs (.../LabelLayer.cs) (revision 8f6ae890fed8e8eae3a32f9c0498a10f82e0ddf9) +++ src/Common/SharpMap/Layers/LabelLayer.cs (.../LabelLayer.cs) (revision 5fc71a385897af92ccb092f2f969b5709afab85a) @@ -18,6 +18,8 @@ using System; using System.Collections.Generic; using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; using System.Linq; using DelftTools.Utils.Aop; using GeoAPI.CoordinateSystems.Transformations; @@ -28,489 +30,526 @@ using SharpMap.Api.Delegates; using SharpMap.Api.Enums; using SharpMap.Api.Layers; +using SharpMap.Converters.Geometries; using SharpMap.CoordinateSystems.Transformations; using SharpMap.Rendering; using SharpMap.Styles; namespace SharpMap.Layers { - /// - /// Label layer class - /// TODO: Auto-configure LabelColumn etc to some default on DataSource change (?) - /// TODO: Change Map Rendering to check LabelLayer RenderRequired (more efficient: currently parent layer must be redrawn) - /// TODO: Remove classes that override this class only to get access to GetText: there's a delegate for that. - /// - /// - /// Creates a new label layer and sets the label text to the "Name" column in the FeatureDataTable of the datasource - /// - /// //Set up a label layer - /// SharpMap.Layers.LabelLayer layLabel = new SharpMap.Layers.LabelLayer("Country labels"); - /// layLabel.DataSource = layCountries.DataSource; - /// layLabel.Enabled = true; - /// layLabel.LabelColumn = "Name"; - /// layLabel.Style = new SharpMap.Styles.LabelStyle(); - /// layLabel.Style.CollisionDetection = true; - /// layLabel.Style.CollisionBuffer = new SizeF(20, 20); - /// layLabel.Style.ForeColor = Color.White; - /// layLabel.Style.Font = new Font(FontFamily.GenericSerif, 8); - /// layLabel.MaxVisible = 90; - /// layLabel.Style.HorizontalAlignment = SharpMap.Styles.LabelStyle.HorizontalAlignmentEnum.Center; - /// - /// + /// + /// Label layer class + /// TODO: Auto-configure LabelColumn etc to some default on DataSource change (?) + /// TODO: Change Map Rendering to check LabelLayer RenderRequired (more efficient: currently parent layer must be redrawn) + /// TODO: Remove classes that override this class only to get access to GetText: there's a delegate for that. + /// + /// + /// Creates a new label layer and sets the label text to the "Name" column in the FeatureDataTable of the datasource + /// + /// //Set up a label layer + /// SharpMap.Layers.LabelLayer layLabel = new SharpMap.Layers.LabelLayer("Country labels"); + /// layLabel.DataSource = layCountries.DataSource; + /// layLabel.Enabled = true; + /// layLabel.LabelColumn = "Name"; + /// layLabel.Style = new SharpMap.Styles.LabelStyle(); + /// layLabel.Style.CollisionDetection = true; + /// layLabel.Style.CollisionBuffer = new SizeF(20, 20); + /// layLabel.Style.ForeColor = Color.White; + /// layLabel.Style.Font = new Font(FontFamily.GenericSerif, 8); + /// layLabel.MaxVisible = 90; + /// layLabel.Style.HorizontalAlignment = SharpMap.Styles.LabelStyle.HorizontalAlignmentEnum.Center; + /// + /// [Entity(FireOnCollectionChange = false)] - public class LabelLayer : Layer, ILabelLayer - { - public LabelLayer(): this("") - { - } + public class LabelLayer : Layer, ILabelLayer + { + private MultipartGeometryBehaviourEnum multipartGeometryBehaviour; - /// - /// Creates a new instance of a LabelLayer - /// - public LabelLayer(string layername) - { - style = new SharpMap.Styles.LabelStyle(); - this.Name = layername; - this.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; - this.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; - multipartGeometryBehaviour = MultipartGeometryBehaviourEnum.All; - this.ShowInTreeView = false; - this.ShowInLegend = false; - this.Visible = false; - this.LabelFilter = LabelCollisionDetection.ThoroughCollisionDetection; - this.Style = new LabelStyle - { - Font = new Font("Arial", 12), - Halo = new Pen(Brushes.White, 1f), - CollisionDetection = true - }; - } + private LabelCollisionDetection.LabelFilterMethod labelFilter; - private MultipartGeometryBehaviourEnum multipartGeometryBehaviour; - /// - /// Gets or sets labelling behavior on multipart geometries - /// - /// Default value is - public virtual MultipartGeometryBehaviourEnum MultipartGeometryBehaviour - { - get { return multipartGeometryBehaviour; } - set { multipartGeometryBehaviour = value; } - } + private ILabelStyle style; - private SharpMap.Rendering.LabelCollisionDetection.LabelFilterMethod labelFilter; + private GetLabelMethod getLabelMethod; - /// - /// Filtermethod delegate for performing filtering - /// - /// - /// Default method is - /// - public virtual SharpMap.Rendering.LabelCollisionDetection.LabelFilterMethod LabelFilter - { - get { return labelFilter; } - set { labelFilter = value; } - } - + public LabelLayer() : this("") {} - private System.Drawing.Drawing2D.SmoothingMode smoothingMode; + /// + /// Creates a new instance of a LabelLayer + /// + public LabelLayer(string layername) + { + style = new LabelStyle(); + Name = layername; + SmoothingMode = SmoothingMode.AntiAlias; + TextRenderingHint = TextRenderingHint.AntiAlias; + multipartGeometryBehaviour = MultipartGeometryBehaviourEnum.All; + ShowInTreeView = false; + ShowInLegend = false; + Visible = false; + LabelFilter = LabelCollisionDetection.ThoroughCollisionDetection; + Style = new LabelStyle + { + Font = new Font("Arial", 12), + Halo = new Pen(Brushes.White, 1f), + CollisionDetection = true + }; + } - /// - /// Render whether smoothing (antialiasing) is applied to lines and curves and the edges of filled areas - /// - public virtual System.Drawing.Drawing2D.SmoothingMode SmoothingMode - { - get { return smoothingMode; } - set { smoothingMode = value; } - } + /// + /// Filtermethod delegate for performing filtering + /// + /// + /// Default method is + /// + public virtual LabelCollisionDetection.LabelFilterMethod LabelFilter + { + get + { + return labelFilter; + } + set + { + labelFilter = value; + } + } - private System.Drawing.Text.TextRenderingHint textRenderingHint; + /// + /// Gets or sets labelling behavior on multipart geometries + /// + /// Default value is + public virtual MultipartGeometryBehaviourEnum MultipartGeometryBehaviour + { + get + { + return multipartGeometryBehaviour; + } + set + { + multipartGeometryBehaviour = value; + } + } - /// - /// Specifies the quality of text rendering - /// - public virtual System.Drawing.Text.TextRenderingHint TextRenderingHint - { - get { return textRenderingHint; } - set { textRenderingHint = value; } - } + /// + /// Render whether smoothing (antialiasing) is applied to lines and curves and the edges of filled areas + /// + public virtual SmoothingMode SmoothingMode { get; set; } - private ILabelStyle style; + /// + /// Specifies the quality of text rendering + /// + public virtual TextRenderingHint TextRenderingHint { get; set; } - /// - /// Gets or sets the rendering style of the label layer. - /// + /// + /// Gets or sets the rendering style of the label layer. + /// public virtual ILabelStyle Style - { - get { return style; } - set { style = value; } - } + { + get + { + return style; + } + set + { + style = value; + } + } - private ITheme theme; + /// + /// Gets or sets thematic settings for the layer. Set to null to ignore thematics + /// + public virtual ITheme Theme { get; set; } - /// - /// Gets or sets thematic settings for the layer. Set to null to ignore thematics - /// - public virtual ITheme Theme - { - get { return theme; } - set { theme = value; } - } + /// + /// Data column or expression where label text is extracted from. + /// + /// + /// This property is overriden by the . + /// + public virtual string LabelColumn { get; set; } - private string labelColumn; - - /// - /// Data column or expression where label text is extracted from. - /// - /// - /// This property is overriden by the . - /// - public virtual string LabelColumn - { - get { return labelColumn; } - set { labelColumn = value; } - } - - private GetLabelMethod getLabelMethod; - - /// - /// Gets or sets the method for creating a custom label string based on a feature. - /// - /// - /// If this method is not null, it will override the value. - /// The label delegate must take a and return a string. - /// - /// Creating a label-text by combining attributes "ROADNAME" and "STATE" into one string, using - /// an anonymous delegate: - /// - /// myLabelLayer.LabelStringDelegate = delegate(SharpMap.Data.FeatureDataRow fdr) - /// { return fdr["ROADNAME"].ToString() + ", " + fdr["STATE"].ToString(); }; - /// - /// - /// + /// + /// Gets or sets the method for creating a custom label string based on a feature. + /// + /// + /// If this method is not null, it will override the value. + /// The label delegate must take a and return a string. + /// + /// Creating a label-text by combining attributes "ROADNAME" and "STATE" into one string, using + /// an anonymous delegate: + /// + /// myLabelLayer.LabelStringDelegate = delegate(SharpMap.Data.FeatureDataRow fdr) + /// { return fdr["ROADNAME"].ToString() + ", " + fdr["STATE"].ToString(); }; + /// + /// + /// public virtual GetLabelMethod LabelStringDelegate - { - get { return getLabelMethod; } - set { getLabelMethod = value; } - } - - private string rotationColumn; + { + get + { + return getLabelMethod; + } + set + { + getLabelMethod = value; + } + } - /// - /// Data column from where the label rotation is derived. - /// If this is empty, rotation will be zero, or aligned to a linestring. - /// Rotation are in degrees (positive = clockwise). - /// - public virtual string RotationColumn - { - get { return rotationColumn; } - set { rotationColumn = value; } - } - - private int priority; + /// + /// Data column from where the label rotation is derived. + /// If this is empty, rotation will be zero, or aligned to a linestring. + /// Rotation are in degrees (positive = clockwise). + /// + public virtual string RotationColumn { get; set; } - /// - /// A value indication the priority of the label in cases of label-collision detection - /// - public virtual int Priority - { - get { return priority; } - set { priority = value; } - } + /// + /// A value indication the priority of the label in cases of label-collision detection + /// + public virtual int Priority { get; set; } [NoNotifyPropertyChange] public override IFeatureProvider DataSource { - get { return base.DataSource ?? ParentDataSource; } //either custom datasource (different from parent, otherwise parent datasource) - set { base.DataSource = value; } + get + { + return base.DataSource ?? ParentDataSource; + } //either custom datasource (different from parent, otherwise parent datasource) + set + { + base.DataSource = value; + } } [NoNotifyPropertyChange] public override ICoordinateTransformation CoordinateTransformation { - get { return base.DataSource == null ? ParentCoordinateTransformation : base.CoordinateTransformation; } - set { base.CoordinateTransformation = value; } + get + { + return base.DataSource == null ? ParentCoordinateTransformation : base.CoordinateTransformation; + } + set + { + base.CoordinateTransformation = value; + } } - private IFeatureProvider ParentDataSource + /// + /// Gets the boundingbox of the entire layer + /// + public override IEnvelope Envelope { - get { return Parent != null ? Parent.DataSource : null; } + get + { + if (DataSource == null) + { + return null; + } + + if (CoordinateTransformation != null) + { + throw new NotImplementedException(); + } + + return DataSource.GetExtents(); + } } - private ICoordinateTransformation ParentCoordinateTransformation - { - get { return Parent != null ? Parent.CoordinateTransformation : null; } - } + [Aggregation] + public virtual ILayer Parent { get; set; } - /// - /// Renders the layer - /// - /// Graphics object reference - /// Map which is rendered - public override void OnRender(System.Drawing.Graphics g, IMap 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 = TextRenderingHint; + /// + /// Renders the layer + /// + /// Graphics object reference + /// Map which is rendered + public override void OnRender(Graphics g, IMap 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 = TextRenderingHint; g.SmoothingMode = SmoothingMode; - var features = Parent.GetFeatures(map.Envelope); + var features = Parent.GetFeatures(map.Envelope); - if (!features.Any()) - { - return; - } + if (!features.Any()) + { + return; + } - //Initialize label collection - var labels = new List(); - - //List LabelBoxes; //Used for collision detection - //Render labels + //Initialize label collection + var labels = new List