예제 #1
0
        public IDisplayCharacterRanges MeasureCharacterWidth(IDisplay display)
        {
            if (_measureTextWidth != null)
            {
                return(_measureTextWidth);
            }

            var format = StringFormatFromAlignment(_align);
            IDisplayCharacterRanges ranges = display.Canvas.DisplayCharacterRanges(_font, format, _text);

            return(ranges);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
            }
        }