Select to view content in your preferred language

Loading all features within a featureLayer into an array

1740
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
16 Replies
MattGiles
Deactivated User
OK sounds good - I get that I am pushing the limits of the app but an invert selection option is required for the nature of the application (will be used to highlight deficiencies in monitoring programs etc) since query's spatial relationship does not include things like "does not contain"...

I assume using the objectIDs to compare would reduce the size of the JSON string?

Instead of the line " if(features[x1].geometry.toString() == selected[y1].geometry.toString())" I tried to use (features[x1].attributes == selected[y1].attributes) and (features[x1].id == selected[y1].id) and neither worked...I attached my code below - is there any reason you can see why neither of these are working? Thanks so much Robert for your help!

protected function InvertSelBtn_clickHandler(event:MouseEvent):void{
    //reset all three arrays
    
    features = [];
    selected = [];
    notSelected = [];
    
    
    
    this.cursorManager.setBusyCursor();
    
    //add features that are currently selected to array selected, then clear selection
    var i:Number = new Number;
    for(i=0;i<targetLayer.selectedFeatures.length;i++){
     var selFeature:Graphic = targetLayer.selectedFeatures;
     selected.push(selFeature);
     
     
    }
    targetLayer.clearSelection();
    
    
     
    //this selects all features
    var query:Query = new Query;
    query.where = "1=1";
    
    //this.cursorManager.setBusyCursor(); 
    targetLayer.selectFeatures(query,"new",new AsyncResponder(onInvertSelectAllResult, onInvertSelectAllFault));
    
    }
    
    //if select all during invert fails
    private function onInvertSelectAllFault(info:Array, token:FeatureLayer = null):void{
     Alert.show("Error During Invert Selection.");
    }
    
    //if select all during invert is successful - continue with invert process
    private function onInvertSelectAllResult(info:Array, token:FeatureLayer = null):void{
     var marker:Boolean = false;
     
     //upon result of selecting all features, add all features from targetLayer to array features, then clear selection
     var i:Number = new Number;
     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 the feature is loaded into notSelected
     var x1:Number = new Number;
     var y1:Number = new Number;
      
     for(x1=0;x1<features.length;x1++){
      marker=false;
      
       for(y1=0;y1<selected.length;y1++){
       //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[x1].geometry.toString() == selected[y1].geometry.toString()){
        //this lets us know that there was a match and nothing should be added to notSelected
        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[x1]);
       
       
      }
    
     }
     
     //pass the array of unselected features into featSet, then pass to unionGeom to get a geometry back
     var featSet:FeatureSet = new FeatureSet(notSelected);
     var unionGeom:Geometry = SelectionWidgetUtil.unionGeoms(featSet);
     
     
     //now run query with unionGeom
      var query1:Query = new Query;
      query1.geometry=unionGeom;
      targetLayer.selectFeatures(query1,"new",new AsyncResponder(onInvertResult, onInvertFault, targetLayer));  
       
    } 

  
   
   //on invert selection result
   private function onInvertResult(info:Array, token:FeatureLayer = null):void
   {
    this.cursorManager.removeBusyCursor();
   
    //this makes the selection results page be displayed upon selection
    /* var e:Event = new SelectionFeatureLayerEvent(SelectionFeatureLayerEvent.SHOW_RESULTS, null);
    dispatchEvent(e); */
   }
   
   //on invert selection fault
   private function onInvertFault(info:Object, token:Object = null):void
   {
    this.cursorManager.removeBusyCursor();
    Alert.show("Could not complete Selection. Please try again.\n" + info.toString(), 
     "Selection Error", Alert.OK);
   }
   
   
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
M Giles,

   Honestly I can not begin to understand the logic in your code. So let me try to tell you how I would approach it, (What you are missing from what Dasa was directing you towards).


  1. You have a featurelayer and it has certain features selected

  2. You want to invert that selection meaning select all the unselected features.

  3. You would begin by building an array of ObjectIds from the current selection.

  4. You would then use targetLayer selectFeatures and the query that you would pass is:

  5.                 var query:Query = new Query;
                    query.where = "NOT " targetLayer.layerDetails.objectIdField + " IN (" + OIDArr.join(",") + ")";
                    targetLayer.selectFeatures(query,"new",new AsyncResponder(onInvertSelectAllResult, onInvertSelectAllFault));
    Where OIDArr is the array containing the objectids of the current selection.
0 Kudos
MattGiles
Deactivated User
Yes im very inexperienced with flex and dont know / understand the full capabilities that are available to me - for this reason alot of my code is very illogical. Thanks Robert Ill try that method of doing it.

One more question for you - how do I load an array from the targetLayer.queryIds() function as it returns an asynctoken...i tried OIDArr = targetLayer.queryIds() as Array but that was unsuccessful
..Ive been searching all over the net and cant find an example that uses .queryIds() function.
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
M Giles,

   For a sample close to using QueryIds look here: It actually use QueryTask executeForIds but will give you what you need.

http://help.arcgis.com/en/webapi/flex/samples/01nq/01nq00000060000000.htm

Also I don't think you even have to go that route... Just loop though your selected features and add the value of the ObjectID field to an array.
0 Kudos
MattGiles
Deactivated User
But how do I access the objectIDs from targetLayer.selectedFeatures?

I tried this:
var OIDArr:Array = new Array;        
    for(anX=0;anX<targetLayer.selectedFeatures.length;anX++){
     Alert.show(targetLayer.selectedFeatures[anX].id)
    }


but that simply returns the graphic IDs which are not the same..


I tried queryTask executeForIds() which works but it returns all the ids in targetLayer. How would I a.make a new FeatureLayer from just the selected features in targetLayer or b.tell it to only return Ids for those features that are selected??

This seems so simple yet so difficult for a noob like myself.

Thanks again. 🙂
0 Kudos
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.
0 Kudos
MattGiles
Deactivated User
Thanks so much for your help Robert. Much appreciated.
0 Kudos