/// <summary> /// Renders the layer /// </summary> /// <param name="g">Graphics object reference</param> /// <param name="map">Map which is rendered</param> public override void Render(Graphics g, MapViewport map) { if (DataSource == null) { throw (new ApplicationException("DataSource property not set on layer '" + LayerName + "'")); } var layerEnvelope = ToSource(map.Envelope); //View to render List <BaseLabel> labels = null; using (var ds = new FeatureDataSet()) { DataSource.Open(); DataSource.ExecuteIntersectionQuery(layerEnvelope, ds); DataSource.Close(); if (ds.Tables.Count > 0) { g.TextRenderingHint = TextRenderingHint; g.SmoothingMode = SmoothingMode; labels = CreateLabelDefinitions(g, map, ds.Tables[0]); } } if (labels == null || labels.Count == 0) { // Obsolete (and will cause infinite loop) //base.Render(g, map); return; } if (Style.CollisionDetection) { _labelFilter?.Invoke(labels); } var combinedArea = RectangleF.Empty; for (int i = 0; i < labels.Count; i++) { var baseLabel = labels[i]; if (!baseLabel.Show) { continue; } var font = baseLabel.Style.GetFontForGraphics(g); if (labels[i] is Label) { var label = baseLabel as Label; var canvasArea = VectorRenderer.DrawLabelEx( g, label.Location, label.Style.Offset, font, label.Style.ForeColor, label.Style.BackColor, label.Style.Halo, label.Rotation, label.Text, map, label.Style.HorizontalAlignment, label.LabelPoint); combinedArea = canvasArea.ExpandToInclude(combinedArea); } else if (labels[i] is PathLabel) { var pathLabel = labels[i] as PathLabel; var lblStyle = pathLabel.Style; var background = pathLabel.AffectedArea.ExteriorRing.TransformToImage(map); if (lblStyle.BackColor != null && lblStyle.BackColor != Brushes.Transparent) { using (var gp = new GraphicsPath()) { gp.AddPolygon(background); g.FillPath(lblStyle.BackColor, gp); } } g.DrawString(lblStyle.Halo, new SolidBrush(lblStyle.ForeColor), pathLabel.Text, font.FontFamily, (int)font.Style, font.Size, lblStyle.GetStringFormat(), lblStyle.IgnoreLength, pathLabel.Location, pathLabel.Box.Height); combinedArea = background.ToRectangleF().ExpandToInclude(combinedArea); } } CanvasArea = combinedArea; // Obsolete (and will cause infinite loop) //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 Render(Graphics g, IMapViewPort map) { if (DataSource == null) { throw (new ApplicationException("DataSource property not set on layer '" + LayerName + "'")); } g.TextRenderingHint = TextRenderingHint; g.SmoothingMode = SmoothingMode; var mapEnvelope = map.Envelope; var layerEnvelope = ToSource(mapEnvelope); //View to render var lineClipping = new CohenSutherlandLineClipping(mapEnvelope.MinX, mapEnvelope.MinY, mapEnvelope.MaxX, mapEnvelope.MaxY); var ds = _dataCache; if (ds == null || ds.Tables.Count == 0) { base.Render(g, map); return; } var features = ds.Tables[0]; //Initialize label collection var labels = new List <BaseLabel>(); //List<System.Drawing.Rectangle> LabelBoxes; //Used for collision detection //Render labels for (var i = 0; i < features.Count; i++) { var feature = features[i]; LabelStyle style; if (Theme != null) //If thematics is enabled, lets override the style { style = Theme.GetStyle(feature) as LabelStyle; } else { style = Style; } var rotationStyle = style?.Rotation ?? 0f; var rotationColumn = 0f; if (!string.IsNullOrEmpty(RotationColumn)) { float.TryParse(feature[RotationColumn].ToString(), NumberStyles.Any, Map.NumberFormatEnUs, out rotationColumn); } var rotation = rotationStyle + rotationColumn; var priority = Priority; if (_getPriorityMethod != null) { priority = _getPriorityMethod(feature); } else if (!string.IsNullOrEmpty(PriorityColumn)) { int.TryParse(feature[PriorityColumn].ToString(), NumberStyles.Any, Map.NumberFormatEnUs, out priority); } string text; text = _getLabelMethod != null?_getLabelMethod(feature) : feature[LabelColumn].ToString(); if (!string.IsNullOrEmpty(text)) { // for lineal geometries, try clipping to ensure proper labeling if (feature.Geometry is ILineal) { if (feature.Geometry is ILineString) { feature.Geometry = lineClipping.ClipLineString(feature.Geometry as ILineString); } else if (feature.Geometry is IMultiLineString) { feature.Geometry = lineClipping.ClipLineString(feature.Geometry as IMultiLineString); } } if (feature.Geometry is IGeometryCollection) { if (MultipartGeometryBehaviour == MultipartGeometryBehaviourEnum.All) { foreach (var geom in (feature.Geometry as IGeometryCollection)) { var lbl = CreateLabel(feature, geom, text, rotation, priority, style, map, g, _getLocationMethod); if (lbl != null) { labels.Add(lbl); } } } else if (MultipartGeometryBehaviour == MultipartGeometryBehaviourEnum.CommonCenter) { var lbl = CreateLabel(feature, feature.Geometry, text, rotation, priority, style, map, g, _getLocationMethod); if (lbl != null) { labels.Add(lbl); } } else if (MultipartGeometryBehaviour == MultipartGeometryBehaviourEnum.First) { if ((feature.Geometry as IGeometryCollection).NumGeometries > 0) { var lbl = CreateLabel(feature, (feature.Geometry as IGeometryCollection).GetGeometryN(0), text, rotation, style, map, g); if (lbl != null) { labels.Add(lbl); } } } else if (MultipartGeometryBehaviour == MultipartGeometryBehaviourEnum.Largest) { var coll = (feature.Geometry as IGeometryCollection); if (coll.NumGeometries > 0) { var largestVal = 0d; var idxOfLargest = 0; for (var j = 0; j < coll.NumGeometries; j++) { var geom = coll.GetGeometryN(j); if (geom is ILineString && ((ILineString)geom).Length > largestVal) { largestVal = ((ILineString)geom).Length; idxOfLargest = j; } if (geom is IMultiLineString && ((IMultiLineString)geom).Length > largestVal) { largestVal = ((IMultiLineString)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; } } var lbl = CreateLabel(feature, coll.GetGeometryN(idxOfLargest), text, rotation, priority, style, map, g, _getLocationMethod); if (lbl != null) { labels.Add(lbl); } } } } else { var lbl = CreateLabel(feature, feature.Geometry, text, rotation, priority, style, map, g, _getLocationMethod); if (lbl != null) { labels.Add(lbl); } } } } if (labels.Count > 0) //We have labels to render... { if (Style.CollisionDetection) { _labelFilter?.Invoke(labels); } for (var i = 0; i < labels.Count; i++) { // Don't show the label if not necessary if (!labels[i].Show) { continue; } if (labels[i] is Label) { var label = labels[i] as Label; if (label.Style.IsTextOnPath == false || label.TextOnPathLabel == null) { VectorRenderer.DrawLabel(g, label.Location, label.Style.Offset, label.Style.GetFontForGraphics(g), label.Style.ForeColor, label.Style.BackColor, label.Style.Halo, label.Rotation, label.Text, map, label.Style.HorizontalAlignment, label.LabelPoint); } else { if (label.Style.BackColor != null && label.Style.BackColor != System.Drawing.Brushes.Transparent) { //draw background if (label.TextOnPathLabel.RegionList.Count > 0) { g.FillRectangles(labels[i].Style.BackColor, labels[i].TextOnPathLabel.RegionList.ToArray()); //g.FillPolygon(labels[i].Style.BackColor, labels[i].TextOnPathLabel.PointsText.ToArray()); } } label.TextOnPathLabel.DrawTextOnPath(); } } else if (labels[i] is PathLabel) { var plbl = labels[i] as PathLabel; var lblStyle = plbl.Style; g.DrawString(lblStyle.Halo, new SolidBrush(lblStyle.ForeColor), plbl.Text, lblStyle.Font.FontFamily, (int)lblStyle.Font.Style, lblStyle.Font.Size, lblStyle.GetStringFormat(), lblStyle.IgnoreLength, plbl.Location); } } } base.Render(g, map); }