protected override Task <bool> OnSketchCompleteAsync(Geometry geometry)
        {
            if (ActiveElementContainer == null)
            {
                Task.FromResult(true);
            }

            if (Module1.SelectedSymbol == null)
            {
                return(Task.FromResult(true));
            }

            return(QueuedTask.Run(() =>
            {
                var centerPt = ((Polygon)geometry).Extent.CenterCoordinate;
                double circleArea = ((Polygon)geometry).Extent.Area;
                double radius = Math.Sqrt(circleArea / Math.PI);
                var ellipticArcSegment = EllipticArcBuilder.CreateEllipticArcSegment(centerPt, radius, esriArcOrientation.esriArcClockwise);

                var ge = LayoutElementFactory.Instance.CreateCircleParagraphGraphicElement
                             (this.ActiveElementContainer,
                             ellipticArcSegment, "Text",
                             Module1.SelectedSymbol as CIMTextSymbol);
                //The new text graphic element has been created
                //We now switch to Pro's out of box "esri_layouts_inlineEditTool"
                //This will allow inline editing of the text
                //This tool will work on graphics on both map view and layouts
                FrameworkApplication.SetCurrentToolAsync("esri_layouts_inlineEditTool");
                return true;
            }));
        }
Пример #2
0
        /// <summary>
        /// Create a circular polygon around a mappoint for with a radius in pixels.
        /// </summary>
        /// <param name="mapPoint">Center of the circle as a mappoint.</param>
        /// <param name="pixels">Circle radius in screen pixels.</param>
        /// <returns>A polygon geometry.</returns>
        private Polygon CreateSearchPolygon(MapPoint mapPoint, int pixels)
        {
            //get search radius
            var screenPoint       = MapView.Active.MapToScreen(mapPoint);
            var radiusScreenPoint = new System.Windows.Point((screenPoint.X + pixels), screenPoint.Y);
            var radiusMapPoint    = MapView.Active.ScreenToMap(radiusScreenPoint);
            var searchRadius      = GeometryEngine.Distance(mapPoint, radiusMapPoint);

            //build a search circle geometry
            var cent       = new Coordinate2D(mapPoint);
            var searchGeom = EllipticArcBuilder.CreateEllipticArcSegment(cent, searchRadius, esriArcOrientation.esriArcClockwise, MapView.Active.Map.SpatialReference);
            var searchPB   = new PolygonBuilder(new[] { searchGeom });

            return(searchPB.ToGeometry());
        }
Пример #3
0
        /// <summary>
        /// Called when the sketch finishes. This is where we will create the sketch operation and then execute it.
        /// </summary>
        /// <param name="geometry">The geometry created by the sketch.</param>
        /// <returns>A Task returning a Boolean indicating if the sketch complete event was successfully handled.</returns>
        protected override Task <bool> OnSketchCompleteAsync(Geometry geometry)
        {
            if (CurrentTemplate == null || geometry == null)
            {
                return(Task.FromResult(false));
            }

            return(QueuedTask.Run(() =>
            {
                //build a circular arc
                var cent = new Coordinate2D(geometry as MapPoint);
                var circleEAB = EllipticArcBuilder.CreateEllipticArcSegment(cent, Radius, esriArcOrientation.esriArcClockwise, MapView.Active.Map.SpatialReference);

                // find the source layer and determine whether polyline/polygon.  Create the appropriate shape
                var lyr = CurrentTemplate.Layer as BasicFeatureLayer;
                Geometry circleGeom = null;
                if (lyr.ShapeType == esriGeometryType.esriGeometryPolygon)
                {
                    circleGeom = PolygonBuilder.CreatePolygon(new[] { circleEAB });
                }
                else
                {
                    circleGeom = PolylineBuilder.CreatePolyline(circleEAB);
                }

                // Create an edit operation
                var createOperation = new EditOperation();
                createOperation.Name = string.Format("Create circular {0}", CurrentTemplate.Layer.Name);
                createOperation.SelectNewFeatures = true;

                // Queue feature creation
                createOperation.Create(CurrentTemplate, circleGeom);

                // Execute the operation
                return createOperation.ExecuteAsync();
            }));
        }
Пример #4
0
        // Note: very different from ArcObjects-based ControlPointUtils (immutable geoms)

        public static Segment SetPointID(Segment template, int?startPointID, int?endPointID)
        {
            if (!startPointID.HasValue && !endPointID.HasValue)
            {
                return(template);                // nothing to update
            }

            switch (template)
            {
            case LineSegment lineSegment:
                using (var builder = new LineBuilder(lineSegment))
                {
                    builder.StartPoint = SetPointID(builder.StartPoint, startPointID);
                    builder.EndPoint   = SetPointID(builder.EndPoint, endPointID);
                    return(builder.ToSegment());
                }

            case EllipticArcSegment ellipticSegment:
                using (var builder = new EllipticArcBuilder(ellipticSegment))
                {
                    builder.StartPoint = SetPointID(builder.StartPoint, startPointID);
                    builder.EndPoint   = SetPointID(builder.EndPoint, endPointID);
                    return(builder.ToSegment());
                }

            case CubicBezierSegment bezierSegment:
                using (var builder = new CubicBezierBuilder(bezierSegment))
                {
                    builder.StartPoint = SetPointID(builder.StartPoint, startPointID);
                    builder.EndPoint   = SetPointID(builder.EndPoint, endPointID);
                    return(builder.ToSegment());
                }

            default:
                throw new ArgumentException(@"Unknown segment type", nameof(template));
            }
        }
Пример #5
0
        async public static void CreateElementSnippets()
        {
            //There are already many Create element snippets in the PRO snippets section.  This section will only contain examples that are NOT in the Pro snippets section
            //Pro snippets region names includes:
            //    Create point graphic with symbology
            //    Create line graphic with symbology
            //    Create rectangle graphic with simple symbology
            //    Create text element with basic font properties
            //    Create rectangle text with more advanced symbol settings
            //    Create a new picture element with advanced symbol settings
            //    Create a map frame and zoom to a bookmark
            //    Create a legend for a specifc map frame
            //    Creating group elements

            LayoutView lytView = LayoutView.Active;
            Layout     layout  = lytView.Layout;

            #region Create_BeizierCurve
            await QueuedTask.Run(() =>
            {
                //Build geometry
                Coordinate2D pt1          = new Coordinate2D(1, 7.5);
                Coordinate2D pt2          = new Coordinate2D(1.66, 8);
                Coordinate2D pt3          = new Coordinate2D(2.33, 7.1);
                Coordinate2D pt4          = new Coordinate2D(3, 7.5);
                CubicBezierBuilder bez    = new CubicBezierBuilder(pt1, pt2, pt3, pt4);
                CubicBezierSegment bezSeg = bez.ToSegment();
                Polyline bezPl            = PolylineBuilder.CreatePolyline(bezSeg);

                //Set symbology, create and add element to layout
                CIMLineSymbol lineSym = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.RedRGB, 4.0, SimpleLineStyle.DashDot);
                GraphicElement bezElm = LayoutElementFactory.Instance.CreateLineGraphicElement(layout, bezPl, lineSym);
                bezElm.SetName("New Bezier Curve");
            });

            #endregion Create_BeizierCurve

            #region Create_freehand
            await QueuedTask.Run(() =>
            {
                //Build geometry
                List <Coordinate2D> plCoords = new List <Coordinate2D>();
                plCoords.Add(new Coordinate2D(1.5, 10.5));
                plCoords.Add(new Coordinate2D(1.25, 9.5));
                plCoords.Add(new Coordinate2D(1, 10.5));
                plCoords.Add(new Coordinate2D(0.75, 9.5));
                plCoords.Add(new Coordinate2D(0.5, 10.5));
                plCoords.Add(new Coordinate2D(0.5, 1));
                plCoords.Add(new Coordinate2D(0.75, 2));
                plCoords.Add(new Coordinate2D(1, 1));
                Polyline linePl = PolylineBuilder.CreatePolyline(plCoords);

                //Set symbolology, create and add element to layout
                CIMLineSymbol lineSym  = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.BlackRGB, 2.0, SimpleLineStyle.Solid);
                GraphicElement lineElm = LayoutElementFactory.Instance.CreateLineGraphicElement(layout, linePl, lineSym);
                lineElm.SetName("New Freehand");
            });

            #endregion Create_freehand

            #region Create_polygon
            await QueuedTask.Run(() =>
            {
                //Build geometry
                List <Coordinate2D> plyCoords = new List <Coordinate2D>();
                plyCoords.Add(new Coordinate2D(1, 7));
                plyCoords.Add(new Coordinate2D(2, 7));
                plyCoords.Add(new Coordinate2D(2, 6.7));
                plyCoords.Add(new Coordinate2D(3, 6.7));
                plyCoords.Add(new Coordinate2D(3, 6.1));
                plyCoords.Add(new Coordinate2D(1, 6.1));
                Polygon poly = PolygonBuilder.CreatePolygon(plyCoords);

                //Set symbolology, create and add element to layout
                CIMStroke outline        = SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.BlueRGB, 2.0, SimpleLineStyle.DashDotDot);
                CIMPolygonSymbol polySym = SymbolFactory.Instance.ConstructPolygonSymbol(ColorFactory.Instance.RedRGB, SimpleFillStyle.ForwardDiagonal, outline);
                GraphicElement polyElm   = LayoutElementFactory.Instance.CreatePolygonGraphicElement(layout, poly, polySym);
                polyElm.SetName("New Polygon");
            });

            #endregion Create_polygon

            #region Create_circle
            await QueuedTask.Run(() =>
            {
                //Build geometry
                Coordinate2D center       = new Coordinate2D(2, 4);
                EllipticArcBuilder eabCir = new EllipticArcBuilder(center, 0.5, esriArcOrientation.esriArcClockwise);
                EllipticArcSegment cir    = eabCir.ToSegment();

                //Set symbolology, create and add element to layout
                CIMStroke outline          = SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.BlackRGB, 2.0, SimpleLineStyle.Dash);
                CIMPolygonSymbol circleSym = SymbolFactory.Instance.ConstructPolygonSymbol(ColorFactory.Instance.RedRGB, SimpleFillStyle.Solid, outline);
                GraphicElement cirElm      = LayoutElementFactory.Instance.CreateCircleGraphicElement(layout, cir, circleSym);
                cirElm.SetName("New Circle");
            });

            #endregion Create_circle

            #region Create_ellipse
            await QueuedTask.Run(() =>
            {
                //Build geometry
                Coordinate2D center        = new Coordinate2D(2, 2.75);
                EllipticArcBuilder eabElp  = new EllipticArcBuilder(center, 0, 1, 0.45, esriArcOrientation.esriArcClockwise);
                EllipticArcSegment ellipse = eabElp.ToSegment();

                //Set symbolology, create and add element to layout
                CIMStroke outline           = SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.GreenRGB, 2.0, SimpleLineStyle.Dot);
                CIMPolygonSymbol ellipseSym = SymbolFactory.Instance.ConstructPolygonSymbol(ColorFactory.Instance.GreyRGB, SimpleFillStyle.Vertical, outline);
                GraphicElement elpElm       = LayoutElementFactory.Instance.CreateEllipseGraphicElement(layout, ellipse, ellipseSym);
                elpElm.SetName("New Ellipse");
            });

            #endregion Create_ellipse

            #region Create_lasso
            await QueuedTask.Run(() =>
            {
                //Build geometry
                List <Coordinate2D> plyCoords = new List <Coordinate2D>();
                plyCoords.Add(new Coordinate2D(1, 1));
                plyCoords.Add(new Coordinate2D(1.25, 2));
                plyCoords.Add(new Coordinate2D(1.5, 1.1));
                plyCoords.Add(new Coordinate2D(1.75, 2));
                plyCoords.Add(new Coordinate2D(2, 1.1));
                plyCoords.Add(new Coordinate2D(2.25, 2));
                plyCoords.Add(new Coordinate2D(2.5, 1.1));
                plyCoords.Add(new Coordinate2D(2.75, 2));
                plyCoords.Add(new Coordinate2D(3, 1));
                Polygon poly = PolygonBuilder.CreatePolygon(plyCoords);

                //Set symbolology, create and add element to layout
                CIMStroke outline        = SymbolFactory.Instance.ConstructStroke(ColorFactory.Instance.BlackRGB, 2.0, SimpleLineStyle.Solid);
                CIMPolygonSymbol polySym = SymbolFactory.Instance.ConstructPolygonSymbol(ColorFactory.Instance.RedRGB, SimpleFillStyle.ForwardDiagonal, outline);
                GraphicElement polyElm   = LayoutElementFactory.Instance.CreatePolygonGraphicElement(layout, poly, polySym);
                polyElm.SetName("New Lasso");
            });

            #endregion Create_lasso

            #region Create_CurveText
            await QueuedTask.Run(() =>
            {
                //Build geometry
                Coordinate2D pt1          = new Coordinate2D(3.6, 7.5);
                Coordinate2D pt2          = new Coordinate2D(4.26, 8);
                Coordinate2D pt3          = new Coordinate2D(4.93, 7.1);
                Coordinate2D pt4          = new Coordinate2D(5.6, 7.5);
                CubicBezierBuilder bez    = new CubicBezierBuilder(pt1, pt2, pt3, pt4);
                CubicBezierSegment bezSeg = bez.ToSegment();
                Polyline bezPl            = PolylineBuilder.CreatePolyline(bezSeg);

                //Set symbolology, create and add element to layout
                CIMTextSymbol sym        = SymbolFactory.Instance.ConstructTextSymbol(ColorFactory.Instance.BlackRGB, 24, "Comic Sans MS", "Regular");
                GraphicElement bezTxtElm = LayoutElementFactory.Instance.CreateCurvedTextGraphicElement(layout, bezPl, "Curved Text", sym);
                bezTxtElm.SetName("New Splinned Text");
            });

            #endregion Create_CurveText

            #region Create_PolygonText
            await QueuedTask.Run(() =>
            {
                //Build geometry
                List <Coordinate2D> plyCoords = new List <Coordinate2D>();
                plyCoords.Add(new Coordinate2D(3.5, 7));
                plyCoords.Add(new Coordinate2D(4.5, 7));
                plyCoords.Add(new Coordinate2D(4.5, 6.7));
                plyCoords.Add(new Coordinate2D(5.5, 6.7));
                plyCoords.Add(new Coordinate2D(5.5, 6.1));
                plyCoords.Add(new Coordinate2D(3.5, 6.1));
                Polygon poly = PolygonBuilder.CreatePolygon(plyCoords);

                //Set symbolology, create and add element to layout
                CIMTextSymbol sym         = SymbolFactory.Instance.ConstructTextSymbol(ColorFactory.Instance.GreyRGB, 10, "Arial", "Regular");
                string text               = "Some Text String that is really long and is <BOL>forced to wrap to other lines</BOL> so that we can see the effects." as String;
                GraphicElement polyTxtElm = LayoutElementFactory.Instance.CreatePolygonParagraphGraphicElement(layout, poly, text, sym);
                polyTxtElm.SetName("New Polygon Text");

                //(Optionally) Modify paragraph border
                CIMGraphic polyTxtGra = polyTxtElm.Graphic;
                CIMParagraphTextGraphic cimPolyTxtGra   = polyTxtGra as CIMParagraphTextGraphic;
                cimPolyTxtGra.Frame.BorderSymbol        = new CIMSymbolReference();
                cimPolyTxtGra.Frame.BorderSymbol.Symbol = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.GreyRGB, 1.0, SimpleLineStyle.Solid);
                polyTxtElm.SetGraphic(polyTxtGra);
            });

            #endregion Create_PolygonText

            #region Create_CircleText
            await QueuedTask.Run(() =>
            {
                //Build geometry
                Coordinate2D center       = new Coordinate2D(4.5, 4);
                EllipticArcBuilder eabCir = new EllipticArcBuilder(center, 0.5, esriArcOrientation.esriArcClockwise);
                EllipticArcSegment cir    = eabCir.ToSegment();

                //Set symbolology, create and add element to layout
                CIMTextSymbol sym        = SymbolFactory.Instance.ConstructTextSymbol(ColorFactory.Instance.GreenRGB, 10, "Arial", "Regular");
                string text              = "Circle, circle, circle, circle, circle, circle, circle, circle, circle, circle, circle";
                GraphicElement cirTxtElm = LayoutElementFactory.Instance.CreateCircleParagraphGraphicElement(layout, cir, text, sym);
                cirTxtElm.SetName("New Circle Text");

                //(Optionally) Modify paragraph border
                CIMGraphic cirTxtGra = cirTxtElm.Graphic;
                CIMParagraphTextGraphic cimCirTxtGra   = cirTxtGra as CIMParagraphTextGraphic;
                cimCirTxtGra.Frame.BorderSymbol        = new CIMSymbolReference();
                cimCirTxtGra.Frame.BorderSymbol.Symbol = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.GreyRGB, 1.0, SimpleLineStyle.Solid);
                cirTxtElm.SetGraphic(cirTxtGra);
            });

            #endregion Create_CircleText

            #region Create_EllipseText
            await QueuedTask.Run(() =>
            {
                //Build geometry
                Coordinate2D center        = new Coordinate2D(4.5, 2.75);
                EllipticArcBuilder eabElp  = new EllipticArcBuilder(center, 0, 1, 0.45, esriArcOrientation.esriArcClockwise);
                EllipticArcSegment ellipse = eabElp.ToSegment();

                //Set symbolology, create and add element to layout
                CIMTextSymbol sym        = SymbolFactory.Instance.ConstructTextSymbol(ColorFactory.Instance.BlueRGB, 10, "Arial", "Regular");
                string text              = "Ellipse, ellipse, ellipse, ellipse, ellipse, ellipse, ellipse, ellipse, ellipse, ellipse, ellipse, ellipse";
                GraphicElement elpTxtElm = LayoutElementFactory.Instance.CreateEllipseParagraphGraphicElement(layout, ellipse, text, sym);
                elpTxtElm.SetName("New Ellipse Text");

                //(Optionally) Modify paragraph border
                CIMGraphic elpTxtGra = elpTxtElm.Graphic;
                CIMParagraphTextGraphic cimElpTxtGra   = elpTxtGra as CIMParagraphTextGraphic;
                cimElpTxtGra.Frame.BorderSymbol        = new CIMSymbolReference();
                cimElpTxtGra.Frame.BorderSymbol.Symbol = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.GreyRGB, 1.0, SimpleLineStyle.Solid);
                elpTxtElm.SetGraphic(elpTxtGra);
            });

            #endregion Create_EllipseText

            MapFrame mfElm = null;
            #region Create_MapFrame
            //This example creates a new map frame and changes the camera scale.
            await QueuedTask.Run(() =>
            {
                //Build geometry
                Coordinate2D ll = new Coordinate2D(6.0, 8.5);
                Coordinate2D ur = new Coordinate2D(8.0, 10.5);
                Envelope env    = EnvelopeBuilder.CreateEnvelope(ll, ur);

                //Reference map, create MF and add to layout
                MapProjectItem mapPrjItem = Project.Current.GetItems <MapProjectItem>().FirstOrDefault(item => item.Name.Equals("Map"));
                Map mfMap = mapPrjItem.GetMap();
                mfElm     = LayoutElementFactory.Instance.CreateMapFrame(layout, env, mfMap);
                mfElm.SetName("New Map Frame");

                //Set the camera
                Camera camera = mfElm.Camera;
                camera.Scale  = 24000;
                mfElm.SetCamera(camera);
            });

            #endregion Create_MapFrame


            #region Create_ScaleBar
            await QueuedTask.Run(() =>
            {
                //Reference a North Arrow in a style
                StyleProjectItem stylePrjItm = Project.Current.GetItems <StyleProjectItem>().FirstOrDefault(item => item.Name == "ArcGIS 2D");
                ScaleBarStyleItem sbStyleItm = stylePrjItm.SearchScaleBars("Double Alternating Scale Bar 1")[0];

                //Build geometry
                Coordinate2D center = new Coordinate2D(7, 8);

                //Reference MF, create north arrow and add to layout
                MapFrame mf = layout.FindElement("New Map Frame") as MapFrame;
                if (mf == null)
                {
                    ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("Map frame not found", "WARNING");
                    return;
                }
                ScaleBar sbElm = LayoutElementFactory.Instance.CreateScaleBar(layout, center, mf, sbStyleItm);
                sbElm.SetName("New Scale Bar");
                sbElm.SetWidth(2);
                sbElm.SetX(6);
                sbElm.SetY(7.5);
            });

            #endregion Create_ScaleBar

            #region Create_NorthArrow
            await QueuedTask.Run(() =>
            {
                //Reference a North Arrow in a style
                StyleProjectItem stylePrjItm   = Project.Current.GetItems <StyleProjectItem>().FirstOrDefault(item => item.Name == "ArcGIS 2D");
                NorthArrowStyleItem naStyleItm = stylePrjItm.SearchNorthArrows("ArcGIS North 10")[0];

                //Build geometry
                Coordinate2D center = new Coordinate2D(7, 5.5);

                //Reference MF, create north arrow and add to layout
                MapFrame mf = layout.FindElement("New Map Frame") as MapFrame;
                if (mf == null)
                {
                    ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("Map frame not found", "WARNING");
                    return;
                }
                NorthArrow arrowElm = LayoutElementFactory.Instance.CreateNorthArrow(layout, center, mf, naStyleItm);
                arrowElm.SetName("New North Arrow");
                arrowElm.SetHeight(1.75);
                arrowElm.SetX(7);
                arrowElm.SetY(6);
            });

            #endregion Create_NorthArrow
        }
        /// <summary>
        /// Returns a polygon with a range fan(circular ring sector - like a donut wedge or wiper blade swipe with inner and outer radius)
        /// from the input parameters
        /// Input Angles must be 0-360 degrees
        /// </summary>
        public static Geometry ConstructRangeFan(MapPoint centerPoint,
                                                 double innerDistanceInMapUnits, double outerDistanceInMapUnits,
                                                 double horizontalStartAngleInBearing, double horizontalEndAngleInBearing,
                                                 SpatialReference sr, double incrementAngleStep = 1.0)
        {
            // Check inputs
            if ((centerPoint == null) || (sr == null) ||
                (innerDistanceInMapUnits < 0.0) || (outerDistanceInMapUnits < 0.0) ||
                (horizontalStartAngleInBearing < 0.0) || (horizontalStartAngleInBearing > 360.0) ||
                (horizontalEndAngleInBearing < 0.0) || (horizontalEndAngleInBearing > 360.0))
            {
                return(null);
            }

            // Tricky - if angle cuts across 360, need to adjust for this case (ex. Angle: 270->90)
            if (horizontalStartAngleInBearing > horizontalEndAngleInBearing)
            {
                horizontalStartAngleInBearing = -(360.0 - horizontalStartAngleInBearing);
            }

            double deltaAngle = Math.Abs(horizontalStartAngleInBearing - horizontalEndAngleInBearing);

            // if full circle(or greater), return donut section with inner/outer rings
            if ((deltaAngle == 0.0) || (deltaAngle >= 360.0))
            {
                // Just add 2 concentric circle buffers
                PolygonBuilder donutPb = new PolygonBuilder();

                EllipticArcSegment circularArcOuter =
                    EllipticArcBuilder.CreateEllipticArcSegment((Coordinate2D)centerPoint,
                                                                outerDistanceInMapUnits, esriArcOrientation.esriArcClockwise, sr);

                donutPb.AddPart(new List <Segment> {
                    circularArcOuter
                });

                if (innerDistanceInMapUnits > 0.0)
                {
                    EllipticArcSegment circularArcInner =
                        EllipticArcBuilder.CreateEllipticArcSegment((Coordinate2D)centerPoint,
                                                                    innerDistanceInMapUnits, esriArcOrientation.esriArcCounterClockwise, sr);

                    donutPb.AddPart(new List <Segment> {
                        circularArcInner
                    });
                }

                return(donutPb.ToGeometry());
            }

            // Otherwise if range fan, construct that
            var points = new List <MapPoint>();

            MapPoint startPoint = null;

            if (innerDistanceInMapUnits <= 0.0)
            {
                startPoint = centerPoint;
                points.Add(startPoint);
            }

            double minAngle = Math.Min(horizontalStartAngleInBearing, horizontalEndAngleInBearing);
            double maxAngle = Math.Max(horizontalStartAngleInBearing, horizontalEndAngleInBearing);

            // don't let this create more than 360 points per arc
            if ((deltaAngle / incrementAngleStep) > 360.0)
            {
                incrementAngleStep = deltaAngle / 360.0;
            }

            // Draw Outer Arc of Ring
            // Implementation Note: because of the unique shape of this ring,
            // it was easier to manually create these points than use EllipticArcBuilder
            for (double angle = minAngle; angle <= maxAngle; angle += incrementAngleStep)
            {
                double cartesianAngle = (450 - angle) % 360;
                double angleInRadians = cartesianAngle * (Math.PI / 180.0);
                double x = centerPoint.X + (outerDistanceInMapUnits * Math.Cos(angleInRadians));
                double y = centerPoint.Y + (outerDistanceInMapUnits * Math.Sin(angleInRadians));

                MapPoint pointToAdd = MapPointBuilder.CreateMapPoint(x, y, sr);
                points.Add(pointToAdd);

                if (startPoint == null)
                {
                    startPoint = pointToAdd;
                }
            }

            if (innerDistanceInMapUnits > 0.0)
            {
                // Draw Inner Arc of Ring - if inner distance set
                for (double angle = maxAngle; angle >= minAngle; angle -= incrementAngleStep)
                {
                    double cartesianAngle = (450 - angle) % 360;
                    double angleInRadians = cartesianAngle * (Math.PI / 180.0);
                    double x = centerPoint.X + (innerDistanceInMapUnits * Math.Cos(angleInRadians));
                    double y = centerPoint.Y + (innerDistanceInMapUnits * Math.Sin(angleInRadians));

                    points.Add(MapPointBuilder.CreateMapPoint(x, y, sr));
                }
            }

            // close Polygon
            points.Add(startPoint);

            PolygonBuilder pb = new PolygonBuilder();

            pb.AddPart(points);

            return(pb.ToGeometry());
        }