Select to view content in your preferred language

Feature layer dynamic query features display

2394
2
10-03-2011 08:05 AM
HugoCardenas
Emerging Contributor
Is there a way to display new sets of features on the map without deleting existing or currently diplayed ones?

Initially, when the page loads for the first time, I display on screen a set of features (cf. XAML code below):

<esri:FeatureLayer ID="MyMeters" Renderer="{StaticResource AlertTypesRenderer}" Where="AlertType = 14" ... />


At run time, the user has a set of check boxes to display any other alerts and remove from the screen the previously loaded ones (cf. C# code bewlow):

ESRI.ArcGIS.Client.FeatureLayer fs = new ESRI.ArcGIS.Client.FeatureLayer();
fs.Where = "AlertType = 11";


At this point, the user has checked-off the "14" and checked the "11" alerts.  If I call a "ClearGraphics" method on the feature layer right before displaying the new features, "ClearGraphics" actually deletes the previous features permanently from the feature service!  Hence, I create a new instance of the "FeatureLayer" (cf. C# code above), rather than referencing the existing instance like this:

FeatureLayer fs = MyMap.Layers["MyMeters"] as FeatureLayer;


I have tried other options like:

1.  Removing the entire MyMap.Layers["MyMeters"] and inserting a new one (in the same index position as that of the previous one) with the new features.

2. Creating a new graphics layers and add this one to the MyMap.Layers collection.

These two options work fine, BUT my feature data grid gets all crazy: in option 1 the feature data grid references the feature layer that is removed.  When I bind the new layer at run-time to it, it does not sync that well. In option 2, the feature data grid does not respond at all.


Perhaps I am managing the features of a feature layer the wrong way.  I think there may be a way to just "hide" or remove previous features from screen, so I can only see on screen the new ones.  In doing, so I can choose to display only the features I specify, without having to "delete" them form the Service, or without having to "remove/insert" feature layers.

Do you know any better way?  Please share it with me.

Hugo.
0 Kudos
2 Replies
JenniferNery
Esri Regular Contributor
How about updating the FeatureLayer.Where clause to include previous clause?
WHERE = "AlertType = 14 or AlertType = 11"

Calling FeatureLayer.Update() will query the service and return features that match the above condition.
0 Kudos
HugoCardenas
Emerging Contributor
Thanks Jennifer!
You did it!  It was the "FeatureLayer.Update()" line that did it.
In my query, I leave out types = 14 in order to show on screen only types = 11.  The type 14 is on screen already; then, I issue a run-time query from code-behind and retrieve types = 11.  The whole idea is to remove the 14s from the screen and place the 11s instead.  It works!

I did have to add the "FeatureLayer_UpdateFailed" event in order for the "FeatureLayer_UpdateCompleted" event to execute; the latter was not executing without the former.  I use the "FeatureLayer_UpdateCompleted" event for further processing of those newly retrieved features.

The whole process is like this:

1.  Retrieve types 14 at page first load (XAML):
<esri:FeatureLayer ID="MyMeters" Renderer="{StaticResource AlertTypesRenderer}" OutFields="*" Where="AlertType = 14" Url="my-url" MouseLeftButtonDown="FeatureLayer_MouseLeftButtonDown" />


2. Bind the feature data grid to the feature layer (XAML):
<esri:FeatureDataGrid  x:Name="MyDataGrid" Map="{Binding ElementName=MyMap}"
GraphicsLayer="{Binding ElementName=MyMap, Path=Layers.[MyMeters]}" SelectionChanged="MyDataGrid_SelectionChanged" />


3. At run-time, perform another query to retrieve types = 11 and remove from screen the 14s that were retrieved at page load with XAML code (cf. step 1):
public void ReLoadMeters()
{
   // Create an instance referencing the already existing feature layer
   FeatureLayer fs = MyMap.Layers["MyMeters"] as FeatureLayer;
   
   // Set event handler on feature layer feature retrieval.
   fs.UpdateCompleted += FeatureLayer_UpdateCompleted;
   fs.UpdateFailed += new EventHandler<Tasks.TaskFailedEventArgs>(FeatureLayer_UpdateFailed);
   fs.Where = "AlertTypes = 11";
   fs.Update();
}


4.  Define the "FeatureLayer_UpdateCompleted" event for further processing of newly retrieved features:
private void FeatureLayer_UpdateCompleted(object sender, EventArgs args)
{
   FeatureLayer fs = sender as FeatureLayer;
   foreach (Graphic graphic in fs.Graphics)
  {
     // Here I do my further processing with the newly retrieved features
  }
}


5.  Define the "FeatureLayer_UpdateFailed" event handler (the event at step 4 was not firing without this one):
private void FeatureLayer_UpdateFailed(object sender, EventArgs args)
{
   FeatureLayer fs = sender as FeatureLayer;
   // Catch any errors here...
}


Now, my feature data grid and the features on screen are in syn all the time: the attributes for those features on screen are listed on the feature data grid; when I click on a map feature or on a row, the map zooms in to the feature and the row highlights.

Thanks again, Jennifer!
Hugo.
0 Kudos