Determine points that are under a sketchOverlay in a map

659
1
01-22-2019 04:53 PM
RichardRolston
New Contributor II

I have a map which has a GraphicsOverlay with various points. I have given the user the ability to select a subset of the points by drawing a polygon using the SketchEditor. How can I determine which points have been selected?

Here is a subset of the code to set up the map:

var symbolLow = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle.Circle, Colors.Green, 10d);

private GraphicsOverlay graphicsOverlayLow = new GraphicsOverlay()
{ Renderer = new SimpleRenderer(symbolLow) };  

foreach (var graphic in graphicListLow)  // graphicListLow is a List of Points    
     graphicsOverlayLow.Graphics.Add(graphic);

MyMapView.GraphicsOverlays = new GraphicsOverlayCollection(); 

MyMapView.GraphicsOverlays.Add(graphicsOverlayLow); 

 // Graphics overlay to host sketch graphics 
private GraphicsOverlay _sketchOverlay = new GraphicsOverlay();
MyMapView.GraphicsOverlays.Add(_sketchOverlay);

I have two buttons, one for starting the drawing of the polygon and one to click when done (this follows the esri example for the SketchEditor). The code for starting is as follows:

private async void SelectButton_Click(object sender, RoutedEventArgs e)
{
     try
     { 
        // Let the user draw on the map view using the chosen sketch mode 
        SketchCreationMode creationMode = SketchCreationMode.Polygon; 
        Esri.ArcGISRuntime.Geometry.Geometry geometry = await MyMapView.SketchEditor.StartAsync(creationMode, true);
          // Create and add a graphic from the geometry the user drew         
         Graphic graphic = CreateGraphic(geometry);
         _sketchOverlay.Graphics.Add(graphic);
     }     
     catch (TaskCanceledException)
     {         
        // Ignore ... let the user cancel drawing 
     }     
     catch (Exception ex) 
     {         
        // Report exceptions         
         MessageBox.Show("Error drawing graphic shape: " + ex.Message);
     } 
} 

private Graphic CreateGraphic(Esri.ArcGISRuntime.Geometry.Geometry geometry)
{     
    // Create a graphic to display the specified geometry     
    Symbol symbol = null;     
    switch (geometry.GeometryType)  
    {         
         // Symbolize with a fill symbol        
         case GeometryType.Envelope:  
         case GeometryType.Polygon:
         {                 
              symbol = new SimpleFillSymbol() 
                {                    
                  Color = Colors.Red,                     
                  Style = SimpleFillSymbolStyle.Solid,          
                };               
               break;            
        }

Here is the handler for the routine that is called when the user clicks the button signaling that they are done drawing the polygon. This is where I want to determine which points have been selected.

private void CompleteButton_Click(object sender, RoutedEventArgs e)
{     
    // Cancel execution of the sketch task if it is already active
    if (MyMapView.SketchEditor.CancelCommand.CanExecute(null))
    {         
        MyMapView.SketchEditor.CancelCommand.Execute(null);
    } 
}

Note that I am using the 100.4 SDK for WPF.

0 Kudos
1 Reply
JenniferNery
Esri Regular Contributor

You can use GeometryEngine.Intersects method to decide whether graphic needs to be selected. 

For example, in code below. GraphicsOverlay contain points and a polygon geometry is used for selection. Once point graphics are available, draw polygon (double-tap to complete draw), then mark graphic as selected based on return value of GeometryEngine.Intersects method. Geometries might need to be in the same SpatialReference, so you might need to use GeometryEngine.Project.

    MyMapView.Map = new Map(SpatialReferences.Wgs84);
    MyMapView.SpatialReferenceChanged += async (s, e) =>
      {
          var geometry = await MyMapView.SketchEditor.StartAsync(SketchCreationMode.Polygon, false);
          var overlay = MyMapView.GraphicsOverlays.FirstOrDefault();
          if (overlay != null)
          {
              foreach (var g in overlay.Graphics)
              {
                  g.IsSelected = GeometryEngine.Intersects(g.Geometry, geometry);
              }
          }
      };
    MyMapView.GraphicsOverlays.Add(new GraphicsOverlay() { Renderer = new SimpleRenderer(new SimpleMarkerSymbol(SimpleMarkerSymbolStyle.Circle, Color.Yellow, 12d)) });
    AddRandomGraphics();
}
private void AddRandomGraphics()
{
    var random = new Random();
    var overlay = MyMapView.GraphicsOverlays.FirstOrDefault();
    if (overlay != null)
    {
        for (int i = 0; i < 10; i++)
        {
            var mp = new MapPoint(random.Next(-180, 180), random.Next(-90, 90), SpatialReferences.Wgs84);
            overlay.Graphics.Add(new Graphic(mp));
        }
    }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos