Draw and Edit Graphics

Download Samples Repository

Description

This sample demonstrates drawing and editing map graphics.

"Desktop" "Store" "Phone" Available for Desktop, Store, Phone

Sample Code

<UserControl x:Class="ArcGISRuntime.Samples.Desktop.DrawAndEditGraphics"
		xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns:esri="http://schemas.esri.com/arcgis/runtime/2013">
	
	<Grid x:Name="LayoutRoot">
		<Grid.Resources>
			<esri:SimpleMarkerSymbol x:Key="SMS" Color="Red" Style="Circle" Size="10" />
			<esri:SimpleLineSymbol x:Key="SLS" Color="Red" Width="5" />
			<esri:SimpleFillSymbol x:Key="SFS" Color="#66FF0000" Style="Solid" />
			<esri:SimpleRenderer x:Key="MarkerRenderer" Symbol="{StaticResource SMS}" />
			<esri:SimpleRenderer x:Key="PolylineRenderer" Symbol="{StaticResource SLS}" />
			<esri:SimpleRenderer x:Key="PolygonRenderer" Symbol="{StaticResource SFS}" />
		</Grid.Resources>
		<esri:MapView x:Name="MyMapView" MapViewTapped="MyMapView_MapViewTapped">
			<esri:Map>
				<esri:Map.InitialViewpoint>
					<esri:ViewpointExtent XMin="-15000000" YMin="2000000" XMax="-7000000" YMax="8000000" />
				</esri:Map.InitialViewpoint>
				<esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer"
											  ServiceUri="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" />
			</esri:Map>
			<esri:MapView.GraphicsOverlays>
				<esri:GraphicsOverlay ID="PointGraphicsOverlay" Renderer="{StaticResource MarkerRenderer}" />
				<esri:GraphicsOverlay ID="PolylineGraphicsOverlay" Renderer="{StaticResource PolylineRenderer}" />
				<esri:GraphicsOverlay ID="PolygonGraphicsOverlay" Renderer="{StaticResource PolygonRenderer}" />
			</esri:MapView.GraphicsOverlays>
		</esri:MapView>

		<Border Background="White"  BorderThickness="1" CornerRadius="5"
				HorizontalAlignment="Right" VerticalAlignment="Top"
				Margin="10" BorderBrush="Black">
			<StackPanel Orientation="Vertical">
				<TextBlock Text="Instructions" Margin="5" FontSize="16" FontWeight="Bold"/>
				<TextBlock Margin="10" HorizontalAlignment="Center" FontSize="12" TextWrapping="Wrap">
				- Select Shape and click Draw to start drawing. <LineBreak/>
				<LineBreak/>
				- Click on shape to select and click Edit to start editing.<LineBreak/>
				<LineBreak/>
				- Click on Yellow Handles to scale.<LineBreak/>
				<LineBreak/>
				- Click on white midpoints to add a new vertex.<LineBreak/>
				<LineBreak/>
				- Click on Blue Handles to rotate
				</TextBlock>
			</StackPanel>
		</Border>

		<Border Background="White" BorderThickness="1" CornerRadius="5"
				HorizontalAlignment="Left" VerticalAlignment="Top"
				Margin="10" BorderBrush="Black">
			<Grid>
				<Grid.RowDefinitions>
					<RowDefinition Height="Auto"/>
					<RowDefinition Height="Auto"/>
					<RowDefinition Height="Auto"/>
				</Grid.RowDefinitions>
				<StackPanel Orientation="Horizontal" Grid.Row="1">
					<ComboBox x:Name="DrawShapes" 
							  Padding="10" Margin="5"/>
					<Button Content="Draw" Click="OnDrawButtonClicked" 
							Padding="10" Margin="5"/>
					<Button Content="Edit" Click="OnDrawButtonClicked" 
							Padding="10" Margin="5" />
					<Button Content="Undo" Command="{Binding Editor.Undo, ElementName=MyMapView}" 
							Padding="10" Margin="5"/>
					<Button Content="Redo" Command="{Binding Editor.Redo, ElementName=MyMapView}"
							Padding="10" Margin="5"/>
					<Button Content="Cancel" Command="{Binding Editor.Cancel, ElementName=MyMapView}"
							Padding="10" Margin="5"/>
					<Button Content="Complete" Command="{Binding Editor.Complete, ElementName=MyMapView}" 
							Padding="10" Margin="5"/>
					<Button Content="Delete Selected Vertex" Command="{Binding Editor.DeleteVertex, ElementName=MyMapView}" 
							Padding="10" Margin="5"/>
				</StackPanel>
				<StackPanel Orientation="Horizontal" Grid.Row="2" Margin="10">
					<CheckBox x:Name="AddVertex" 
							  Content="AddVertex" IsChecked="True"
							  Margin="5"/>
					<CheckBox x:Name="MoveVertex" 
							  Content="Move Vertex" IsChecked="True" 
							  Margin="5"/>
					<CheckBox x:Name="DeleteVertex" 
							  Content="Delete Vertex" IsChecked="True" 
							  Margin="5"/>
					<CheckBox x:Name="MoveGeometry" 
							  Content="Move Geometry" IsChecked="True"
							  Margin="5"/>
					<CheckBox x:Name="Scale" 
							  Content="Scale" IsChecked="True" 
							  Margin="5"/>
					<CheckBox x:Name="Rotate" 
							  Content="Rotate" IsChecked="True" 
							  Margin="5"/>
					<CheckBox x:Name="MaintainAspectRatio" 
							  Content="Maintain AspectRatio" IsChecked="True"
							  Margin="5"/>
				</StackPanel>
			</Grid>
		</Border>
	</Grid>
</UserControl>
using Esri.ArcGISRuntime.Controls;
using Esri.ArcGISRuntime.Layers;
using Esri.ArcGISRuntime.Symbology;
using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace ArcGISRuntime.Samples.Desktop
{
	/// <summary>
	/// This sample demonstrates drawing and editing map graphics.
	/// </summary>
	/// <title>Draw and Edit Graphics</title>
	/// <category>Editing</category>
	public partial class DrawAndEditGraphics : UserControl
	{
		Graphic _editGraphic = null;

		public DrawAndEditGraphics()
		{
			InitializeComponent();

			DrawShapes.ItemsSource = new DrawShape[]
			{
				DrawShape.Freehand,
				DrawShape.Point,
				DrawShape.Polygon,
				DrawShape.Polyline,
				DrawShape.Arrow,
				DrawShape.Circle,
				DrawShape.Ellipse,
				DrawShape.LineSegment,
				DrawShape.Rectangle
			};
			DrawShapes.SelectedIndex = 0;
		}

		private async void OnDrawButtonClicked(object sender, RoutedEventArgs e)
		{
			string message = null;
			var resultGeometry = _editGraphic == null ? null : _editGraphic.Geometry;

			var editCnfg = MyMapView.Editor.EditorConfiguration;
			editCnfg.AllowAddVertex = AddVertex.IsChecked.HasValue && AddVertex.IsChecked.Value;
			editCnfg.AllowDeleteVertex = DeleteVertex.IsChecked.HasValue && DeleteVertex.IsChecked.Value;
			editCnfg.AllowMoveGeometry = MoveGeometry.IsChecked.HasValue && MoveGeometry.IsChecked.Value;
			editCnfg.AllowMoveVertex = MoveVertex.IsChecked.HasValue && MoveVertex.IsChecked.Value;
			editCnfg.AllowRotateGeometry = Rotate.IsChecked.HasValue && Rotate.IsChecked.Value;
			editCnfg.AllowScaleGeometry = Scale.IsChecked.HasValue && Scale.IsChecked.Value;
			editCnfg.MaintainAspectRatio = MaintainAspectRatio.IsChecked.HasValue && MaintainAspectRatio.IsChecked.Value;
			editCnfg.VertexSymbol =
					new SimpleMarkerSymbol() { Style = SimpleMarkerStyle.Diamond, Color = Colors.Yellow, Size = 15 };

			try
			{
				var drawShape = (DrawShape)DrawShapes.SelectedItem;

				GraphicsOverlay graphicsOverlay;
				graphicsOverlay = drawShape == DrawShape.Point ? MyMapView.GraphicsOverlays["PointGraphicsOverlay"] as GraphicsOverlay :
						   ((drawShape == DrawShape.Polyline || drawShape == DrawShape.Freehand || drawShape == DrawShape.LineSegment) ?
				  MyMapView.GraphicsOverlays["PolylineGraphicsOverlay"] as GraphicsOverlay : MyMapView.GraphicsOverlays["PolygonGraphicsOverlay"] as GraphicsOverlay);

				var progress = new Progress<GeometryEditStatus>();
				progress.ProgressChanged += (a, b) =>
				{
					//if (b.GeometryEditAction == GeometryEditAction..CompletedEdit)
					//    if (_editGraphic != null)
					//        _editGraphic.IsSelected = false;

				};

				var content = (sender as Button).Content.ToString();
				switch (content)
				{
					case "Draw":
						{
							var r = await MyMapView.Editor.RequestShapeAsync(drawShape, null, progress);
							graphicsOverlay.Graphics.Add(new Graphic() { Geometry = r });
							break;
						}
					case "Edit":
						{
							if (_editGraphic == null)
								return;
							var g = _editGraphic;
							g.IsVisible = false;
							var r = await MyMapView.Editor.EditGeometryAsync(g.Geometry, null, progress);
							resultGeometry = r ?? resultGeometry;
							_editGraphic.Geometry = resultGeometry;
							_editGraphic.IsSelected = false;
							break;
						}
				}

			}
			catch (TaskCanceledException)
			{
				// Ignore TaskCanceledException - usually happens if the editor gets cancelled or restarted
			}
			catch (Exception ex)
			{

				message = ex.Message;				
			}
			finally
			{
				if (_editGraphic != null)
				{
					_editGraphic.IsVisible = true;
					_editGraphic = null;
				}
			}
			if (message != null)
				MessageBox.Show(message);
		}

		private async void MyMapView_MapViewTapped(object sender, MapViewInputEventArgs e)
		{
			if (MyMapView.Editor.IsActive)
				return;

			var drawShape = (DrawShape)DrawShapes.SelectedItem;
			GraphicsOverlay graphicsOverlay;
			graphicsOverlay = drawShape == DrawShape.Point ? MyMapView.GraphicsOverlays["PointGraphicsOverlay"] as GraphicsOverlay :
					   ((drawShape == DrawShape.Polyline || drawShape == DrawShape.Freehand || drawShape == DrawShape.LineSegment) ?
			  MyMapView.GraphicsOverlays["PolylineGraphicsOverlay"] as GraphicsOverlay : MyMapView.GraphicsOverlays["PolygonGraphicsOverlay"] as GraphicsOverlay);


			var graphic = await graphicsOverlay.HitTestAsync(MyMapView, e.Position);

			if (graphic != null)
			{
				//Clear previous selection
				foreach (GraphicsOverlay gOLay in MyMapView.GraphicsOverlays)
				{
					gOLay.ClearSelection();
				}

				//Cancel editing if started
				if (MyMapView.Editor.Cancel.CanExecute(null))
					MyMapView.Editor.Cancel.Execute(null);

				_editGraphic = graphic;
				_editGraphic.IsSelected = true;
			}
		}
	}
}
Feedback on this topic?