IdentifyTask and Multiple map services

3321
14
02-17-2011 10:06 AM
AngelGonzalez
Occasional Contributor II
How would you go about using the IdentifyTasK with multiple map service? Sample code wouild be appreciate.
0 Kudos
14 Replies
JenniferNery
Esri Regular Contributor
You can refer and modify this sample: http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#Identify

You can extend the scope of identifyTask by making it a private member of the class and subscribe to its ExecuteCompleted and Failed events upfront. You can also create a Stack or Queue of the map services Url.

identifyTask = new IdentifyTask();
identifyTask.ExecuteCompleted += IdentifyTask_ExecuteCompleted;
identifyTask.Failed += IdentifyTask_Failed;   
mapServices = new Stack<string>();
UpdateMapServices(); //TODO: push or enqueue map service URL's


In the MouseClick, you can simply update the Url property of IdentifyTask and then pass identifyParams as UserState to your IdentifyTask so you can re-use it for the other map services.
 identifyTask.Url = mapServices.Pop();
 identifyTask.ExecuteAsync(identifyParams, identifyParams);


In the ExecuteCompleted, you can call the succeeding Execute this way:
if (mapServices.Count == 0)
 UpdateMapServices(); //to re-add the map services for the next click event
else
{
 identifyTask.Url = mapServices.Pop();
 IdentifyParameters identifyParams = args.UserState as IdentifyParameters;
 identifyTask.ExecuteAsync(identifyParams, identifyParams );
}


Your task then is to update the UIElement. Notice that ShowFeatures() clears _dataItems and IdentifyComboBox so everytime new result comes back, the IdentifyResultGrid is cleared. You need to change this so that it can display results from all services.
0 Kudos
DominiqueBroux
Esri Frequent Contributor
0 Kudos
AngelGonzalez
Occasional Contributor II
Jennifer & Dominique,

I used a combination of both codes to dynamically get my map services and populate the comboBox with the results.

Thanks for your help!
0 Kudos
TobinCrain
New Contributor
angelg, can you expand on what you did to make this work?

Or Jennifer, can you help me out?  I am also trying to identify from a dynamic service and a couple of tiled services.  I could really use a little more detail in you explanation.

Thanks,
Tobin
0 Kudos
AngelGonzalez
Occasional Contributor II
I basically started out with Identify on ESRI sample site, see second posting for link
On my site I have an Identify button that the user clicks to turn identify on and off. Using the code that Jennifer supplied I modified it as follows:

namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        // Used by Identify
        private List<DataItem> _dataItems = null;
        bool IdentifyButtonClicked = false;
        private bool _needReset = true;                 //***
        bool IdentifyResultsPanelVisible = false;
        private IdentifyTask identifyTask = new IdentifyTask();
        public Stack<string> myMapService = new Stack<string>();
...
 


In the public MainPage I added the event handler:

public MainPage()
        {
            InitializeComponent();
            
            identifyTask.ExecuteCompleted +=new EventHandler<IdentifyEventArgs>(identifyTask_ExecuteCompleted);
            identifyTask.Failed +=new EventHandler<TaskFailedEventArgs>(identifyTask_Failed);

            UpdateMapServices();                //** This finds all dynamic map services I am using
        }



UpdateMapServices: Defines all dynamic map services that I am using
 //** Used by Identify 
        private void UpdateMapServices()
        {
            Stack<string> myTempStack = new Stack<string>();

            foreach (Layer layer in MyMap.Layers)
            {
                ArcGISDynamicMapServiceLayer dynamicLayer = layer as ArcGISDynamicMapServiceLayer;
                if (dynamicLayer != null)
                {
                    myTempStack.Push(dynamicLayer.Url.ToString());
                }
            }

            // Reverse stack order to reflect layers as drawn
            while (myTempStack.Count != 0)
            {
                myMapService.Push(myTempStack.Pop().ToString());
            }

        }


The MouseClick had been modified as follows:
 private void QueryPoint_MouseClick(object sender, Map.MouseEventArgs e)
        {

            if (IdentifyButtonClicked == true)   //*** Used by my IdentifyButton
            {
                if (IdentifyResultsPanelVisible)
                {
                    IdentifyResultsPanel.Visibility = Visibility.Collapsed;
                }

                MapPoint clickPoint = e.MapPoint;

                IdentifyParameters identifyParams = new IdentifyParameters()
                {
                    Geometry = clickPoint,
                    Tolerance = 20,
                    MapExtent = MyMap.Extent,
                    Width = (int)MyMap.ActualWidth,
                    Height = (int)MyMap.ActualHeight,
                    LayerOption = LayerOption.all,
                    SpatialReference = MyMap.SpatialReference
                };

                identifyTask.Url = myMapService.Pop();

                identifyTask.ExecuteAsync(identifyParams, identifyParams);

                MyMap.Cursor = Cursors.Wait;
               
                //  _needReset  is a flag used to determine if the user clicks on the map to a new  identify
                _needReset = true;              //***

                if (_needReset)                 //***
                {
                    GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer;
                    graphicsLayer.ClearGraphics();
                    ESRI.ArcGIS.Client.Graphic graphic = new ESRI.ArcGIS.Client.Graphic()
                    {
                        Geometry = clickPoint,
                        Symbol = MapRow.Resources["DefaultPictureSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol
                    };
                    graphicsLayer.Graphics.Add(graphic);
                }
            }

        }


Showfeature modified as follows:
public void ShowFeature(List<IdentifyResult> results)
        {
            // if true new identify is being requested, need to setup new list and clear identifyCombobox
            if (_needReset)                            {
                _dataItems = new List<DataItem>();
                IdentifyComboBox.Items.Clear();     //***
                _needReset = false;
            }
            
            if (results != null && results.Count > 0)
            {
                foreach (IdentifyResult result in results)
                {
                    Graphic feature = result.Feature;
                                                           
                    string tempLayerName = "(" + result.LayerName + ")";
                    
                    string title = tempLayerName.PadRight(20, ' ') +"|" + result.Value.ToString();// formatting
                    _dataItems.Add(new DataItem()
                    {
                        Title = title,
                        Data = feature.Attributes
                    });

                    IdentifyComboBox.Items.Add(title);
                }
                IdentifyComboBox.SelectedIndex = 0;
            }
        }


Once the IdentifyTask has been executed once(for the first dynamicMapService) you need to see if their is another dynamicMapservice
void identifyTask_ExecuteCompleted(object sender, IdentifyEventArgs e)
        {

            if (_needReset)           //If this is a new identify request then
            {
                IdentifyDetailDataGrid.ItemsSource = null;                  // clear datagrid
            }

            if (e.IdentifyResults != null && e.IdentifyResults.Count > 0)
            {
                ShowFeature(e.IdentifyResults);
            }
            else
            {
                IdentifyComboBox.Items.Clear();
                IdentifyComboBox.UpdateLayout();

                IdentifyResultsPanel.Visibility = Visibility.Collapsed;
                IdentifyResultsPanelVisible = false;
            }

            if (myMapService.Count == 0)                                 // once all map services had been identify then:
            {
                UpdateMapServices();                                        // re-populate the stack
                MyMap.Cursor = Cursors.Stylus;                              // set stylus
                IdentifyResultsPanel.Visibility = Visibility.Visible;       // show result panel
                IdentifyResultsPanelVisible = true;                         // set flag to true
            }
            else
            {
                identifyTask.Url = myMapService.Pop();                                      // get next dynamicMapService url for identify
                IdentifyParameters identifyParams = e.UserState as IdentifyParameters;      // pass in userstate
                identifyTask.ExecuteAsync(identifyParams, identifyParams);                  // execute 
            }

            

        }


The Identify Grid is put in a stackpanel

            <!--Identify-->
            <StackPanel x:Name="IdentifyStackPanel" Orientation="Vertical">
            <Border x:Name="IdentifyBorder" Background="#77919191" BorderThickness="1" CornerRadius="5"
                HorizontalAlignment="Left" BorderBrush="Gray"  VerticalAlignment="Top" Margin="5">
            <Border.Effect>
                <DropShadowEffect/>
            </Border.Effect>
            <Grid x:Name="IdentifyGrid" HorizontalAlignment="Right"  VerticalAlignment="Top" >
                <Grid.RowDefinitions>
                    <RowDefinition Height="30" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <TextBlock x:Name="DataDisplayTitleBottom" Text="Click on map to Identify a feature"
                           Foreground="White" FontSize="10" Grid.Row="0"
                           Margin="15,5,15,1" HorizontalAlignment="Center" >
                    <TextBlock.Effect>
                        <DropShadowEffect />
                    </TextBlock.Effect>
                </TextBlock>
                <Grid x:Name="IdentifyResultsPanel" Margin="5,1,5,5" HorizontalAlignment="Center" 
                      VerticalAlignment="Top" Visibility="Collapsed" Grid.Row="1">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="30" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <ComboBox x:Name="IdentifyComboBox" SelectionChanged="cb_SelectionChanged"
                              Margin="5,1,5,5" Grid.Row="0" FontFamily="Consolas" FontSize="12" Foreground="Brown">
                        
                    </ComboBox>
                    <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
                                  Width="330" MinHeight="200" Grid.Row="1">
                        <slData:DataGrid x:Name="IdentifyDetailDataGrid" AutoGenerateColumns="False" HeadersVisibility="None"
                                         Background="White">
                            <slData:DataGrid.Columns>
                                
                                <!--Shows field names*****-->
                                <slData:DataGridTextColumn Binding="{Binding Path=Key}" FontWeight="Bold"/>  
                                                                                                
                                <!--Shows field values*****-->
                                 <slData:DataGridTextColumn Binding="{Binding Path=Value}" />

                            </slData:DataGrid.Columns>
                        </slData:DataGrid>
                    </ScrollViewer>
                </Grid>
            </Grid>            
        </Border> 
        </StackPanel>


Hope this help
0 Kudos
TobinCrain
New Contributor
Thanks Angel.  Your code sample really helped me out.
0 Kudos
DanDong
New Contributor
Thank you guys!! This really offers me big help 😄
0 Kudos
SantoshV
New Contributor II
Hey thank you soo much for the code it was of great help..
However as we are using multiple services the the iteration is more as it iterates completely for every service.. is there a way where I can reduce the time taken for execute the complete program?
0 Kudos
DominiqueBroux
Esri Frequent Contributor
In this sample, the identify tasks are executed in //.

You can test it with this web map.
0 Kudos