Skip To Content ArcGIS for Developers Sign In Dashboard

ArcGIS Runtime SDK for .NET

Difference

Download Samples Repository

Description

Example of using the GeometryEngine.Difference or GeometryEngine.SymmetricDifference methods to calculate the geometric difference between feature geometries and a user defined geometry. To use this sample, the user draws a polygon over the feature polygons and the system then calculates the difference between the intersecting feature geometries and displays the resulting polygons in a graphics layer on the map.

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

Sample Code

<UserControl x:Class="ArcGISRuntime.Samples.Desktop.Difference"
             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="layoutGrid">
        <Grid.Resources>
            <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>

            <esri:SimpleFillSymbol x:Key="FillSymbol" Color="#660000FF" Style="Solid">
                <esri:SimpleFillSymbol.Outline>
                    <esri:SimpleLineSymbol Color="Blue" Width="2" />
                </esri:SimpleFillSymbol.Outline>
            </esri:SimpleFillSymbol>
        </Grid.Resources>

        <esri:MapView x:Name="MyMapView" WrapAround="True">
			<esri:Map InitialViewpoint="-15053000,2749000,-6540000,6590000">
				<esri:ArcGISTiledMapServiceLayer
                    ServiceUri="http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer" />
			</esri:Map>
			<esri:MapView.GraphicsOverlays>
				<esri:GraphicsOverlay ID="resultsOverlay" />
			</esri:MapView.GraphicsOverlays>
        </esri:MapView>

		<Border Background="White" BorderBrush="Black" BorderThickness="1"
				 HorizontalAlignment="Right" VerticalAlignment="Top"
				 Margin="30" Padding="20">
			<Border.Effect>
				<DropShadowEffect/>
			</Border.Effect>
			<StackPanel>
                <TextBlock Text="Click the 'Difference' button to digitize a polygon and calculate the geometric difference between polygon features and the digitized polygon. Resulting difference polygons will be shown as blue graphics."
                           Width="400" TextAlignment="Left" TextWrapping="Wrap" />
                <StackPanel Margin="12,12,12,0" HorizontalAlignment="Center">
                    <Button Content="Difference" Click="DifferenceButton_Click" />
                    <CheckBox x:Name="useSymmetricDifference" Content="Use Symmetric Difference" Margin="12,12,12,0" HorizontalAlignment="Center" />
                </StackPanel>
            </StackPanel>
        </Border>

        <Border Background="White" BorderBrush="Black" BorderThickness="2" Margin="25"
                HorizontalAlignment="Center" VerticalAlignment="Bottom"
                Visibility="{Binding ElementName=MyMapView, Path=Editor.IsActive, Converter={StaticResource BooleanToVisibilityConverter}}">
            <TextBlock Text="Draw a polygon on the map." Margin="8" FontSize="14" />
        </Border>
    </Grid>
</UserControl>
using Esri.ArcGISRuntime.Controls;
using Esri.ArcGISRuntime.Data;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.Layers;
using Esri.ArcGISRuntime.Symbology;
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace ArcGISRuntime.Samples.Desktop
{
    /// <summary>
    /// Example of using the GeometryEngine.Difference or GeometryEngine.SymmetricDifference methods to calculate the geometric difference between feature geometries and a user defined geometry. To use this sample, the user draws a polygon over the feature polygons and the system then calculates the difference between the intersecting feature geometries and displays the resulting polygons in a graphics layer on the map.
    /// </summary>
    /// <title>Difference</title>
	/// <category>Geometry</category>
	public partial class Difference : UserControl
    {
        private const string GDB_PATH = @"..\..\..\samples-data\maps\usa.geodatabase";

        private Symbol _fillSymbol;
        private FeatureLayer _statesLayer;
		private GraphicsOverlay _differenceGraphics;

        /// <summary>Construct Difference sample control</summary>
        public Difference()
        {
            InitializeComponent();

            _fillSymbol = layoutGrid.Resources["FillSymbol"] as Symbol;
			_differenceGraphics = MyMapView.GraphicsOverlays["resultsOverlay"];
            CreateFeatureLayers();
        }

        // Creates a feature layer from a local .geodatabase file
		private async void CreateFeatureLayers()
        {
            try
            {
                var gdb = await Geodatabase.OpenAsync(GDB_PATH);

                var table = gdb.FeatureTables.First(ft => ft.Name == "US-States");
                _statesLayer = new FeatureLayer() { ID = table.Name, FeatureTable = table };
                MyMapView.Map.Layers.Add(_statesLayer);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error creating feature layer: " + ex.Message, "Geometry Difference Sample");
            }
        }

        // Calculates a geometric difference between features and user defined geometry
        private async void DifferenceButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
				_differenceGraphics.Graphics.Clear();

                // wait for user to draw difference polygon
                Polygon userpoly = await MyMapView.Editor.RequestShapeAsync(DrawShape.Polygon) as Polygon;

				// Take account of WrapAround
				Polygon poly = GeometryEngine.NormalizeCentralMeridian(userpoly) as Polygon;

                // Adjust user polygon for backward digitization
                poly = GeometryEngine.Simplify(poly) as Polygon;

                // get intersecting features from the feature layer
                SpatialQueryFilter filter = new SpatialQueryFilter();
                filter.Geometry = GeometryEngine.Project(poly, _statesLayer.FeatureTable.SpatialReference);
                filter.SpatialRelationship = SpatialRelationship.Intersects;
                filter.MaximumRows = 52;
                var stateFeatures = await _statesLayer.FeatureTable.QueryAsync(filter);

                // Calc difference between feature geometries and user polygon and add results to graphics layer
                var states = stateFeatures.Select(feature => feature.Geometry);

                var diffGraphics = states
                    .Select(state => ((bool)useSymmetricDifference.IsChecked) 
                        ? GeometryEngine.SymmetricDifference(state, poly) 
                        : GeometryEngine.Difference(state, poly))
                    .Select(geo => new Graphic(geo, _fillSymbol));

				_differenceGraphics.Graphics.AddRange(diffGraphics);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Difference Error: " + ex.Message, "Geometry Difference Sample");
            }
        }
    }
}
Feedback on this topic?