Select to view content in your preferred language

Identify & Query Tasks in one

1968
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
You can probably use Intersect() see this sample: http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#Intersect

The MouseClick will get you the feature you will use to find if it intersects other features. You can then use the result of this intersection as you wish for your Identify.
0 Kudos
TylerMunn
Emerging Contributor
Thanks Jennifer, I should be able to adapt my code.

Question though - It looks like that uses a GeometryService, is it possible to have a Secure GeometryService? Currently I am using one for a distance measurement tool, and it always asks if I want to Display Mixed Content. I checked around when creating the Service but could not seem to create a secured one.

I know my users can tolerate that message as they rarely measure distances, but it is not going to fly if every time they run the application they are forced to deal with this message box popping up when they select something on the map.

Any idea how to deal with the above if I cannot create a secure geometry service? Thanks.
0 Kudos
JenniferNery
Esri Regular Contributor
Geometry service can be secured the same way map services are secured

You can refer to the following help doc from ArcGIS Server team: http://help.arcgis.com/en/arcgisserver/10.0/help/arcgis_server_dotnet_help/index.html#//0093000000pz....
0 Kudos
TylerMunn
Emerging Contributor
Thanks Jennifer.

I created an https directory, and set the appropriate parameters. For some reason, when using my geometry service vs the one on the ESRI sample site, I'm getting much different measurement results.

I simply changed my code to reference the new Geometry Service, and it doesnt look like there are any settings on my Geometry Service which would affect the measure results...any ideas?
0 Kudos
JenniferNery
Esri Regular Contributor
I found only this documentation about publishing your own Geometry Service: http://help.arcgis.com/en/arcgisserver/10.0/help/arcgis_server_dotnet_help/index.html#//009300000027...

You might get better answer from ArcGIS Server forum: http://forums.arcgis.com/forums/9-ArcGIS-Server-.NET
0 Kudos
TylerMunn
Emerging Contributor
Thanks again.

So I'm tackling the programming finally and this is how I see it working - please let me know if something does not make sense, I'm hoping to make sure my logic works before I spend too much time on it.

1 - Identity Task to get all mapped features at click point (points, lines, polygons in any layer that is visible)
2 - For Each Identify Result, buffer 1 metre and union together (we want to know of any intersecting features to the originally selected features)
3 - Query/Select/Identify all visible features that intersect the buffer (Can I have 2 identify tasks?)
4 - Add those features to my dropdown & add to graphics layer
0 Kudos
JenniferNery
Esri Regular Contributor
I think this approach sound like a feasible solution. For 1 and 3, you may use the same IdentifyTask with different IdentifyParameters. You can use the same ExecuteCompleted event handler too and distinguish which operation to do based on the UserToken  http://help.arcgis.com/en/webapi/silverlight/apiref/ESRI.ArcGIS.Client~ESRI.ArcGIS.Client.Tasks.Iden...

You might also want to look at Relation. This does not allow mixed type of geometries though.
Sample:
http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#Relation
Documentation:
http://help.arcgis.com/en/webapi/silverlight/apiref/ESRI.ArcGIS.Client~ESRI.ArcGIS.Client.Tasks.Geom...
0 Kudos
TylerMunn
Emerging Contributor
I'm having a bit of an issue passing the graphics from my Identity Task to GeometryService_BufferCompleted. I'm guessing I might not have my BufferParameters in the right spot? I've spent a few hours trying to figure it out, but no luck yet. Also, I will be potentially buffering points/lines/polygons - do I need to make any changes for this?

I realize that each time it goes through the loop, a feature will be buffered. There will generally only be 4-5 selected at a time maximum so processing time shouldnt be an issue. Will this be an issue with unioning my buffer results? Ultimately I want a single unioned buffer polygon which I can use later on.


private void IdentifyTask_ExecuteCompleted(object sender, IdentifyEventArgs args)
        {
            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;

                    }

                    GeometryService geometryServiceSSL =
                        new GeometryService("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
                    geometryServiceSSL.BufferCompleted += GeometryService_BufferCompleted;
                    geometryServiceSSL.Failed += GeometryService_Failed;

                    graphic.SetZIndex(1);
                    graphicsLayer.Graphics.Add(graphic);

                    //test
                    // If buffer spatial reference is GCS and unit is linear, geometry service will do geodesic buffering
                    BufferParameters bufferParams = new BufferParameters()
                    {
                        Unit = LinearUnit.Meter,
                        BufferSpatialReference = new SpatialReference(4326),
                        OutSpatialReference = MyMap.SpatialReference,
                        UnionResults = true

                    };
                    bufferParams.Features.Add(graphic);
                    bufferParams.Distances.Add(5000);

                    geometryServiceSSL.BufferAsync(bufferParams);
                    //test
  
                }

            }
            else

            {
               //do nothing
            }

        }


Here is the code for my Buffer - no graphic features are being passed as I can see from results.count always being 0.
 
void GeometryService_BufferCompleted(object sender, GraphicsEventArgs args)
        {
            
            IList<Graphic> results = args.Results;
            GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer;

            //this tests to see if anything is carried over in results
            MessageBox.Show("count is " + args.Results.Count);

            foreach (Graphic graphic in results)
            {
                graphic.Symbol = DefaultFillSymbol;
                graphicsLayer.Graphics.Add(graphic);
            }
        }


Thanks for any ideas!

EDIT - I'm moving ahead temporarily and have set up different IdentifyParameters to base my 2nd Identify on the Buffered Polygon. How do I go about setting the Geometry of my new IdentifyParameters to the Buffered Polygon which I will have created?
0 Kudos
TylerMunn
Emerging Contributor
Well, after more playing around it looks like my point features were buffering fine all along, not lines or polygons however.
0 Kudos