public IDisplayCharacterRanges MeasureCharacterWidth(IDisplay display) { if (_measureTextWidth != null) { return(_measureTextWidth); } var format = StringFormatFromAlignment(_align); IDisplayCharacterRanges ranges = display.Canvas.DisplayCharacterRanges(_font, format, _text); return(ranges); }
public List <IAnnotationPolygonCollision> AnnotationPolygon(IDisplay display, IGeometry geometry, TextSymbolAlignment symbolAlignment) { if (_font == null || _text == null || display.Canvas == null) { return(null); } List <IAnnotationPolygonCollision> polygons = new List <IAnnotationPolygonCollision>(); if (geometry is IPoint) { #region IPoint double x = ((IPoint)geometry).X; double y = ((IPoint)geometry).Y; display.World2Image(ref x, ref y); var annotationPolygon = AnnotationPolygon(display, (float)x, (float)y, symbolAlignment); annotationPolygon.Rotate((float)x, (float)y, Angle); polygons.Add(annotationPolygon); #endregion } else if (geometry is IMultiPoint) { #region IMultipoint IMultiPoint pColl = (IMultiPoint)geometry; for (int i = 0; i < pColl.PointCount; i++) { double x = pColl[i].X; double y = pColl[i].Y; display.World2Image(ref x, ref y); var annotationPolygon = AnnotationPolygon(display, (float)x, (float)y, symbolAlignment); annotationPolygon.Rotate((float)x, (float)y, Angle); polygons.Add(annotationPolygon); } #endregion } else if (geometry is IDisplayPath) { if (String.IsNullOrEmpty(_text)) { return(null); } IDisplayPath path = (IDisplayPath)geometry; #region Text On Path var format = StringFormatFromAlignment(_align); IDisplayCharacterRanges ranges = this.MeasureCharacterWidth(display); float sizeW = ranges.Width; float stat0 = path.Chainage, stat1 = stat0 + sizeW, stat = stat0; if (stat0 < 0) { return(null); } #region Richtung des Textes CanvasPointF?p1_ = path.PointAt(stat0); //SpatialAlgorithms.Algorithm.DisplayPathPoint(path, stat0); CanvasPointF?p2_ = path.PointAt(stat1); //SpatialAlgorithms.Algorithm.DisplayPathPoint(path, stat1); if (!p1_.HasValue || !p2_.HasValue) { return(null); } if (p1_.Value.X > p2_.Value.X) { #region Swap Path Direction path.ChangeDirection(); stat = stat0 = path.Length - stat1; stat1 = stat0 + sizeW; #endregion } #endregion AnnotationPolygonCollection charPolygons = new AnnotationPolygonCollection(); float x, y, angle; for (int i = 0; i < _text.Length; i++) { CanvasRectangleF cSize = ranges[i]; int counter = 0; while (true) { CanvasPointF?p1 = path.PointAt(stat); //SpatialAlgorithms.Algorithm.DisplayPathPoint(path, stat); CanvasPointF?p2 = path.PointAt(stat + cSize.Width); if (!p1.HasValue || !p2.HasValue) { return(null); } angle = (float)(Math.Atan2(p2.Value.Y - p1.Value.Y, p2.Value.X - p1.Value.X) * 180.0 / Math.PI); //float ccc = 0f; //angle = 0f; //for (float xxx = 0f; xxx <= cSize.Width; xxx += cSize.Width / 10f, ccc += 1f) //{ // p2 = path.PointAt(stat + xxx/*cSize.Width*/); //SpatialAlgorithms.Algorithm.DisplayPathPoint(path, stat + cSize.Width); // if (p1 == null || p2 == null) // return null; // angle += (float)(Math.Atan2(((PointF)p2).Y - ((PointF)p1).Y, ((PointF)p2).X - ((PointF)p1).X) * 180.0 / Math.PI); //} //angle /= ccc; x = p1.Value.X; y = p1.Value.Y; AnnotationPolygon polygon = null; switch (format.LineAlignment) { case StringAlignment.Near: polygon = new Symbology.AnnotationPolygon((float)x + .1f * cSize.Width, (float)y + .2f * cSize.Height, .8f * cSize.Width, .6f * cSize.Height); break; case StringAlignment.Far: polygon = new Symbology.AnnotationPolygon((float)x + .1f * cSize.Width, (float)y - .8f * cSize.Height, .8f * cSize.Width, .6f * cSize.Height); break; default: polygon = new Symbology.AnnotationPolygon((float)x + .1f * cSize.Width, (float)y - .6f * cSize.Height / 2f, .8f * cSize.Width, .6f * cSize.Height); break; } polygon.Rotate((float)x, (float)y, Angle + angle); if (charPolygons.CheckCollision(polygon)) { stat += cSize.Width / 10.0f; counter++; if (counter > 7) { return(null); } continue; } charPolygons.Add(polygon); //using (System.Drawing.Drawing2D.GraphicsPath grpath = new System.Drawing.Drawing2D.GraphicsPath()) //{ // grpath.StartFigure(); // grpath.AddLine(polygon[0], polygon[1]); // grpath.AddLine(polygon[1], polygon[2]); // grpath.AddLine(polygon[2], polygon[3]); // grpath.CloseFigure(); // display.GraphicsContext.FillPath(Brushes.Aqua, grpath); //} break; } stat += cSize.Width;// +_font.Height * 0.1f; } if (charPolygons.Count > 0) { #region Glättung //for (int i = 1; i < charPolygons.Count - 1; i++) //{ // double angle0 = ((AnnotationPolygon)charPolygons[i - 1]).Angle; // double angle2 = ((AnnotationPolygon)charPolygons[i + 1]).Angle; // ((AnnotationPolygon)charPolygons[i]).Angle = (angle0 + angle2) * 0.5; // float x0 = ((AnnotationPolygon)charPolygons[i - 1]).X1; // float y0 = ((AnnotationPolygon)charPolygons[i - 1]).Y1; // float x2 = ((AnnotationPolygon)charPolygons[i + 1]).X1; // float y2 = ((AnnotationPolygon)charPolygons[i + 1]).Y1; // ((AnnotationPolygon)charPolygons[i]).X1 = (x0 + x2) * 0.5f; // ((AnnotationPolygon)charPolygons[i]).Y1 = (y0 + y2) * 0.5f; //} #endregion polygons.Add(charPolygons); path.AnnotationPolygonCollision = charPolygons; } #endregion } else if (geometry is IPolyline) { IPolyline pLine = (IPolyline)geometry; for (int iPath = 0; iPath < pLine.PathCount; iPath++) { IPath path = pLine[iPath]; if (path.PointCount == 0) { continue; } #region Simple Method IPoint p1 = path[0], p2; for (int iPoint = 1; iPoint < path.PointCount; iPoint++) { p2 = path[iPoint]; double angle = -Math.Atan2(p2.Y - p1.Y, p2.X - p1.X) * 180.0 / Math.PI; if (display.DisplayTransformation.UseTransformation) { angle -= display.DisplayTransformation.DisplayRotation; } if (angle < 0) { angle += 360; } if (angle > 90 && angle < 270) { angle -= 180; } var format = StringFormatFromAlignment(_align); double x, y; if (format.Alignment == StringAlignment.Center) { x = p1.X * 0.5 + p2.X * 0.5; y = p1.Y * 0.5 + p2.Y * 0.5; } else if (format.Alignment == StringAlignment.Far) { x = p2.X; y = p2.Y; } else { x = p1.X; y = p1.Y; } display.World2Image(ref x, ref y); var annotationPolygon = AnnotationPolygon(display, (float)x, (float)y, symbolAlignment); annotationPolygon.Rotate((float)x, (float)y, Angle); polygons.Add(annotationPolygon); p1 = p2; } #endregion } } return(polygons.Count > 0 ? polygons : null); }
public void Draw(IDisplay disp, IFeature feature) { if (!(_symbol is ISymbol)) { return; } string expr = _expression; foreach (FieldValue fv in feature.Fields) { if (fv.Name == _fieldname && !_useExpression) { _symbol.Text = fv.Value.ToString(); } if (fv.Name == _symbolRotation.RotationFieldName) { try { _symbol.Rotation = (float)_symbolRotation.Convert2DEGAritmetic(Convert.ToDouble(fv.Value)); } catch { } } if (_useExpression) { expr = expr.Replace("[" + fv.Name + "]", fv.Value.ToString()); } } if (_useExpression) { _symbol.Text = expr; } if (String.IsNullOrEmpty(_symbol.Text)) { return; } if (_howManyLabels == howManyLabels.one_per_name) { if (_labelStrings.Contains(_symbol.Text.Trim())) { return; } } if (feature.Shape is IPoint) { if (disp.LabelEngine.TryAppend(disp, _symbol, feature.Shape, _labelPriority != labelPriority.always) == LabelAppendResult.Succeeded) { if (_howManyLabels == howManyLabels.one_per_name) { _labelStrings.Add(_symbol.Text.Trim()); } } } else if (feature.Shape is IMultiPoint) { var multiPoint = (IMultiPoint)feature.Shape; for (int i = 0, i_to = multiPoint.PointCount; i < i_to; i++) { if (multiPoint[i] == null) { continue; } if (disp.LabelEngine.TryAppend(disp, _symbol, multiPoint[i], _labelPriority != labelPriority.always) == LabelAppendResult.Succeeded) { if (_howManyLabels == howManyLabels.one_per_name) { _labelStrings.Add(_symbol.Text.Trim()); } if (_howManyLabels == howManyLabels.one_per_part) { break; } } } } else if (feature.Shape is IPolyline) { IPoint point1 = null, point2 = null; double maxLenght = 0; IEnvelope dispEnv = _clipEnvelope; //disp.Envelope; //if (disp.GeometricTransformer != null) //{ // object e = disp.GeometricTransformer.InvTransform2D(disp.Envelope); // if (e is IGeometry) dispEnv = ((IGeometry)e).Envelope; //} IPolyline pLine = (IPolyline)gView.Framework.SpatialAlgorithms.Clip.PerformClip(dispEnv, feature.Shape); if (pLine == null) { return; } if (_lineLabelling == CartographicLineLabeling.CurvedText) { #region Text On Path IDisplayCharacterRanges ranges = _symbol.MeasureCharacterWidth(disp); if (ranges == null) { return; } float textWidth = ranges.Width; for (int iPath = 0; iPath < pLine.PathCount; iPath++) { IPath path = pLine[iPath]; if (path == null) { continue; } IPointCollection pathPoints = path; if (disp.GeometricTransformer != null) { pathPoints = (IPointCollection)disp.GeometricTransformer.Transform2D(pathPoints); } Geometry.DisplayPath displayPath = new Geometry.DisplayPath(); for (int iPoint = 0; iPoint < pathPoints.PointCount; iPoint++) { double x = pathPoints[iPoint].X, y = pathPoints[iPoint].Y; disp.World2Image(ref x, ref y); displayPath.AddPoint(new System.Drawing.PointF((float)x, (float)y)); } float pathLenght = displayPath.Length; if (pathLenght == 0.0 || textWidth > pathLenght) { continue; } displayPath.Chainage = pathLenght / 2f - textWidth / 2f; float nextChainage = pathLenght / 10f; bool found = false; while (!found) { if (disp.LabelEngine.TryAppend(disp, _symbol, displayPath, _labelPriority != labelPriority.always) == LabelAppendResult.Succeeded) { found = true; if (_howManyLabels == howManyLabels.one_per_name) { _labelStrings.Add(_symbol.Text.Trim()); } if (_howManyLabels != howManyLabels.one_per_part) { break; } } if (!found) { displayPath.Chainage = nextChainage; nextChainage += pathLenght / 10f; } if (displayPath.Chainage + textWidth > pathLenght) { break; } } } #endregion } else if (_lineLabelling == CartographicLineLabeling.Horizontal || _lineLabelling == CartographicLineLabeling.Perpendicular) { #region Horizontal for (int iPath = 0; iPath < pLine.PathCount; iPath++) { IPath path = pLine[iPath]; for (int iPoint = 0; iPoint < path.PointCount - 1; iPoint++) { IPoint p1 = path[iPoint]; IPoint p2 = path[iPoint + 1]; if (dispEnv.minx <= p1.X && dispEnv.maxx >= p1.X && dispEnv.miny <= p1.Y && dispEnv.maxy >= p1.Y && dispEnv.minx <= p2.X && dispEnv.maxx >= p2.X && dispEnv.miny <= p2.Y && dispEnv.maxy >= p2.Y) { double len = Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y)); if (len > maxLenght) { maxLenght = len; //alpha = Math.Atan2((p2.Y - p1.Y), (p2.X - p1.X)); point1 = p1; point2 = p2; } } } } if (point1 != null && point2 != null) { Point p = new Point(point1.X * 0.5 + point2.X * 0.5, point1.Y * 0.5 + point2.Y * 0.5); if (_lineLabelling == CartographicLineLabeling.Perpendicular) { double angle = Math.Atan2(point2.X - point1.X, point2.Y - point1.Y) * 180.0 / Math.PI; if (angle < 0) { angle += 360; } if (angle > 90 && angle < 270) { angle -= 180; } _symbol.Angle = (float)angle; } if (disp.LabelEngine.TryAppend(disp, _symbol, p, _labelPriority != labelPriority.always) == LabelAppendResult.Succeeded) { if (_howManyLabels == howManyLabels.one_per_name) { _labelStrings.Add(_symbol.Text.Trim()); } } } #endregion } else { #region Parallel Labelling for (int iPath = 0; iPath < pLine.PathCount; iPath++) { IPath path = pLine[iPath]; for (int iPoint = 0; iPoint < path.PointCount - 1; iPoint++) { IPoint p1 = path[iPoint]; IPoint p2 = path[iPoint + 1]; if (dispEnv.minx <= p1.X && dispEnv.maxx >= p1.X && dispEnv.miny <= p1.Y && dispEnv.maxy >= p1.Y && dispEnv.minx <= p2.X && dispEnv.maxx >= p2.X && dispEnv.miny <= p2.Y && dispEnv.maxy >= p2.Y) { double len = Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y)); if (len > maxLenght) { maxLenght = len; //alpha = Math.Atan2((p2.Y - p1.Y), (p2.X - p1.X)); point1 = p1; point2 = p2; } } } } if (point1 != null && point2 != null) { pLine = new Polyline(); pLine.AddPath(new Path()); pLine[0].AddPoint(point1); pLine[0].AddPoint(point2); if (disp.LabelEngine.TryAppend(disp, _symbol, pLine, _labelPriority != labelPriority.always) == LabelAppendResult.Succeeded) { if (_howManyLabels == howManyLabels.one_per_name) { _labelStrings.Add(_symbol.Text.Trim()); } } } #endregion } } else if (feature.Shape is IPolygon) { LabelPolygon(disp, (IPolygon)feature.Shape); } }