Click or drag to resize
Code Example - GeometryEngine_ConvexHull

Demonstrates using the powerful GeometryEngine local process to generate a convex hull graphic polygon based upon user specified mouse-clicks/taps on the map.

Code Example
Geometry Engine Convex Hull

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.

<Window x:Class="GeometryEngine_ConvexHull.MainWindow"
        Title="MainWindow" Height="600" Width="800">

    <Grid x:Name="layoutGrid">

        <!-- Define a SimpleMarkerSymbol and SimpleFillSymbol in the Grid Resources. -->

            <!-- A red point, size 6.-->
            <esri:SimpleMarkerSymbol x:Key="PointSymbol" Color="Red" Size="6" />

            <!-- A semi transparent blue fill, with blue border, thickness of 2. -->
            <esri:SimpleFillSymbol x:Key="ConvexHullSymbol" Color="#660000FF" Style="Solid">
                    <esri:SimpleLineSymbol Color="Blue" Width="2" />

        <!-- Add a MapView. -->
        <esri:MapView x:Name="MapView1" WrapAround="True">

            <!-- Add a Map. -->
            <esri:Map x:Name="Map1">

                <!-- Add a backdrop ArcGISTiledMapServiceLayer. -->
                    ServiceUri="" />

                <!-- GraphicsLayer to hold the points the user clicks on the map. -->
                <esri:GraphicsLayer x:Name="myGraphicsLayer_UserInputPoints"/>

                <!-- GraphicsLayer to hold the polygon from the GeometryEngine.ConvexHull operation. -->
                <esri:GraphicsLayer x:Name="myGraphicsLayer_ConvexHullPolygon"/>


        <!-- Add instructions on how to use the example code. Include a button to click when 3 or more points have been added to define the ConvexHull. -->
        <Border Background="White" BorderBrush="Black" BorderThickness="2" Margin="5" HorizontalAlignment="Right" VerticalAlignment="Bottom">
            <StackPanel Margin="3,3">
                <TextBlock Text="Add three or more points on the map and click the 'Generate Convex Hull' button. A polygon containing all the points entered will be returned."
                           Width="400" TextAlignment="Left" TextWrapping="Wrap" />
                <Button x:Name="btnConvexHull" Content="Generate Convex Hull" Margin="3,3,3,3" HorizontalAlignment="Center" IsEnabled="False"
                        Click="ConvexHullButton_Click" />


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_ConvexHull.MainWindow" to be just "MainWindow".

using System.Linq;

namespace GeometryEngine_ConvexHull
    public partial class MainWindow : System.Windows.Window
        public MainWindow()

            // Set the initial extent (via the InitialViewpoint Property) to that of the continental US 
            Esri.ArcGISRuntime.Geometry.Envelope myEnvelope = new Esri.ArcGISRuntime.Geometry.Envelope(-15000000, 2000000, -7000000, 8000000);
            MapView1.Map.InitialViewpoint = new Esri.ArcGISRuntime.Controls.Viewpoint(myEnvelope);

            // Call the routine to allow the user to add point graphics to the map.

        private async void DrawPoints()
            // The routine continuously accepts new points from the user.

                // Wait for all of the layers in the map to have loaded before the user can add any points.
                await MapView1.LayersLoadedAsync();

                // Continuously let the user add points assuming that layers have loaded in the map, thus setting the MapView Extent.
                while (MapView1.Extent != null)
                    // Get a MapPoint from the MapView via the Editor.
                    Esri.ArcGISRuntime.Controls.Editor myEditor = MapView1.Editor;
                    Esri.ArcGISRuntime.Geometry.MapPoint myMapPoint = await myEditor.RequestPointAsync();

                    // Reset graphics layers if we've already created a convex hull polygon.
                    if (myGraphicsLayer_ConvexHullPolygon.Graphics.Count > 0)

                    // Get point symbol defined in XAML for the user input point graphics and apply it to the graphic being added to the graphics layer.
                    Esri.ArcGISRuntime.Symbology.Symbol myPointSymbol = (Esri.ArcGISRuntime.Symbology.Symbol)(layoutGrid.Resources["PointSymbol"]);
                    myGraphicsLayer_UserInputPoints.Graphics.Add(new Esri.ArcGISRuntime.Layers.Graphic(myMapPoint, myPointSymbol));

                    // If we have more than 3 graphics added by the user, enable the button to create the convex hull polygon.
                    if (myGraphicsLayer_UserInputPoints.Graphics.Count > 2)
                        btnConvexHull.IsEnabled = true;
            catch (System.Threading.Tasks.TaskCanceledException)
                // Do nothing if this error occurs.
            catch (System.Exception ex)
                // Display error message if there as a problem adding points to the graphics layer.
                System.Windows.MessageBox.Show("Error adding points: " + ex.Message, "Convex Hull Sample");

        // Creates a convex hull polygon from the input point graphics
        private void ConvexHullButton_Click(object sender, System.Windows.RoutedEventArgs e)
                // Create a list to hold geometries from the user input point graphics. NOTE: List make use of IEnumerable
                System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.Geometry> myList = new System.Collections.Generic.List<Esri.ArcGISRuntime.Geometry.Geometry>();

                // --------------------------------------------------------------------------------------------------------------------------
                // Version 1: long form

                // Loop through each point graphic in the graphics layer and add it's geometry to the list.
                foreach (Esri.ArcGISRuntime.Layers.Graphic oneGraphic in myGraphicsLayer_UserInputPoints.Graphics)

                // Get the polygon from the GeometryEngine ConvexHull operation.
                Esri.ArcGISRuntime.Geometry.Geometry myConvexHull = Esri.ArcGISRuntime.Geometry.GeometryEngine.ConvexHull(myList);

                // --------------------------------------------------------------------------------------------------------------------------

                // Version 2: short form using LINQ

                // Get the polygon from the GeometryEngine ConvexHull operation.
                //var myConvexHull = Esri.ArcGISRuntime.Geometry.GeometryEngine.ConvexHull(myGraphicsLayer_UserInputPoints.Graphics.Select(g => g.Geometry));

                // --------------------------------------------------------------------------------------------------------------------------

                // Get polygon symbol defined in XAML and apply it to the convex hull graphic being added to the graphics layer.
                Esri.ArcGISRuntime.Symbology.Symbol myPolygonSymbol = (Esri.ArcGISRuntime.Symbology.Symbol)(layoutGrid.Resources["ConvexHullSymbol"]);
                myGraphicsLayer_ConvexHullPolygon.Graphics.Add(new Esri.ArcGISRuntime.Layers.Graphic(myConvexHull, myPolygonSymbol));

                // Disable clicking the button again until the user adds at least 3 new points.
                btnConvexHull.IsEnabled = false;
            catch (System.Exception ex)
                // Display error message if there as a problem generating the convex hull polygon..
                System.Windows.MessageBox.Show("Error calculating convex hull: " + ex.Message, "Convex Hull Sample");