Select to view content in your preferred language

Loading all features within a featureLayer into an array

1733
16
Jump to solution
02-15-2012 07:35 AM
MattGiles
Deactivated User
Is there a way to load all the features from a FeatureLayer into an Array (similar to FeatureLayer.selectedFeatures but for ALL the features) so they can be compared with an array of graphics? Or do I have to select all features in the FeatureLayer first and then use .selectedFeatures???
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus
M Giles,

   The ObjectID is a field in the attributes of the feature.
                var OIDArr:Array = new Array;                                                 for(anX=0;anX<targetLayer.selectedFeatures.length;anX++){                     Alert.show(targetLayer.selectedFeatures[anX].attributes[targetLayer.layerDetails.objectIdField])                 }


You should probably start promoting some of these posts that you find helpful.

View solution in original post

0 Kudos
16 Replies
DasaPaddock
Esri Regular Contributor
0 Kudos
MattGiles
Deactivated User
I have looked at that already and doesnt seem to be working for me:

protected function InvertSelBtn_clickHandler(event:MouseEvent):void{
    var i:Number = new Number;
    
    //array to hold selected features (graphics) in target layer
    var selected:Array = [];
    for(i=0;i<targetLayer.selectedFeatures.length;i++){
     var graphic:Graphic = targetLayer.selectedFeatures;
     selected.push(graphic);
    }
    
    //clear selected features in targetLayer after selected in loaded with the features that were selected
    targetLayer.clearSelection();
    
    Alert.show("before loading all features");
    
    //this holds all features in the targetLayer
    var targetLayerFeatures:ArrayCollection = new ArrayCollection;
    targetLayerFeatures = targetLayer.graphicProvider as ArrayCollection;
    
    Alert.show(targetLayerFeatures.contains(selected[1]).toString());


I load all selected features into an array of graphics - this works as i can print the geometry of the features and they are correct. Then i load all the features in the targetLayer into an arraycollection using the graphics provider. But arraycollection.length is 0 (so its not loading correctly) and the alert at the bottom prints false (again indicating the arraycollection is not loading correctly - since selected[1] comes from the targetLayer as well).

What am I doing incorrectly?

I am doing this to add invert selection functionality to my selection widget. Once i have an array of all the features in the targetLayer I will use a query to invert the selection. Is there an easier way of doing this?
0 Kudos
DasaPaddock
Esri Regular Contributor
The graphicsProvider is just the features already loaded into the FeatureLayer.

To do what you want, I'd try calling this:
http://help.arcgis.com/en/webapi/flex/apiref/com/esri/ags/layers/FeatureLayer.html#queryIds()
with Query.where = "1=1".

Then invert the selection by calling selectFeatures() with Query.objectIds.
0 Kudos
MattGiles
Deactivated User
Sorry Im new to flex - could you explain what queryID does exactly (nothing was selected when i used targetLayer.queryIds with query.where="1=1".

Also could you explain how i would use query.objectIds??

Thanks in advance
0 Kudos
MattGiles
Deactivated User
I tried another way that made a bit more sense to me.

I have successfully loaded an array with the unselected features and am trying to pass their geometries into a query and then pass the query into selectFeatures()

For some reason the query is not working out. The alert before query1 shows the right number of unselected points but the alert after the query shows 0.

 protected function InvertSelBtn_clickHandler(event:MouseEvent):void{
    var i:Number = new Number;
    var marker:Boolean = false;
    
    //holds all features in the targetLayer
    var features:Array = [];
    
    //holds all currently selected features in targetLayer
    var selected:Array = [];
    
    //holds all features that are not currently selected  - to be selected
    var notSelected:Array = [];
    
    //add features that are currently selected to array selected, then clear selection
    for(i=0;i<targetLayer.selectedFeatures.length;i++){
     var selFeature:Graphic = targetLayer.selectedFeatures;
     selected.push(selFeature);
     }
    //last query selects all points
    targetLayer.clearSelection();
    
    
    
    //this selects all features
    var query:Query = new Query;
     query.where = "1=1";
     
    //this.cursorManager.setBusyCursor(); 
    targetLayer.selectFeatures(query,"new",new AsyncResponder(onResult, onFault));
    
    //if select all fails
    function onFault(info:Array, token:FeatureLayer = null):void{
     Alert.show("Error During Invert Selection.");
    }
    
    //if selection is successful
    function onResult(info:Array, token:FeatureLayer = null):void{
    //upon result of selecting all features, add all features from targetLayer to array features, then clear selection
    for(i=0;i<targetLayer.selectedFeatures.length;i++){
     var feature:Graphic = targetLayer.selectedFeatures;
     features.push(feature);
     }
    
    
    
    //targetLayer.clearSelection();
    
    //nested for loop to iterate through features (run once for each feature in targetLayer)
    //then iterate through selected (run once for each feature in selFeatures)
    //if their objects match, marker set to true - if at the end of the inside loop marker is still false
    //no match was found and 
    for(x=0;x<features.length;x++){
     for(y=0;y<selected.length;y++){
      //if there is ever a match, mark boolean as true, and features wont be added to notSelected
      //i will have to change this to work with line, poly -for now points is fine
      if(features.geometry as MapPoint === selected.geometry as MapPoint){
       marker=true;
       
      } 
     }
     
     //if match wasnt found in inside for loop, then the feature wasnt selected and will be added to notSelected
     if(marker===false){
      notSelected.push(features);
     }
     
     //speed things up and break the loop if all non selected features have been added
     if(features.length<=(selected.length+notSelected.length)){
      break;
     }
    }
    //this alert broke the selection screen for some reason lol
    //Alert.show("# features selected: " +selected.length.toString()+"+ # features not selected: "+notSelected.length.toString()+"= # features total: "+features.length.toString());
    
    //loop through notSelected, adding each feature in it to selection of targetLayer
    targetLayer.clearSelection(); 
    
    Alert.show(notSelected.length.toString());
    
    var query1:Query = new Query;
     query1.geometry = notSelected.geometry;
     query1.spatialRelationship=Query.SPATIAL_REL_OVERLAPS;
     
     targetLayer.selectFeatures(query1,"new",null);
    
    
    
    Alert.show(targetLayer.selectedFeatures.length.toString());
    
    
    }
   }
0 Kudos
MattGiles
Deactivated User
I solved the query issue - but the real issue is the line that compares geometries from features to geometries from selected...this if statement is never entered...can someone shed some light?
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
M Giles,

   Why not just compare their ObjectIds or their attributes?
0 Kudos
MattGiles
Deactivated User
Is their a big difference between comparing the graphics attributes and comparing the graphics geometries? I tried both and neither worked..I have it working now by comparing their geometries type casted into strings (ex: features.geometry.toString()) - this seems like a bad way of doing it but it seems to work...

Invert now works with points but it seems to crap out with polygons (sometimes). I have a layer with ~100 polygons and when i select ~25-50 of them and invert selection i get the error message:

RPC Fault faultString="Unable to complete  operation." faultCode="400" faultDetail="Unable to complete Query operation."

but when i select ~90 of them it works..


Any ideas on what could be causing this?
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
M Giles,

   Using the ObjectIDs would be much cleaner and is the was it is done in ArcMap. The issue you are likely having is just the size of the data being requested if it was some 100 simple four point polygons then that would be a JSON string of 400 X and Ys on top of all the other data that is in the JSON response. The whole problem with the selection widget and what you are attempting to do is you are treating a web mapping app like it is an online ArcMap which it will never be.
0 Kudos