Filtering the FeatureLayer graphics on the client side

2883
3
Jump to solution
04-08-2013 12:25 PM
PriyaRam
New Contributor III
Hi,

I have loaded the feature layer on the client side based on a certain criteria on the definition query and I would like to know, if it is possible to obtain a subset of this Feature layer by performing a filter on the client side, rather than querying again using selectFeatures.

Thanks in advance for all your help.


Priya
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
IvanBespalov
Occasional Contributor III
Try to extend FeatureLayer

package ee.alphagis.layers {  import com.esri.ags.events.LayerEvent;  import com.esri.ags.layers.FeatureLayer;    public class MyFeatureLayer extends FeatureLayer  {   public function MyFeatureLayer(url:String=null, proxyURL:String=null, token:String=null)   {    super(url, proxyURL, token);   }      public function setFilterFunction(func:Function):void   {    $graphicProvider.filterFunction = func;    $graphicProvider.refresh();    dispatchEvent(new LayerEvent(LayerEvent.UPDATE_END, this, null, true));   }  } }

<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"        xmlns:s="library://ns.adobe.com/flex/spark"        xmlns:mx="library://ns.adobe.com/flex/mx"       xmlns:esri="http://www.esri.com/2008/ags"        xmlns:layers="ee.alphagis.layers.*">    <s:layout>   <s:HorizontalLayout gap="5"        paddingBottom="10"        paddingLeft="10"        paddingRight="10"        paddingTop="10" />  </s:layout>    <fx:Script>   <![CDATA[    import com.esri.ags.Graphic;    import com.esri.ags.events.GraphicEvent;    import com.esri.ags.events.LayerEvent;        import mx.collections.ArrayCollection;        [Bindable]    private var totalGraphicsShown:String = "";        private var filterParam:int;        protected function onGraphicAdd(event:GraphicEvent):void    {     event.graphic.toolTip = "FIPS: " + event.graphic.attributes.FIPS       + "\n"       + "POP2000: " + event.graphic.attributes.POP2000;    }        protected function onFilterClick(event:MouseEvent):void    {     var bt:Button = Button(event.target);     switch (bt.id)     {      case bt100.id:       filterParam = 100;       break;      case bt300.id:       filterParam = 300;       break;      case bt500.id:       filterParam = 500;       break;      case bt700.id:       filterParam = 700;       break;      case bt900.id:       filterParam = 900;       break;     }          fLayer.setFilterFunction(providerFilterFunction);    }        protected function onClearFilters(event:MouseEvent):void    {     fLayer.setFilterFunction(null);    }        protected function providerFilterFunction(item:Object):Boolean    {     var isFiltered:Boolean = false;     var gr:Graphic = Graphic(item);     if (int(gr.attributes.POP2000) < filterParam)     {      isFiltered = true;     }     return isFiltered;    }     protected function onLayerUpdateEnd(event:LayerEvent):void    {     totalGraphicsShown = "Total graphics shown: " + (fLayer.graphicProvider as ArrayCollection).length;    }    ]]>  </fx:Script>    <fx:Declarations>   <esri:SimpleMarkerSymbol id="symbol1"          alpha="0.7"          color="0xFF0000"          size="6"          style="triangle"/>   <esri:SimpleMarkerSymbol id="symbol2"          alpha="0.7"          color="0xFF0000"          size="10"          style="triangle"/>   <esri:SimpleMarkerSymbol id="symbol3"          alpha="0.7"          color="0xFF0000"          size="16"          style="triangle"/>   <esri:SimpleMarkerSymbol id="symbol4"          alpha="0.7"          color="0xFF0000"          size="22"          style="triangle"/>   <esri:SimpleMarkerSymbol id="symbol5"          alpha="0.7"          color="0xFF0000"          size="26"          style="triangle"/>  </fx:Declarations>    <s:Panel width="100%"     height="100%"     title="Map">       <esri:Map>    <esri:extent>     <esri:Extent id="lowerManhattan"         xmin="-8239000" ymin="4968000" xmax="-8235000" ymax="4971000">      <esri:SpatialReference wkid="102100"/>     </esri:Extent>    </esri:extent>    <esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"/>    <layers:MyFeatureLayer id="fLayer"             graphicAdd="onGraphicAdd(event)"            updateEnd="onLayerUpdateEnd(event)"            outFields="[FIPS,POP2000]"            url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/0">     <layers:renderer>      <esri:ClassBreaksRenderer field="POP2000">       <esri:ClassBreakInfo maxValue="61"              symbol="{symbol1}"/>       <esri:ClassBreakInfo maxValue="264"             minValue="62"             symbol="{symbol2}"/>       <esri:ClassBreakInfo maxValue="759"             minValue="265"             symbol="{symbol3}"/>       <esri:ClassBreakInfo maxValue="1900"             minValue="760"             symbol="{symbol4}"/>       <esri:ClassBreakInfo minValue="1901"              symbol="{symbol5}"/>      </esri:ClassBreaksRenderer>     </layers:renderer>    </layers:MyFeatureLayer>   </esri:Map>     </s:Panel>    <s:Panel width="300"     height="100%"     title="Filters">      <s:VGroup paddingBottom="5"       paddingLeft="5"        paddingRight="5"       paddingTop="5"        gap="10">        <s:Button id="bt100"         label="Filter POP2000 less 100"        click="onFilterClick(event)"/>        <s:Button id="bt300"         label="Filter POP2000 less 300"        click="onFilterClick(event)"/>        <s:Button id="bt500"         label="Filter POP2000 less 500"        click="onFilterClick(event)"/>        <s:Button id="bt700"         label="Filter POP2000 less 700"        click="onFilterClick(event)"/>        <s:Button id="bt900"         label="Filter POP2000 less 900"        click="onFilterClick(event)"/>        <s:Button label="Clear filters"        click="onClearFilters(event)"/>        <s:Label text="{totalGraphicsShown}" />       </s:VGroup>     </s:Panel>   </s:Application>


Good luck.

UPD: API version 3.1 release 12/12/2012

View solution in original post

0 Kudos
3 Replies
IvanBespalov
Occasional Contributor III
In sample with sources graphicsFilterFunction(...)
0 Kudos
PriyaRam
New Contributor III
Thanks for the sample. However I see that you are using Graphics Layer, but in my case it is a Feature layer. I cannot use a Graphics layer in my scenario, since I need to show the symbology. I tried to filter on the graphicsProvider(ArrayCollection ) property of the FeatureLayer by attaching a filter function to it. But the filtering is not getting applied.(It honors what the API doc says.) Just wanted to make sure, if there is any other way i can do client side filtering on the features of the FeatureLayer.



graphicProvider : Object
[override] This inherited property returns an ArrayCollection of all the graphics currently in the layer, but unlike GraphicsLayer, this should be treated as a read-only property and modifications to the returned ArrayCollection are ignored.


Rgds..
Priya
0 Kudos
IvanBespalov
Occasional Contributor III
Try to extend FeatureLayer

package ee.alphagis.layers {  import com.esri.ags.events.LayerEvent;  import com.esri.ags.layers.FeatureLayer;    public class MyFeatureLayer extends FeatureLayer  {   public function MyFeatureLayer(url:String=null, proxyURL:String=null, token:String=null)   {    super(url, proxyURL, token);   }      public function setFilterFunction(func:Function):void   {    $graphicProvider.filterFunction = func;    $graphicProvider.refresh();    dispatchEvent(new LayerEvent(LayerEvent.UPDATE_END, this, null, true));   }  } }

<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"        xmlns:s="library://ns.adobe.com/flex/spark"        xmlns:mx="library://ns.adobe.com/flex/mx"       xmlns:esri="http://www.esri.com/2008/ags"        xmlns:layers="ee.alphagis.layers.*">    <s:layout>   <s:HorizontalLayout gap="5"        paddingBottom="10"        paddingLeft="10"        paddingRight="10"        paddingTop="10" />  </s:layout>    <fx:Script>   <![CDATA[    import com.esri.ags.Graphic;    import com.esri.ags.events.GraphicEvent;    import com.esri.ags.events.LayerEvent;        import mx.collections.ArrayCollection;        [Bindable]    private var totalGraphicsShown:String = "";        private var filterParam:int;        protected function onGraphicAdd(event:GraphicEvent):void    {     event.graphic.toolTip = "FIPS: " + event.graphic.attributes.FIPS       + "\n"       + "POP2000: " + event.graphic.attributes.POP2000;    }        protected function onFilterClick(event:MouseEvent):void    {     var bt:Button = Button(event.target);     switch (bt.id)     {      case bt100.id:       filterParam = 100;       break;      case bt300.id:       filterParam = 300;       break;      case bt500.id:       filterParam = 500;       break;      case bt700.id:       filterParam = 700;       break;      case bt900.id:       filterParam = 900;       break;     }          fLayer.setFilterFunction(providerFilterFunction);    }        protected function onClearFilters(event:MouseEvent):void    {     fLayer.setFilterFunction(null);    }        protected function providerFilterFunction(item:Object):Boolean    {     var isFiltered:Boolean = false;     var gr:Graphic = Graphic(item);     if (int(gr.attributes.POP2000) < filterParam)     {      isFiltered = true;     }     return isFiltered;    }     protected function onLayerUpdateEnd(event:LayerEvent):void    {     totalGraphicsShown = "Total graphics shown: " + (fLayer.graphicProvider as ArrayCollection).length;    }    ]]>  </fx:Script>    <fx:Declarations>   <esri:SimpleMarkerSymbol id="symbol1"          alpha="0.7"          color="0xFF0000"          size="6"          style="triangle"/>   <esri:SimpleMarkerSymbol id="symbol2"          alpha="0.7"          color="0xFF0000"          size="10"          style="triangle"/>   <esri:SimpleMarkerSymbol id="symbol3"          alpha="0.7"          color="0xFF0000"          size="16"          style="triangle"/>   <esri:SimpleMarkerSymbol id="symbol4"          alpha="0.7"          color="0xFF0000"          size="22"          style="triangle"/>   <esri:SimpleMarkerSymbol id="symbol5"          alpha="0.7"          color="0xFF0000"          size="26"          style="triangle"/>  </fx:Declarations>    <s:Panel width="100%"     height="100%"     title="Map">       <esri:Map>    <esri:extent>     <esri:Extent id="lowerManhattan"         xmin="-8239000" ymin="4968000" xmax="-8235000" ymax="4971000">      <esri:SpatialReference wkid="102100"/>     </esri:Extent>    </esri:extent>    <esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"/>    <layers:MyFeatureLayer id="fLayer"             graphicAdd="onGraphicAdd(event)"            updateEnd="onLayerUpdateEnd(event)"            outFields="[FIPS,POP2000]"            url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/0">     <layers:renderer>      <esri:ClassBreaksRenderer field="POP2000">       <esri:ClassBreakInfo maxValue="61"              symbol="{symbol1}"/>       <esri:ClassBreakInfo maxValue="264"             minValue="62"             symbol="{symbol2}"/>       <esri:ClassBreakInfo maxValue="759"             minValue="265"             symbol="{symbol3}"/>       <esri:ClassBreakInfo maxValue="1900"             minValue="760"             symbol="{symbol4}"/>       <esri:ClassBreakInfo minValue="1901"              symbol="{symbol5}"/>      </esri:ClassBreaksRenderer>     </layers:renderer>    </layers:MyFeatureLayer>   </esri:Map>     </s:Panel>    <s:Panel width="300"     height="100%"     title="Filters">      <s:VGroup paddingBottom="5"       paddingLeft="5"        paddingRight="5"       paddingTop="5"        gap="10">        <s:Button id="bt100"         label="Filter POP2000 less 100"        click="onFilterClick(event)"/>        <s:Button id="bt300"         label="Filter POP2000 less 300"        click="onFilterClick(event)"/>        <s:Button id="bt500"         label="Filter POP2000 less 500"        click="onFilterClick(event)"/>        <s:Button id="bt700"         label="Filter POP2000 less 700"        click="onFilterClick(event)"/>        <s:Button id="bt900"         label="Filter POP2000 less 900"        click="onFilterClick(event)"/>        <s:Button label="Clear filters"        click="onClearFilters(event)"/>        <s:Label text="{totalGraphicsShown}" />       </s:VGroup>     </s:Panel>   </s:Application>


Good luck.

UPD: API version 3.1 release 12/12/2012
0 Kudos