EllipticArcSegment in SceneView

127
3
08-07-2022 11:01 AM
FranciscoLopez
New Contributor II

I want to create an arc in an SceneView. People told me I have to use EllipticArcSegment, and it works in MapView, but I can use it in SceneView. When I use EllipticArcSegment in ScenView I get a line not an arc. See the picture.

public MainWindow()
{
InitializeComponent();
MySceneView.Scene = new Scene(BasemapStyle.ArcGISImageryStandard);
MyMapView.Map = new Map(BasemapStyle.ArcGISTopographic);

MapPoint _spain = new MapPoint(-4.00475, 40.637861, SpatialReferences.Wgs84);
Graphic _arc = CreateArc(_spain, 0.080, 90.0, 45.0);
Graphic _arc1 = CreateArc(_spain, 0.080, 90.0, 45.0);
_AiminginZone_GO.Graphics.Add(_arc);
_AiminginZone_GO1.Graphics.Add(_arc1);
MyMapView.GraphicsOverlays.Add(_AiminginZone_GO);
MySceneView.GraphicsOverlays.Add(_AiminginZone_GO1);
}

private Graphic CreateArc(MapPoint center, double radius, double arcAngle, double azimuth)
{

_AiminginZone_GO.Graphics.Clear();
_AiminginZone_GO1.Graphics.Clear();
// set up spatial references
SpatialReference wgs84 = SpatialReferences.Wgs84;
SpatialReference webMercator = SpatialReferences.WebMercator;
// make a point in lat/long (WGS84)
MapPoint centrePoint = new MapPoint(center.X, center.Y, 56, wgs84);
MapPoint centrePoint1 = new MapPoint(center.X+0.05, center.Y, 56, wgs84);
// project it to a mercator projection where the unit of measure is metres
MapPoint mercatorPoint = (MapPoint)GeometryEngine.Project(centrePoint, webMercator);
// create an arc segment which is 50Kilometers radius, starting at 90 degrees, the arc angle is 45 degrees clockwise
//EllipticArcSegment arcSegment = new EllipticArcSegment(centrePoint, mercatorPoint, (Math.PI / 180) * 90, true, true, (Math.PI / 180) * 90, (Math.PI / 180) * -45, wgs84);
EllipticArcSegment arcSegment = EllipticArcSegment.CreateCircularEllipticArc(mercatorPoint, 50000, (Math.PI / 180) * 90, (Math.PI / 180) * -45, webMercator);

// make a part with the segment
Part part = new Part(webMercator);
part.Add(arcSegment);

// create the line from the part
Polyline line = new Polyline(part);

// add it to a graphic and graphics overlay to allow us to visualise it
var polylineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle.Dash, System.Drawing.Color.Red, 3.0);
Graphic arcGraphic = new Graphic(line, polylineSymbol);
return arcGraphic;
}

 

00.Compare.png

 

 

 

0 Kudos
3 Replies
Nicholas-Furness
Esri Regular Contributor

Hi. Thanks for following up in the Esri Community!

Unfortunately there is a bug in Runtime that means that true curves in a GraphicsOverlay require that the graphics overlay rendering mode is set to static. The default mode is dynamic.

This also impacts true curves in a feature layer backed by a mobile geodatabase, but that doesn't impact you here.

One alternative you could consider if you must display the GraphicsOverlay in dynamic mode is to densify the curve geometry and use the densified geometry for your graphic.

Hope this helps. I'll see how we can expose this information through the docs until we are able to fix it.

0 Kudos
FranciscoLopez
New Contributor II

Hi Nicholas, I have tried to use Densify without success. I am new using using GIS Tools and I do not understand how to resolve the problem using densify.

0 Kudos
FranciscoLopez
New Contributor II

Hi, so I was doing some test using the following the attached code and the results are very stranger, see the pictures.

 

I am using SceneView (Left picture) and MapView (Right picture). In the code, I draw a circle using GeodesicEllipseParameters and it make a perfect circle in the both Views. And I draw a Arc using EllipticArcSegment.CreateCircularEllipticArc where I cant make an arc that it follows the circle. In the pictures can show differents results.

The result is different using Dynamic or Static rendering.

I'd like to make a semi circle forms part of the main circle. So, How can I do it? The semi circle is defined by a radius, angle and azimuth.

The code is:

 

private void ShowGraphics(MapPoint center, double radius, double startAngle, double azimuth)
        {
            CheckGOType();
            //***********************************************************************************
            MyMapView.GraphicsOverlays.Clear();
            MySceneView.GraphicsOverlays.Clear();
            GraphicsOverlay MyMapView_go = new GraphicsOverlay();
            GraphicsOverlay MySceneView_go = new GraphicsOverlay();
            MyMapView_go.RenderingMode = ValueSelectes;
            MySceneView_go.RenderingMode = ValueSelectes;
            MyMapView_go.Graphics.Clear();
            MySceneView_go.Graphics.Clear();
            MyMapView_go.Graphics.Add(MakeArc(center, radius / 100, startAngle, azimuth));
            MySceneView_go.Graphics.Add(MakeArc(center, radius / 100, startAngle, azimuth));
            MyMapView.GraphicsOverlays.Add(MyMapView_go);
            MySceneView.GraphicsOverlays.Add(MySceneView_go);
            //***********************************************************************************
            GraphicsOverlay CircleScene = new GraphicsOverlay();
            GraphicsOverlay CircleMap = new GraphicsOverlay();
            CircleScene.RenderingMode = GraphicsRenderingMode.Dynamic;
            CircleMap.RenderingMode = GraphicsRenderingMode.Dynamic;
            CircleScene.Graphics.Clear();
            CircleMap.Graphics.Clear();
            CircleMap = MakeEllipseGraphicsOverlay(center, radius);
            CircleScene = MakeEllipseGraphicsOverlay(center, radius);
            MyMapView.GraphicsOverlays.Add(CircleMap);
            MySceneView.GraphicsOverlays.Add(CircleScene);
        }
        private void CheckGOType()
        {
            if (tDynamic.IsChecked == true)
            {
                ValueSelectes = GraphicsRenderingMode.Dynamic;
            }
            if (tStatic.IsChecked == true)
            {
                ValueSelectes = GraphicsRenderingMode.Static;
            }
        }
        private Graphic MakeArc(MapPoint center, double radius, double arcAngle, double azimuth)
        {
            SpatialReference spatialReference = center.SpatialReference;
            // Get the angle of the azimuth.
            var directionAngle = 90 - azimuth;
            directionAngle = (directionAngle < 0) ? directionAngle + 360 : directionAngle;
            directionAngle = (directionAngle > 360) ? directionAngle - 360 : directionAngle;
            // Subtract half of the arc angle from the direction (wedge should be split by the azimuth angle).
            var startPointDegrees = directionAngle - (arcAngle / 2);
            startPointDegrees = (startPointDegrees < 0) ? startPointDegrees + 360 : startPointDegrees;
            startPointDegrees = (startPointDegrees > 360) ? startPointDegrees - 360 : startPointDegrees;
            // Get the radian values of the angles.
            var startPointRadians = startPointDegrees * Math.PI / 180.0;
            var arcAngleRadians = arcAngle * Math.PI / 180;
            // Create an arc segment with the center point, radius, start point of the arc, arc angle, and spatial reference.
            EllipticArcSegment arc = EllipticArcSegment.CreateCircularEllipticArc(center, radius, startPointRadians, arcAngleRadians, spatialReference);
            // create the sides of the wedge (center point to start/end points of the arc).
            var startSide = new LineSegment(center, arc.StartPoint);
            //var endSide = new LineSegment(center, arc.EndPoint);
            // Create the wedge-shaped polygon.
            PolygonBuilder builder = new PolygonBuilder(spatialReference);
            // Note: only need to add one of the sides to complete the polygon.
            builder.AddPart(new Part(new Segment[] { startSide, arc }, spatialReference));
            var polylineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, System.Drawing.Color.White, 2.0);
            Graphic ellipseGraphic = new Graphic(builder.ToGeometry(), polylineSymbol);
            return ellipseGraphic;
        }
        private GraphicsOverlay MakeEllipseGraphicsOverlay(MapPoint center, double distance)
        {
            // Create a simple fill symbol with outline.
            SimpleLineSymbol curvedLineSymbol = new SimpleLineSymbol(SimpleLineSymbolStyle.Solid, System.Drawing.Color.Black, 5);
            SimpleFillSymbol curvedFillSymbol = new SimpleFillSymbol(SimpleFillSymbolStyle.Null, System.Drawing.Color.Purple, curvedLineSymbol);
            // Create a graphics overlay for the polygons with curve segments.
            GraphicsOverlay ellipseGraphicsOverlay = new GraphicsOverlay();

            // Create and assign a simple renderer to the graphics overlay.
            ellipseGraphicsOverlay.Renderer = new SimpleRenderer(curvedFillSymbol);
            // Create the polygon geometry, then create a graphic using that polygon.
            Polygon ellipse = MakeEllipseGeometry(center, distance);
            Graphic ellipseGraphic = new Graphic(ellipse);
            // Add the graphic to the graphics overlay.
            ellipseGraphicsOverlay.Graphics.Add(ellipseGraphic);
            return ellipseGraphicsOverlay;
        }
        private Polygon MakeEllipseGeometry(MapPoint center, double distance)
        {
            // Creates a GeodesicEllipseParameters object to use for GeometryEngine.EllipseGeodesic method.
            GeodesicEllipseParameters parameters = new GeodesicEllipseParameters
            {
                Center = center,
                GeometryType = GeometryType.Polygon,
                SemiAxis1Length = distance,
                SemiAxis2Length = 0,
                AxisDirection = 0,
                MaxPointCount = 2360,
                // Angular unit is degrees by default.
                AngularUnit = AngularUnits.Degrees,
                // Linear unit is meters by default.
                LinearUnit = LinearUnits.Kilometers,
                MaxSegmentLength = 0.001
            };
            Polygon ellipsePoly = (Polygon)GeometryEngine.EllipseGeodesic(parameters);
            return ellipsePoly;
        }

 

 

01.png02.png03.png04.png05.png

0 Kudos