Select to view content in your preferred language

How to perform spatial query between two services...

6192
24
07-15-2010 04:45 AM
MichaelBlom
Deactivated User
Hello,
all of the sdk examples involving spatial qeuries involve a service being queried against a feature that the user creates in th UI. 

ie drag a box, take the geometry from that box, set that geometry into the query, perform task

I want to do a query task between two service layers.

I see that I need to get at the recordset from the service in Silverlight, does anyone know how to do this?

Thanks,
Mike
0 Kudos
24 Replies
MichaelBlom
Deactivated User
answering my own question:

  • within the xaml for my ArcGISDynamicMapServiceLayer, i provide a call to a method for Initialized

  • in the code behind: var dynamicService = sender as ArcGISDynamicMapServiceLayer;

  • get the layerinfos: foreach (LayerInfo fl in dynamicService.Layers)

0 Kudos
JMcNeil
Deactivated User
Mike,
I am looking to do something similar.  I'm wondering if I could see your code or ask you a few questions. 

Thanks
Jay
jmcneil@escondido.org
0 Kudos
SourishChakraborty
Deactivated User
Hi,
Please clarify a little;
There may be a scenario where multiple layers are there in a service.You can query one layer with the features of other layer from the same service.

There may be a scenario where two layers are from different services.You can query one service layer by using the features of other service layer.

Which scenario you want to use.

Thanks & Regards
Sourish Chakraborty
0 Kudos
JMcNeil
Deactivated User
After reading Mike's and your post I'm thinking he was trying something different.  Basically, I have implemented the Spatial Query tools.....straight forward and super easy; grabbed the xaml and code behind C# from the interactive sdk ( http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#SpatialQuery ) but I would really like to give the user the option to do spatial queries on multiple/several layers (not multiple layers at the same time but the user selects an active layer to perform the query on probably from one service but being able to select layers from two or three services might be an option because there will be several services that make up the map).

I built a layer list for my application that allows the user to check check boxes to turn on/off layers so I was thinking I could create radio buttons for each layer,  which would drive the active layer or I could create a drop down list of all the layers in the map and this could drive the active layer. 

What I'm kind of  lost and twisted about is how to change my fields and data table headers based on the active layer.  The spatial query interactive SDK sample ( http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#SpatialQuery ) hard codes all the fields and table field names.  Maybe somehow there is a way to query the active service/layer and dynamically populate some Collection object, or maybe have an XML file that is hard coded and that populates the table. What about global variables of the layer name, fields, headers, etc.  Then when the user submits the query, set the query parameters from the global variables.  Or just bind them to those variables. 

Not sure setting the active layer seems straight forward and I think I can handle that I am just having a hard time thinking of how to populate the table and I guess I'm was hoping to sneak a peak at something to jump start my process.
0 Kudos
ChristineZeller
Occasional Contributor
answering my own question:

  • within the xaml for my ArcGISDynamicMapServiceLayer, i provide a call to a method for Initialized

  • in the code behind: var dynamicService = sender as ArcGISDynamicMapServiceLayer;

  • get the layerinfos: foreach (LayerInfo fl in dynamicService.Layers)




Mike like Mr. Lennon

I am looking to do something similar and was also wondering if you wouldn't mind sharing your call to method for initialized and your foreach (LayerInfo fl in dynamicService.Layers) loop with a little more detail.  I'm somewhat fresh/green and have an idea on how it should be done but having trouble.

Christine.
0 Kudos
JMcNeil
Deactivated User
Christine, Mike, blomm or anyone else interested in this post!

I finally found a little time to try and get the SDK spatial tool to work with muiltiple layers, using a combo drop down box.  I'm almost there and now I'm having a freeze about how to handle the xaml end........populating the headers and fields for the datagrid.  This Part:

 <!-- Query Results -->

                                            <slData:DataGrid x:Name="QueryDetailsDataGrid" AutoGenerateColumns="False" HeadersVisibility="Column" Background="White" 
                                IsReadOnly="True" HorizontalScrollBarVisibility="Hidden"
                             RowStyle="{StaticResource MyCustomRow}" CanUserSortColumns="True"
                             SelectionChanged="QueryDetailsDataGrid_SelectionChanged"
                             LoadingRow="QueryDetailsDataGrid_LoadingRow">                                               
                                                         <slData:DataGrid.Columns>
                                                            <slData:DataGridTextColumn Binding="{Binding Attributes[BVUNIQUEID]}" Header="BV UNIQUE ID"/>
                                                            <slData:DataGridTextColumn Binding="{Binding Attributes[CREZ_NAME]}" Header="CREZ NAME"/>
                                                            <slData:DataGridTextColumn Binding="{Binding Attributes[SOLARTH_MW]}" Header="SOLARTH MW"/>
                                                            <slData:DataGridTextColumn Binding="{Binding Attributes[ACRES]}" Header="ACRES"/>
                                                        </slData:DataGrid.Columns>
                                                    </slData:DataGrid>
                                            
                                            
                                            
                                                </ScrollViewer>
                                          
                                    </Grid>
                                </userControls:CollapsiblePanel>
                                
                       
                                <!-- End Query Results -->




So Like I said I add a drop down list in xaml, which is used to select which layer is active.

 <!--Jays DropDown List / Combo Box for Spatial Selection -->


                            <ComboBox x:Name="LayerListDropDown" Width="150" Height="30" VerticalAlignment="Bottom" HorizontalAlignment="Center"  Margin="0,5,0,5" SelectionChanged="DropDown_ItemSelected">
                                
                                <ComboBoxItem Content="layer1" />
                                <ComboBoxItem Content="layer2" />
                                <ComboBoxItem Content="layer3" />
                               
                            </ComboBox>


                            <!--Jays DropDown List / Combo Box for Spatial Selection -->




In my code behind I add this

 #region LayerListDropDown Code
        //layerlist dropdown code


        private void DropDown_ItemSelected(object sender, EventArgs e)
        {

            if (LayerListDropDown.SelectedIndex == 0)
            {
       
                UrlServiceId = "http://dgpdch01/ArcGIS/rest/services/testD2/MapServer/14";
            }

            else if (LayerListDropDown.SelectedIndex == 1)
            {
      
                UrlServiceId = "http://dgpdch01/ArcGIS/rest/services/testD2/MapServer/18";
            }

            else
            {
        
                UrlServiceId = "http://dgpdch01/ArcGIS/rest/services/testD2/MapServer/19";
            }


            _queryTask = new QueryTask(UrlServiceId);
            _queryTask.ExecuteCompleted += QueryTask_ExecuteCompleted;
            _queryTask.Failed += QueryTask_Failed;

        }

        #endregion





and in the method

private void MyDrawSurface_DrawComplete(object sender, ESRI.ArcGIS.Client.DrawEventArgs args)

I add this

 //Jay add for if else drop list.

             if (LayerListDropDown.SelectedIndex == 0)
            {
                query.OutFields.AddRange(new string[] { "BVUNIQUEID", "ACRES", "CREZ_NAME", "SOLARTH_MW" }); 
            }

            else if (LayerListDropDown.SelectedIndex == 1)
            {
                query.OutFields.AddRange(new string[] { "PROJECTTYP", "CREZ_BVID", "CREZ_NAME", "MW", "CALCULATED"}); 
            }

            else
            {
                query.OutFields.AddRange(new string[] { "PROJECT_ID", "ASSOC_CREZ", "ACRES", "CREZ_BVID", "GISCALC" }); 
            }




So now the user can select a layer and spatial query on the selected layer but the field name it is trying to pull and field headers are static.   Also right now it is only working with polygon layers.  Once I get polys down I will write story/animation so lines and markers work but

What should I do to switch what is being  Generater in the QueryDetailsDataGrid GRID (the first xaml code I posted or to be really specific I only need to change the column data....see below). 

Should I handle this with hiding and showing animation/grids or is there a way to do like a if/else in xaml or add some event trigge and checked if that is checked (EventTrigger EventName="Checked") but the check should be the drop down list so it would be really easy to just do an if/else 

Late in the day and I can't think......plus I'm a hack.


<slData:DataGrid.Columns>
                                                            <slData:DataGridTextColumn Binding="{Binding Attributes[BVUNIQUEID]}" Header="BV UNIQUE ID"/>
                                                            <slData:DataGridTextColumn Binding="{Binding Attributes[CREZ_NAME]}" Header="CREZ NAME"/>
                                                            <slData:DataGridTextColumn Binding="{Binding Attributes[SOLARTH_MW]}" Header="SOLARTH MW"/>
                                                            <slData:DataGridTextColumn Binding="{Binding Attributes[ACRES]}" Header="ACRES"/>
                                                 </slData:DataGrid.Columns>
0 Kudos
JMcNeil
Deactivated User
O.K.
I got a little more time today and made no progress I was thinking something like a datatrigger but I don't even know if that is possible in Silverlight....I couldn't find the ref to add or it wouldn't let me add it.  I gave Interaction.Triggers and EventTrigger a thought but on what?

So I just thought keep it simple and basic....like most of my coding.  So I add a few variables in my CODE behind -  MainPage.xaml.cs and declared them up where the other variable are declared and assigned them in the if/else statement (see code below for that ref.)           



        private void MyDrawSurface_DrawComplete(object sender, ESRI.ArcGIS.Client.DrawEventArgs args)
        {
            GraphicsLayer selectionGraphicslayer = Map.Layers["MySelectionGraphicsLayer"] as GraphicsLayer;
            selectionGraphicslayer.ClearGraphics();

            // Bind data grid to query results
            Binding resultFeaturesBinding = new Binding("LastResult.Features");
            resultFeaturesBinding.Source = _queryTask;
            QueryDetailsDataGrid.SetBinding(DataGrid.ItemsSourceProperty, resultFeaturesBinding);

            Query query = new ESRI.ArcGIS.Client.Tasks.Query();


            

            //Jay add for if else drop list.

             if (LayerListDropDown.SelectedIndex == 0)
            {




                Field1 = "BVUNIQUEID";
                Field2 = "ACRES";
                Field3 = "CREZ_NAME";
                Field4 = "SOLARTH_MW";

                query.OutFields.AddRange(new string[] { Field1, Field2, Field3, Field4 });


               

            

            }

            else if (LayerListDropDown.SelectedIndex == 1)
            {


                 



And this works but when flip back to my xaml where the attributes are binded.

I can't pass my varialbe and bind that


<slData:DataGrid.Columns>

<!-- This dies -->
<slData:DataGridTextColumn Binding= "{Binding Attributes[Field1]}" Header= Field1/>

<!-- These still work -->
 <slData:DataGridTextColumn Binding="{Binding Attributes[ACRES]}" Header="CREZ NAME"/>
 <slData:DataGridTextColumn Binding="{Binding Attributes[SOLARTH_MW]}" Header="SOLARTH MW"/>
     <slData:DataGridTextColumn Binding="{Binding Attributes[ACRES]}" Header="ACRES"/>
 </slData:DataGrid.Columns>
                                            
                                              



Which makes sense....

SO I'm Pleading for help and apologizing that this post is growing and growing and growing with no resolution.... sort of like the Bing Map does not show up post and the Area And Perimeter, which I haven't looked at yet but I promise I will try to help solve them if someone helps me!  And that will clear 3 posts that are constantly on the top of this board.
0 Kudos
JenniferNery
Esri Regular Contributor
Can you just use FeatureDataGrid instead? Bind Map to your map and GraphicsLayer to your SelectionGraphicsLayer, since the query results are added to your GraphicsLayer.


                <esri:FeatureDataGrid Grid.Row="1" x:Name="QueryDetailsDataGrid" Height="170" 
                                      Map="{Binding ElementName=MyMap}" 
                                      GraphicsLayer="{Binding ElementName=MyMap, Path=Layers[MySelectionGraphicsLayer]}" />


Your ComboBox can probably contain FeatureLayers:
XAML-code
                <ComboBox x:Name="Layers" >
                    <ComboBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding LayerInfo.Name}"/>
                        </DataTemplate>
                    </ComboBox.ItemTemplate>
                </ComboBox>

Code-behind (maybe after Initialize)
            string baseUrl = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer";
            for (int i = 0; i <= 5; i++)
            {
                FeatureLayer featureLayer = new FeatureLayer() { Url = string.Format("{0}/{1}", baseUrl, i)};
                featureLayer.Initialize();
                layers.Add(featureLayer);
            }
            Layers.ItemsSource = layers;
            Layers.SelectedIndex = 0;


Also, I would tweak the query to return all fields.
            QueryTask queryTask = new QueryTask((Layers.SelectedItem as FeatureLayer).Url);
            //... more code here
            query.OutFields.Add("*");
0 Kudos
JMcNeil
Deactivated User
Jennifer, thanks for the reply!  I didn't think of using FeatureDataGrid instead.

Just glancing at your code you posted.  What do I declare the layers and query variables as.  I don�??t think they exist in my current code. 

I think the layers maybe should be:

ItemCollection layers;
       

But what about the query is that a property of the Outfields constructor, like an Item?  Or is it a list?  How should I declare it?  Sorry for the confusion.
0 Kudos