/// <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); }
/// <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); }