Select to view content in your preferred language

Identify & Query Tasks in one

1979
11
02-22-2011 11:48 AM
TylerMunn
Emerging Contributor
I currently have a map service that allows the user to click the map, and any visible feature will be selected, and added to a ComboBox using an Identity Task based on the mouse click point.

I now need to modify the code so that any visible feature which touches any of the selected features, will also become selected and added to the combobox.

My initial thought was to mimic the buffer query http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#BufferQuery and have any visible feature which touches the graphics layer become selected itself. How would I go about adding the additional features selected from the Query Task into IdentifyResults? I've pasted the code for my identify task, as well as the code that populates the combobox.

 public void ShowFeatures(List<IdentifyResult> results)
        {
            _dataItems = new List<DataItem>();

            if (results != null && results.Count > 0)
            {
                IdentifyComboBox.Items.Clear();
                foreach (IdentifyResult result in results)
                {
                    Graphic feature = result.Feature;
                    string title = result.Value.ToString() + " (" + result.LayerName + ")";
                    _dataItems.Add(new DataItem()
                    {
                        Title = title,
                        Data = feature.Attributes
                    });
                    IdentifyComboBox.Items.Add(title);

                }

                // Workaround for bug with ComboBox 
                IdentifyComboBox.UpdateLayout();

                IdentifyComboBox.SelectedIndex = 0;
            }

            IdentifyDetailsDataGrid.IsEnabled = false;
        }


 private void IdentifyTask_ExecuteCompleted(object sender, IdentifyEventArgs args)
        {
            IdentifyDetailsDataGrid.ItemsSource = null;


            if (args.IdentifyResults != null && args.IdentifyResults.Count > 0)
            {
                IdentifyResultsPanel.Visibility = Visibility.Visible;

                ShowFeatures(args.IdentifyResults);

            }
            else
            {
                IdentifyComboBox.Items.Clear();
                IdentifyComboBox.UpdateLayout();

                //IdentifyResultsPanel.Visibility = Visibility.Collapsed;
            }

            //test to colour clicked layers
            GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer;
            graphicsLayer.ClearGraphics();
         

            if (args.IdentifyResults.Count > 0)
            {
                foreach (IdentifyResult result in args.IdentifyResults)
                {
                    Graphic graphic = result.Feature;

                    switch (graphic.Attributes["Shape"].ToString())
                    {

                        case "Polygon":
                            graphic.Symbol = DefaultFillSymbol;
                            break;

                        case "Polyline":
                            graphic.Symbol = DefaultLineSymbol;
                            break;

                        case "Point":
                            graphic.Symbol = DefaultMarkerSymbol;
                            break;

                    }

                    graphicsLayer.Graphics.Add(result.Feature);

                }
            }
            else
            {
               // MessageBox.Show("Found " + args.IdentifyResults.Count + " Features");
            }
            
        }



Thanks for any help, I think my logic is correct but I'm not sure the best way to get there. Can I simply run something like ShowFeatures(args.QueryResults); for the additional selected features?
0 Kudos
11 Replies
JenniferNery
Esri Regular Contributor
IdentifyTask will give you features of varying geometry type. I think in Identify.ExecuteCompleted event handler you should be able to queue up features to buffer in a GraphicCollection so that you perform a BufferAsync on each geometry type.

In this sample, bp is BufferParameters, gm is GeometryService.
GraphicCollection toBuffer = new GraphicCollection();
void it_ExecuteCompleted(object sender, IdentifyEventArgs e)
{
 bp.Features.Clear();
 toBuffer.Clear();
 foreach (var result in e.IdentifyResults)
 {
  if (bp.Features.Count == 0 || bp.Features[0].Geometry.GetType() == result.Feature.Geometry.GetType())
   bp.Features.Add(result.Feature);
  else
   toBuffer.Add(result.Feature);
 }
 gm.BufferAsync(bp);
}

void gm_BufferCompleted(object sender, GraphicsEventArgs e)
{
 GraphicsLayer layer = this.MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer;
 foreach(var result in e.Results)
 {
  layer.Graphics.Add(new Graphic()
  {
   Geometry = result.Geometry,
   Symbol = this.LayoutRoot.Resources["RedFillSymbol"] as Symbol
  });
 }

 if (toBuffer.Count > 0)
 {
  bp.Features.Clear();    
  foreach (var g in toBuffer)
  {
   if (bp.Features.Count == 0 || bp.Features[0].Geometry.GetType() == g.Geometry.GetType())
    bp.Features.Add(g);
  }
  foreach (var g in bp.Features)
   toBuffer.Remove(g);
  gm.BufferAsync(bp);
 }
}
0 Kudos
TylerMunn
Emerging Contributor
Thanks Jennifer.

I'm playing with the code you've provided - For whatever reason I am not able to add e after IdentifyEventArgs And GraphicsEventsArgs, can I just use args.IdentifyResults and args.Results instead?

And curious where I am supposed to put the code for  -

GraphicCollection toBuffer = new GraphicCollection();


as well my buffer parameters
BufferParameters bp = new BufferParameters()
        {
            Unit = LinearUnit.Meter,
            BufferSpatialReference = new SpatialReference(4326),
            OutSpatialReference = MyMap.SpatialReference,
            UnionResults = true
        };


and declaring the geometry service
GeometryService gm=
                        new GeometryService("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
                    gm.BufferCompleted += GeometryService_BufferCompleted;
                    gm.Failed += GeometryService_Failed;


Thanks again...I'm somewhat new to this and having some trouble trying to modify my existing code. Fun fun!
0 Kudos