Click or drag to resize
Code Example - GeometryEngine_TestingSpatialRelationships

Demonstrates using the powerful GeometryEngine local process to test various spatial relationships (Contains, Crosses, Disjoint, Equals, Intersects, Overlaps, Touches, Within) between two input geometries.

Code Example
Geometry Engine Testing Spatial Relationships

This section contains selected code files from a Visual Studio project that emphasize specific ArcGIS Runtime SDK (Windows Desktop) features. For example: some code examples may accomplish the bulk of the work as a configuration property in the .xaml file and hence only the .xaml file will be shown in detail below. In other code examples, the .xaml is used to define the configuration of graphical elements for the application but the application logic is performed in the code behind, hence you may see both the .xaml and .cs/.vb files shown in detail below.

XAML
<Window x:Class="GeometryEngine_TestingSpatialRelationships.MainWindow"
        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"
    Title="MainWindow" Height="600" Width="800">
    <Grid>

        <StackPanel x:Name="StackPanel1" Orientation="Vertical">

            <!-- TextBlock to hold the instructions on how to use the sample code. -->
            <TextBlock Height="74" HorizontalAlignment="Left" Name="TextBlock1" VerticalAlignment="Top" Width="775" 
                   TextWrapping="Wrap" Margin="7,0,0,0" />

            <!-- Add a MapView with a GraphicsLayer. -->
            <StackPanel x:Name="StackPanel_Maps" Orientation="Horizontal">
                <esri:MapView x:Name="MapView1" Height="390" Width="390" BorderBrush="Black" BorderThickness="2">
                    <esri:Map >
                        <esri:GraphicsLayer x:Name="MyPolygonGraphicsLayer" />
                    </esri:Map>
                </esri:MapView>
                <TextBox x:Name="TextBox_Results" Width="390" />
            </StackPanel>

            <!-- Add a StackPanel for the buttons that a user can push to test various GeometryEngine spatial relationships (Contains, Crosses, Disjoint, Equals
                 Intersects, Overlaps, Touches, Within). -->
            <StackPanel x:Name="StackPanel2" Orientation="Horizontal" HorizontalAlignment="Center">
                <Button x:Name="Button_Shift_Up" Content="Shift Up" Click="Button_Shift_Up_Click" Margin="3,3" FontSize="18" Foreground="Green" FontWeight="Bold"/>
                <Button x:Name="Button_Shift_Down" Content="Shift Down" Click="Button_Shift_Down_Click" Margin="3,3" FontSize="18" Foreground="Black" FontWeight="Bold"/>
            </StackPanel>
        </StackPanel>

    </Grid>
</Window>

SPECIAL NOTE: The XAML displayed above comes from a C# project. If you are a VB.NET developer, you will need to modify the text for the x:Class namespace from "GeometryEngine_TestingSpatialRelationships.MainWindow" to be just "MainWindow".

namespace GeometryEngine_TestingSpatialRelationships
{
    public partial class MainWindow : System.Windows.Window
    {
        public MainWindow()
        {
            InitializeComponent();

            // Add instructions on how to use the sample. 
            TextBlock1.Text = "When the application loads two polygon geometries will be drawn of exactly the same size, shape, and position in the Map -- " + 
                "Geometry1 has a thick black outline and Geometry2 has a thin red outline. Various spatial relationship tests will be displayed in the TextBox. " + 
                "Click the 'Shift Up' and 'Shift Down' buttons to move Geometry2 across the Map to see how the spatial relationships change between the two polygons.";

            // Define a fictitious initial extent for the two Map's.
            Esri.ArcGISRuntime.Geometry.Envelope myEnvelope = new Esri.ArcGISRuntime.Geometry.Envelope(-2, -2, 12, 12);
            MapView1.Map.InitialViewpoint = new Esri.ArcGISRuntime.Controls.Viewpoint(myEnvelope);

            // The Map control typically gets it's SpatialReference from the 1st layer that is added to the Map's LayerCollection.
            // In this unique case, only an empty GraphicsLayer (without any defined SpatialReference) was added to the Map's 
            // LayerCollection and hence the Map control did not have any SpatialReference set. We will manually set the Map's 
            // SpatialReference with the next line of code, so that graphics can be drawn. 
            MapView1.Map.SpatialReference = Esri.ArcGISRuntime.Geometry.SpatialReferences.WebMercator;


            // Draw the 1st polygon graphic in MapView1.
            // -----------------------------------------

            //Define a list of MapPoint's (the basic building blocks of a polygons shape).
            System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint> myListOfMapPoints = new System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint>();
            myListOfMapPoints.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(3, 3));
            myListOfMapPoints.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(5, 6));
            myListOfMapPoints.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(7, 3));

            // Create a new Polygon geometry using the List of MapPoints in the defined SpatialReference as the map control. 
            Esri.ArcGISRuntime.Geometry.Polygon myPolygon = new Esri.ArcGISRuntime.Geometry.Polygon(myListOfMapPoints, new Esri.ArcGISRuntime.Geometry.SpatialReference(102100));

            // Define a basic fill symbol for the polygon.
            Esri.ArcGISRuntime.Symbology.SimpleFillSymbol myFillSymbol = new Esri.ArcGISRuntime.Symbology.SimpleFillSymbol();
            myFillSymbol.Style = Esri.ArcGISRuntime.Symbology.SimpleFillStyle.Null;
            Esri.ArcGISRuntime.Symbology.SimpleLineSymbol myOutline = new Esri.ArcGISRuntime.Symbology.SimpleLineSymbol();
            myOutline.Color = System.Windows.Media.Colors.Black;
            myOutline.Style = Esri.ArcGISRuntime.Symbology.SimpleLineStyle.Solid;
            myOutline.Width = 10;
            myFillSymbol.Outline = myOutline;

            // Create a new graphic and set it's geometry and symbol. 
            Esri.ArcGISRuntime.Layers.Graphic myGraphic = new Esri.ArcGISRuntime.Layers.Graphic();
            myGraphic.Geometry = myPolygon;
            myGraphic.Symbol = myFillSymbol;

            // Add the graphic to the graphics collection. This will cause the graphic to draw in the map.
            MyPolygonGraphicsLayer.Graphics.Add(myGraphic);


            // Draw the 2nd polygon graphic in MapView1.
            // -----------------------------------------

            //Define a list of MapPoint's (the basic building blocks of a polygons shape).
            System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint> myListOfMapPoints2 = new System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint>();
            myListOfMapPoints2.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(3, 3));
            myListOfMapPoints2.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(5, 6));
            myListOfMapPoints2.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(7, 3));

            // Create a new Polygon geometry using the List of MapPoints in the defined SpatialReference as the map control. 
            Esri.ArcGISRuntime.Geometry.Polygon myPolygon2 = new Esri.ArcGISRuntime.Geometry.Polygon(myListOfMapPoints2, new Esri.ArcGISRuntime.Geometry.SpatialReference(102100));

            // Define a basic fill symbol for the polygon.
            Esri.ArcGISRuntime.Symbology.SimpleFillSymbol myFillSymbol2 = new Esri.ArcGISRuntime.Symbology.SimpleFillSymbol();
            myFillSymbol2.Style = Esri.ArcGISRuntime.Symbology.SimpleFillStyle.Null;
            Esri.ArcGISRuntime.Symbology.SimpleLineSymbol myOutline2 = new Esri.ArcGISRuntime.Symbology.SimpleLineSymbol();
            myOutline2.Color = System.Windows.Media.Colors.Red;
            myOutline2.Style = Esri.ArcGISRuntime.Symbology.SimpleLineStyle.Solid;
            myOutline2.Width = 2;
            myFillSymbol2.Outline = myOutline2;

            // Create a new graphic and set it's geometry and symbol. 
            Esri.ArcGISRuntime.Layers.Graphic myGraphic2 = new Esri.ArcGISRuntime.Layers.Graphic();
            myGraphic2.Geometry = myPolygon2;
            myGraphic2.Symbol = myFillSymbol2;

            // Add the graphic to the graphics collection. This will cause the graphic to draw in the map.
            MyPolygonGraphicsLayer.Graphics.Add(myGraphic2);

            DisplaySpatialRelationships();
        }

        private void Button_Shift_Up_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // Calls the function to move a polygon up in the Map.
            ShiftPolygon(1);
        }

        private void Button_Shift_Down_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // Calls the function to move a polygon down in the Map.
            ShiftPolygon(-1);
        }

        public void ShiftPolygon(double TheShiftAmount)
        {

            // A function to move a polygon up/down within the Map.

            // Get the GraphicCollection in the Map.
            Esri.ArcGISRuntime.Layers.GraphicCollection myGraphicCollection = MyPolygonGraphicsLayer.Graphics;

            // Get the second Graphic in the GraphicCollection. 
            Esri.ArcGISRuntime.Layers.Graphic myGraphic = myGraphicCollection[1];

            // Get the generic Geometry for the Graphic.
            Esri.ArcGISRuntime.Geometry.Geometry myGeometry = myGraphic.Geometry;

            // Get the Symbol for the Graphic.
            Esri.ArcGISRuntime.Symbology.SimpleFillSymbol mySimpleSymbolFill = (Esri.ArcGISRuntime.Symbology.SimpleFillSymbol)myGraphic.Symbol;

            // Remove the Graphic from the GraphicCollection.
            myGraphicCollection.RemoveAt(1);


            // Create a Polygon from Geometry of the Graphic that was in the GraphicCollection.
            Esri.ArcGISRuntime.Geometry.Polygon myPolygon2 = (Esri.ArcGISRuntime.Geometry.Polygon)myGeometry;

            // Get the PartCollection from the Polygon. 
            Esri.ArcGISRuntime.Geometry.ReadOnlyPartCollection myPartCollection2 = myPolygon2.Parts;

            // Create a new List Of MapPoint objects. 
            System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint> myListOfMapPoints2 = new System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint>();

            // Loop through each PartCollection
            for (var i = 0; i < myPartCollection2.Count; i++)
            {

                // Get the SegmentCollection from each PartCollection.
                Esri.ArcGISRuntime.Geometry.ReadOnlySegmentCollection oneSegmentCollection = myPartCollection2[i];

                // Loop through each SegmentCollection.
                for (var j = 0; j < oneSegmentCollection.Count; j++)
                {

                    // Get one Segment from the SegmentCollection.
                    Esri.ArcGISRuntime.Geometry.Segment oneSegment = oneSegmentCollection[j];

                    // Add a MapPoint to the SegmentCollection that is offset up/down by the shift amount so that the Polygon is in a different position in the Map.
                    myListOfMapPoints2.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(oneSegment.StartPoint.X, oneSegment.StartPoint.Y + TheShiftAmount));

                }

            }

            // Create a new Graphic. 
            Esri.ArcGISRuntime.Layers.Graphic myGraphic2 = new Esri.ArcGISRuntime.Layers.Graphic();

            // Create a new Polygon that is offset (i.e. moved up/down) from the one that was in the GraphicCollection. Set it's .Geometry and .Symbol.
            Esri.ArcGISRuntime.Geometry.Polygon myPolygon_Moved = new Esri.ArcGISRuntime.Geometry.Polygon(myListOfMapPoints2, new Esri.ArcGISRuntime.Geometry.SpatialReference(102100));
            myGraphic2.Geometry = myPolygon_Moved;
            myGraphic2.Symbol = mySimpleSymbolFill;

            // Add the new Graphic to the GraphicsCollection. This will cause the graphic to draw in the map.
            MyPolygonGraphicsLayer.Graphics.Add(myGraphic2);

            // Call the custom function that will display the various GeometryEngine spatial relationship tests.
            DisplaySpatialRelationships();

        }

        public void DisplaySpatialRelationships()
        {

            // Simple function to display the results of various GeometryEngine spatial relationship tests in a TextBox.

            // Get the GraphicsCollection from the GraphicsLayer.
            Esri.ArcGISRuntime.Layers.GraphicCollection myGraphicCollection = MyPolygonGraphicsLayer.Graphics;

            // Get the 1st Graphic in the GraphicsCollection and it's Geometry.
            Esri.ArcGISRuntime.Layers.Graphic Graphic1 = myGraphicCollection[0];
            Esri.ArcGISRuntime.Geometry.Geometry myGeometry1 = Graphic1.Geometry;

            // Get the 2nd Graphic in the GraphicsCollection and it's Geometry.
            Esri.ArcGISRuntime.Layers.Graphic Graphic2 = myGraphicCollection[1];
            Esri.ArcGISRuntime.Geometry.Geometry myGeometry2 = Graphic2.Geometry;

            // Create a new StringBuilder object to hold the results of the various GeomertyEngine spatial relationship tests.
            System.Text.StringBuilder myStringBuilder = new System.Text.StringBuilder();

            // Run each of the GeometryEngine spatial relationship tests and append the text version of the boolean to the StringBuilder.
            myStringBuilder.AppendLine("Geometry1 CONTAINS Geometry2 = " + Esri.ArcGISRuntime.Geometry.GeometryEngine.Contains(myGeometry1, myGeometry2).ToString());
            myStringBuilder.AppendLine("Geometry1 CROSSES Geometry2 = " + Esri.ArcGISRuntime.Geometry.GeometryEngine.Crosses(myGeometry1, myGeometry2).ToString());
            myStringBuilder.AppendLine("Geometry1 DISJOINT Geometry2 = " + Esri.ArcGISRuntime.Geometry.GeometryEngine.Disjoint(myGeometry1, myGeometry2).ToString());
            myStringBuilder.AppendLine("Geometry1 EQUALS Geometry2 = " + Esri.ArcGISRuntime.Geometry.GeometryEngine.Equals(myGeometry1, myGeometry2).ToString());
            myStringBuilder.AppendLine("Geometry1 INTERSECTS Geometry2 = " + Esri.ArcGISRuntime.Geometry.GeometryEngine.Intersects(myGeometry1, myGeometry2).ToString());
            myStringBuilder.AppendLine("Geometry1 OVERLAPS Geometry2 = " + Esri.ArcGISRuntime.Geometry.GeometryEngine.Overlaps(myGeometry1, myGeometry2).ToString());
            myStringBuilder.AppendLine("Geometry1 TOUCHES Geometry2 = " + Esri.ArcGISRuntime.Geometry.GeometryEngine.Touches(myGeometry1, myGeometry2).ToString());
            myStringBuilder.AppendLine("Geometry1 WITHIN Geometry2 = " + Esri.ArcGISRuntime.Geometry.GeometryEngine.Within(myGeometry1, myGeometry2).ToString());

            // Display the text of the spatial relationship tests back to the user.
            TextBox_Results.Text = myStringBuilder.ToString();

        }
    }
}