Beispiel #1
0
        /// <summary>
        /// Create a new point. This will activate drawing experience on the map. To complete it, select location from the map.
        /// </summary>
        /// <param name="sceneView">The <see cref="SceneView"/> that is used for drawing.</param>
        /// <exception cref="TaskCanceledException">If previous task wasn't completed, <see cref="TaskCanceledException"/>
        /// will be thrown. The task is cancelled if <see cref="Cancel"/> method or if any other draw or edit method is called.
        /// </exception>
        /// <returns>Return new <see cref="MapPoint"/> based on the user interactions.</returns>
        public static async Task <MapPoint> CreatePointAsync(SceneView sceneView)
        {
            Initialize();
            var geometry = await SceneDrawHelper.DrawPointAsync(sceneView, _drawTaskTokenSource.Token);

            Cleanup();
            return(geometry);
        }
Beispiel #2
0
        /// <summary>
        /// Edit existing <see cref="Polyline"/>. This will activate editing experience on the map. Edit is completed on double click.
        /// </summary>
        /// <param name="sceneView">The <see cref="SceneView"/> that is used for editing.</param>
        /// <exception cref="TaskCanceledException">If previous task wasn't completed, <see cref="TaskCanceledException"/>
        /// will be thrown. The task is cancelled if <see cref="Cancel"/> method or if any other draw or edit method is called.
        /// </exception>
        /// <returns>Return edited <see cref="Polygon"/> based on the user interactions.</returns>
        public static async Task <Polyline> EditPolylineAsync(SceneView sceneView, Polyline polyline)
        {
            Initialize();

            var             tcs             = new TaskCompletionSource <Polyline>();
            PolylineBuilder polylineBuilder = new PolylineBuilder(sceneView.SpatialReference);
            var             sketchlayer     = CreateSketchLayer(sceneView);
            var             vertexlayer     = CreateSketchLayer(sceneView);

            // Create vertices from the original polyline
            var vertices = new List <Graphic>();

            foreach (var vertex in (polyline.Parts[0].GetPoints()))
            {
                vertices.Add(new Graphic(vertex, DefaultVertexSymbol));
            }

            // Default to original polyline
            var newPolyline = new Polyline(polyline.Parts);

            Graphic lineGraphic = new Graphic(newPolyline)
            {
                Symbol = DefaultLineSymbol
            };
            Graphic lineMoveGraphic = new Graphic()
            {
                Symbol = DefaultLineMoveSymbol
            };

            sketchlayer.Graphics.AddRange(new Graphic[] { lineGraphic, lineMoveGraphic });
            vertexlayer.Graphics.AddRange(vertices);

            CancellationTokenSource tokenSource = null;
            Graphic selectedVertex  = null;
            bool    isEditingVertex = false;

            Action cleanupEvents = SetUpHandlers(sceneView,
                                                 (p) => //On mouse move, move completion line around
            {
                if (p != null && isEditingVertex)
                {
                    // Update visual indicator polyline
                    var vertexPoints = newPolyline.Parts[0].GetPoints().ToList();
                    var index        = vertexPoints
                                       .IndexOf(vertexPoints.Where
                                                    (point => GeometryEngine.Equals(point, selectedVertex.Geometry)).First());
                    var temporaryVertices = new List <MapPoint>();

                    if (index > 0)
                    {
                        temporaryVertices.Add(vertexPoints[index - 1]);     // Add previous segment
                    }
                    temporaryVertices.Add(p);
                    if (index != vertexPoints.Count() - 1)
                    {
                        temporaryVertices.Add(vertexPoints[index + 1]);     // Add next segment
                    }
                    var builder = new PolylineBuilder(temporaryVertices);
                    lineMoveGraphic.Geometry  = builder.ToGeometry();
                    lineMoveGraphic.IsVisible = true;
                }
            },
                                                 async(p) => //On tap add a vertex
            {
                if (p == null)
                {
                    return;
                }
                if (isEditingVertex)
                {
                    return;
                }
                if (selectedVertex != null)
                {
                    selectedVertex.IsSelected = false;
                }

                selectedVertex = await vertexlayer.HitTestAsync(sceneView, sceneView.LocationToScreen(p));

                // No vertex found so return
                if (selectedVertex == null)
                {
                    return;
                }

                isEditingVertex           = true;
                selectedVertex.IsSelected = true;
                tokenSource = new CancellationTokenSource();
                try
                {
                    var newPoint = await SceneDrawHelper.DrawPointAsync(sceneView, tokenSource.Token);

                    if (newPoint == null)
                    {
                        return;
                    }

                    var vertexPoints = newPolyline.Parts[0].GetPoints();
                    var index        = vertexPoints.ToList()
                                       .IndexOf(vertexPoints.Where
                                                    (point => GeometryEngine.Equals(point, selectedVertex.Geometry)).First());
                    var builder = new PolylineBuilder(vertexPoints);
                    builder.Parts[0].MovePoint(index, newPoint);

                    lineGraphic.Geometry = null;

                    // Update polyline
                    newPolyline          = builder.ToGeometry();
                    lineGraphic.Geometry = newPolyline;

                    // Update vertex
                    selectedVertex.Geometry = newPoint;
                    tokenSource             = null;
                }
                catch (TaskCanceledException tce)
                {
                }
                finally
                {
                    lineMoveGraphic.IsVisible = false;
                    selectedVertex.IsSelected = false;
                    selectedVertex            = null;
                    isEditingVertex           = false;
                }
            },
                                                 (p) => // Double tapped - completes task and returns new polyline
            {
                tcs.SetResult(newPolyline);
            });
            Action cleanup = () =>
            {
                cleanupEvents();
                sceneView.GraphicsOverlays.Remove(sketchlayer);
                sceneView.GraphicsOverlays.Remove(vertexlayer);
                if (tokenSource != null)
                {
                    tokenSource.Cancel();
                }
                Cleanup();
            };

            _drawTaskTokenSource.Token.Register(() => tcs.SetCanceled());

            Polyline result = null;

            try
            {
                result = await tcs.Task;
            }
            finally
            {
                cleanup();
            }
            return(result);
        }