Click or drag to resize
Code Example - PolygonFromScratch

Demonstrates creating a simple polygon, donut polygon, and multiple ring polygon via code-behind. An option to view coordinate information for each vertex in the polygons is provided.

Code Example
Polygon From Scratch

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="PolygonFromScratch.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>

        <!-- Add a StackPanel to define how UI elements will be placed. -->
        <StackPanel x:Name="StackPanel1" Orientation="Vertical">

            <!-- Add a MapView Control. -->
            <esri:MapView x:Name="MapView1" Height="525" Width="800" >

                <!-- Add a Map.-->
                <esri:Map >
                    <esri:GraphicsLayer x:Name="MyPolygonGraphicsLayer" />
                    <esri:GraphicsLayer x:Name="MyPolylineGraphicsLayer" />
                    <esri:GraphicsLayer x:Name="MyPointGraphicsLayer" />
                </esri:Map>
            </esri:MapView>

            <!-- Add another StackPanel for defining how UI elements will be placed. -->
            <StackPanel x:Name="StackPanel2" Orientation="Horizontal">

                <!-- Add several buttons to place various types of Polygons on the Map and a button to interrogate the geometry of the polygons. -->

                <Button x:Name="ButtonSimplePolygon" Content="Simple Polygon" Click="ButtonSimplePolygon_Click" Margin="3,3" FontSize="18" Foreground="Blue" FontWeight="Bold" />
                <Button x:Name="ButtonDonutPolygon" Content="Donut Polygon" Click="ButtonDonutPolygon_Click" Margin="3,3" FontSize="18" Foreground="Red" FontWeight="Bold"/>
                <Button x:Name="ButtonMultipartPolygon" Content="MultiPart Polygon" Click="ButtonMultipartPolygon_Click" Margin="3,3" FontSize="18" Foreground="Green" FontWeight="Bold"/>
                <Button x:Name="ButtonShowPolygonParts" Content="Show  Details for Last Graphic Added" Click="ButtonShowPolygonParts_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 "PolygonFromScratch.MainWindow" to be just "MainWindow".

// INSTRUCTIONS:
// Click the 'Simple Polygon' button to draw a simple polygon on the map. Then click the 'Show Details from Last Graphic Added' to see the 
// coordinate values that compose the polygon in MessageBoxes. Then click the 'Donut Polygon' button to draw a donut shaped polygon and then
// click the the 'Show Details from Last Graphic Added' to see the coordinate values that compose the polygon in MessageBoxes. Finally, 
// click the 'MultiPart Polygon' button to to draw a multi part complex polygon (i.e. like an island chain) and then click the the 'Show 
// Details Last from Graphic Added' to see the coordinate values that compose the polygon in MessageBoxes.

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

            // Define a fictitious initial extent.
            Esri.ArcGISRuntime.Geometry.Envelope myEnvelope = new Esri.ArcGISRuntime.Geometry.Envelope(0, 0, 15, 15);
            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;
        }


        private void ButtonSimplePolygon_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // This function will create a simple polygon and place it in the graphics layer that will display in the Map.

            //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(1, 5));
            myListOfMapPoints.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(1, 10));
            myListOfMapPoints.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(2, 10));
            myListOfMapPoints.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(2, 5));

            // 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.Color = System.Windows.Media.Colors.Blue;
            myFillSymbol.Style = Esri.ArcGISRuntime.Symbology.SimpleFillStyle.Solid;

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

        private void ButtonDonutPolygon_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // This function will create polygon with a hole in it (i.e. a donut shape) and place it in the graphics layer that will display in the Map.

            // Define a List of MapPoint's to house the outer ring (i.e. exterior) of the polygon. 
            System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint> myCoordinateCollectionExteriorRing = new System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint>();
            myCoordinateCollectionExteriorRing.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(5, 5));
            myCoordinateCollectionExteriorRing.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(5, 10));
            myCoordinateCollectionExteriorRing.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(10, 10));
            myCoordinateCollectionExteriorRing.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(10, 5));

            // Define a List of MapPoint's to house the inner ring (i.e. interior) of the polygon. 
            System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint> myCoordinateCollectionInteriorRing = new System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint>();
            myCoordinateCollectionInteriorRing.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(6, 6));
            myCoordinateCollectionInteriorRing.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(9, 6));
            myCoordinateCollectionInteriorRing.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(9, 9));
            myCoordinateCollectionInteriorRing.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(6, 9));

            // Create a List of (List of MapPoint's) (i.e. a collection of rings). Add each List of MapPoint's (i.e. a single ring) to the 
            // List of (List of MapPoint's).
            System.Collections.Generic.List<System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint>> myRings = new System.Collections.Generic.List<System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint>>();
            myRings.Add(myCoordinateCollectionExteriorRing);
            myRings.Add(myCoordinateCollectionInteriorRing);

            // Define a polygon using the List of (List of MapPoint's) in the constructor.
            Esri.ArcGISRuntime.Geometry.Polygon myPolygon = new Esri.ArcGISRuntime.Geometry.Polygon(myRings);

            // Define a basic fill symbol for the polygon.
            Esri.ArcGISRuntime.Symbology.SimpleFillSymbol myFillSymbol = new Esri.ArcGISRuntime.Symbology.SimpleFillSymbol();
            myFillSymbol.Color = System.Windows.Media.Colors.Red;
            myFillSymbol.Style = Esri.ArcGISRuntime.Symbology.SimpleFillStyle.Solid;

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

        private void ButtonMultipartPolygon_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // This function will create polygon with multiple parts (a good use case would be a chain of islands like Hawaii) and place 
            // it in the graphics layer that will display in the Map.

            // Define a List of MapPoint's to house the first ring of the polygon). 
            System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint> myListOfMapPointsPart1 = new System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint>();
            myListOfMapPointsPart1.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(12, 3));
            myListOfMapPointsPart1.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(12, 5));
            myListOfMapPointsPart1.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(13, 5));
            myListOfMapPointsPart1.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(13, 3));

            // Define a List of MapPoint's to house the second ring of the polygon). 
            System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint> myListOfMapPointsPart2 = new System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint>();
            myListOfMapPointsPart2.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(12, 7));
            myListOfMapPointsPart2.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(12, 9));
            myListOfMapPointsPart2.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(13, 9));
            myListOfMapPointsPart2.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(13, 7));

            // Define a List of MapPoint's to house the third ring of the polygon).
            System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint> myListOfMapPointsPart3 = new System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint>();
            myListOfMapPointsPart3.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(12, 11));
            myListOfMapPointsPart3.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(12, 13));
            myListOfMapPointsPart3.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(13, 13));
            myListOfMapPointsPart3.Add(new Esri.ArcGISRuntime.Geometry.MapPoint(13, 11));

            // Create a List of (List of MapPoint's) (i.e. a collection of rings). Add each individual List of MapPoint's (single ring) to the 
            // List of (List of MapPoint's).
            System.Collections.Generic.List<System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint>> myRings = new System.Collections.Generic.List<System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.MapPoint>>();
            myRings.Add(myListOfMapPointsPart1);
            myRings.Add(myListOfMapPointsPart2);
            myRings.Add(myListOfMapPointsPart3);

            // Define a polygon using the List of (List of MapPoint's) in the constructor.
            Esri.ArcGISRuntime.Geometry.Polygon myPolygon = new Esri.ArcGISRuntime.Geometry.Polygon(myRings);

            // Define a basic fill symbol for the polygon.
            Esri.ArcGISRuntime.Symbology.SimpleFillSymbol myFillSymbol = new Esri.ArcGISRuntime.Symbology.SimpleFillSymbol();
            myFillSymbol.Color = System.Windows.Media.Colors.Green;
            myFillSymbol.Style = Esri.ArcGISRuntime.Symbology.SimpleFillStyle.Solid;

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

        private void ButtonShowPolygonParts_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            // This function will get the last graphic drawn in the map and display back to the user the parts (i.e. Segments and MapPoints) that makes
            // up the polygon. 

            // Get the graphics collection from the graphics layer that was defined in XAML.
            Esri.ArcGISRuntime.Layers.GraphicCollection myGraphicCollection = MyPolygonGraphicsLayer.Graphics;

            // If there is at least one graphic in the graphics collection then proceed. 
            if (myGraphicCollection.Count > 0)
            {
                // Get the last graphic in the graphics collection.
                Esri.ArcGISRuntime.Layers.Graphic myLastGraphic = myGraphicCollection[myGraphicCollection.Count - 1];

                // Obtain the geometry from the graphic. 
                Esri.ArcGISRuntime.Geometry.Polygon myGeometry = (Esri.ArcGISRuntime.Geometry.Polygon)myLastGraphic.Geometry;

                // Get the PartCollection from the polygon geometry.
                Esri.ArcGISRuntime.Geometry.ReadOnlyPartCollection myPartCollection = myGeometry.Parts;

                // Loop through each PartCollection
                for (var i = 0; i < myPartCollection.Count; i++)
                {
                    // Get the SegmentCollection from one PartCollection.
                    Esri.ArcGISRuntime.Geometry.ReadOnlySegmentCollection oneSegmentCollection = myPartCollection[i];

                    // Loop through each SegmentCollection. 
                    for (var j = 0; j < oneSegmentCollection.Count; j++)
                    {
                        // Create a string builder to display an information string to the user.
                        System.Text.StringBuilder myStringBuilder = new System.Text.StringBuilder();

                        // Display the Part (aka. ring) index value in the PartCollection.
                        myStringBuilder.AppendLine("PartCollection (aka. ring): " + i.ToString());

                        // Display the Segment index value is in the PartCollection. 
                        myStringBuilder.AppendLine("Segment: " + j.ToString());

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

                        // Display the X,Y information for the StartPoint and EndPoint in the Segment.
                        myStringBuilder.AppendLine("(StartPoint) X: " + oneSegment.StartPoint.X.ToString() + ", Y: " + oneSegment.StartPoint.Y.ToString());
                        myStringBuilder.AppendLine("(EndPoint) X: " + oneSegment.EndPoint.X.ToString() + ", Y: " + oneSegment.EndPoint.Y.ToString());

                        // Present the results to the user.
                        System.Windows.MessageBox.Show(myStringBuilder.ToString());


                        // Display the Segments that define the Polygons visually. 
                        Esri.ArcGISRuntime.Layers.Graphic myPolylineGraphic = new Esri.ArcGISRuntime.Layers.Graphic();
                        System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.LineSegment> myLineSegments = new System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.LineSegment>();
                        myLineSegments.Add(new Esri.ArcGISRuntime.Geometry.LineSegment(oneSegment.StartPoint, oneSegment.EndPoint));
                        myPolylineGraphic.Geometry = new Esri.ArcGISRuntime.Geometry.Polyline(myLineSegments);
                        Esri.ArcGISRuntime.Symbology.SimpleLineSymbol mySimpleLineSymbol = new Esri.ArcGISRuntime.Symbology.SimpleLineSymbol();
                        mySimpleLineSymbol.Color = System.Windows.Media.Colors.Yellow;
                        mySimpleLineSymbol.Width = 3;
                        myPolylineGraphic.Symbol = mySimpleLineSymbol;
                        MyPolylineGraphicsLayer.Graphics.Add(myPolylineGraphic);

                        // Display the MapPoints that define the Segments visually. 
                        Esri.ArcGISRuntime.Layers.Graphic myPointGraphic = new Esri.ArcGISRuntime.Layers.Graphic();
                        myPointGraphic.Geometry = oneSegment.StartPoint;
                        Esri.ArcGISRuntime.Symbology.SimpleMarkerSymbol mySimpleMarkerSymbol = new Esri.ArcGISRuntime.Symbology.SimpleMarkerSymbol();
                        mySimpleMarkerSymbol.Color = System.Windows.Media.Colors.Black;
                        myPointGraphic.Symbol = mySimpleMarkerSymbol;
                        MyPointGraphicsLayer.Graphics.Add(myPointGraphic);
                    }
                }
            }
        }
    }
}