Select to view content in your preferred language

Populate combobox with a layer from a map service.

2029
12
12-08-2010 08:00 AM
JasonLevine
Deactivated User
I've been searching for the proper way of doing this, but I've only found how to populate a combobox with the results from a query.  Basically, I'd like to create an ArrayCollection that contains all of the features of a single layer in a map service and use it as the data provider for my combobox. When a user clicks a feature in that layer in the combobox, the map will zoom to that feature.

I've put together the following code, but I'm definitely on the wrong track.  Any help is appreciated.
<?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:esri="http://www.esri.com/2008/ags"
      pageTitle="Map Extent and Mouse Coordinates" 
      creationComplete="combobox()">
 
 <fx:Script>
  <![CDATA[
   
   import mx.collections.ArrayCollection;
  
   private function combobox():void
   {
    var comboArray:ArrayCollection = new ArrayCollection();
    comboArray = comm_layer.layerInfos.Communities_Places //the specific layer in the map service
    cmb.dataProvider = comboArray;
    cmb.labelField = comboArray.comm_name_ //field within the Communities_Places layer
   }
     
  ]]>
 </fx:Script>
 
 <s:layout>
  <s:VerticalLayout paddingTop="6"/>
 </s:layout>
 
 <s:HGroup>
  <s:ComboBox id="cmb" right="250"/>
 </s:HGroup>
 
 <esri:Map id="myMap">
  <esri:extent>
   <esri:Extent xmin="-13338986.2116637" ymin="3926661.77417242" xmax="-13002755.460699" ymax="4152028.76378653">
    <esri:SpatialReference wkid="3857"/>
   </esri:Extent>
  </esri:extent>
  <esri:ArcGISDynamicMapServiceLayer id="comm_layer" url="http://10.2.8.73/ArcGIS/rest/services/ZNET_Public/city_maskForExtent/MapServer"/>
 </esri:Map>

</s:Application>


Thanks,
Jason
Tags (2)
0 Kudos
12 Replies
RobertScheitlin__GISP
MVP Emeritus
Jason,

   I think you are missing something here... The only way you can get the attributes and geometry for a specific layer IS to use a query. LayerInfo only has the layer name and it's id, definitely does not contain it's geometry of each individual feature.
0 Kudos
JasonLevine
Deactivated User
Yah, I was definitely missing something here.  I figured it out.

Thanks for pointing me in the right direction,
Jason
0 Kudos
DasaPaddock
Esri Regular Contributor
Here's a sample too:

<?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:esri="http://www.esri.com/2008/ags">

    <fx:Script>
        <![CDATA[
            import com.esri.ags.Graphic;
            import com.esri.ags.events.MapEvent;
            import com.esri.ags.events.QueryEvent;
            import com.esri.ags.geometry.Extent;
            import com.esri.ags.tasks.supportClasses.Query;

            import mx.collections.ArrayList;

            import spark.events.IndexChangeEvent;

            protected function map_loadHandler(event:MapEvent):void
            {
                var query:Query = new Query();
                query.outFields = [ "STATE_NAME" ];
                query.outSpatialReference = map.spatialReference;
                query.returnGeometry = true;
                query.where = "1=1";
                queryTask.execute(query);
            }

            protected function queryTask_executeCompleteHandler(event:QueryEvent):void
            {
                ddList.dataProvider = new ArrayList(event.featureSet.features);
            }

            protected function ddListLabelFunction(item:Graphic):String
            {
                return item.attributes["STATE_NAME"];
            }

            protected function ddList_changeHandler(event:IndexChangeEvent):void
            {
                var stateExtent:Extent = Graphic(ddList.selectedItem).geometry.extent;
                map.extent = stateExtent

                // make sure the whole extent is visible
                if (!map.extent.contains(stateExtent))
                {
                    map.level--;
                }
            }
        ]]>
    </fx:Script>

    <fx:Declarations>
        <esri:QueryTask id="queryTask"
                        executeComplete="queryTask_executeCompleteHandler(event)"
                        showBusyCursor="true"
                        url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5"
                        useAMF="false"/>
    </fx:Declarations>

    <s:controlBarContent>
        <s:DropDownList id="ddList"
                        width="200"
                        change="ddList_changeHandler(event)"
                        labelFunction="ddListLabelFunction"
                        prompt="Choose a state to zoom to"/>
    </s:controlBarContent>

    <esri:Map id="map" load="map_loadHandler(event)">
        <esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"/>
    </esri:Map>

</s:Application>
0 Kudos
JasonLevine
Deactivated User
Hi Dasa,
   I'm using a comboBox instead of a dropdown list.  I managed to populate it correctly, but I can't seem to get my change function figured out:
<?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:esri="http://www.esri.com/2008/ags"
      pageTitle="Map Extent and Mouse Coordinates" 
      creationComplete="combobox()">
 
 <fx:Script>
  <![CDATA[
   import com.esri.ags.FeatureSet;
   import com.esri.ags.Graphic;
   import com.esri.ags.events.QueryEvent;
   import com.esri.ags.tasks.QueryTask;
   import com.esri.ags.tasks.supportClasses.Query;
   import com.esri.ags.utils.GraphicUtil;
   
   import mx.collections.ArrayCollection;
  
   private function combobox():void
   {
   var comboQueryTask:QueryTask = new QueryTask();
   comboQueryTask.url = "http://10.2.8.73/ArcGIS/rest/services/ZNET_Public/city_mask/MapServer/0";
   comboQueryTask.useAMF = false;
   var comboQuery:Query = new Query();
   comboQuery.returnGeometry = true;
   comboQuery.where = "1=1";
   comboQuery.outFields = ["CITY_COMM_"];
   comboQuery.outSpatialReference = myMap.spatialReference;
   comboQueryTask.execute(comboQuery);
   comboQueryTask.addEventListener(QueryEvent.EXECUTE_COMPLETE, onQueryComplete);
   }
   
   private var commExtent:Extent = new Extent();
   private function onQueryComplete(event:QueryEvent):void
   {
    var featureSet:FeatureSet = event.featureSet;
    var results:ArrayCollection = new ArrayCollection();
    for each (var graphic:Graphic in featureSet.features)
    {
     var fieldValue:String = graphic.attributes["CITY_COMM_"].toString();
     results.addItem({label: fieldValue, data: graphic});
    }
    cmb.labelField = "label";
    cmb.dataProvider = results;
    var graphicsExtent:Extent = GraphicUtil.getGraphicsExtent(featureSet.features);
    commExtent = graphicsExtent;
    
   }
   
   private function change():void
   {
    var extent2:Extent = Graphic(cmb.selectedItem).geometry.extent;
    myMap.extent = extent2;
   }
   
     
  ]]>
 </fx:Script>
 
 <s:layout>
  <s:VerticalLayout paddingTop="6"/>
 </s:layout>
 
 <s:HGroup>
  <s:ComboBox id="cmb" right="250" change="change()" width="350" selectedItem="{{label:'Select Your Community'}}"/>
 </s:HGroup>
 
 <esri:Map id="myMap">
  <esri:extent>
   <esri:Extent xmin="-13338986.2116637" ymin="3926661.77417242" xmax="-13002755.460699" ymax="4152028.76378653">
    <esri:SpatialReference wkid="3857"/>
   </esri:Extent>
  </esri:extent>
  <esri:ArcGISDynamicMapServiceLayer id="comm_layer" url="http://10.2.8.73/ArcGIS/rest/services/ZNET_Public/city_maskForExtent/MapServer"/>
 </esri:Map>

</s:Application>


What am I doing wrong?

Thanks,
Jason
0 Kudos
DasaPaddock
Esri Regular Contributor
In my sample I'm putting the Graphics into the dataProvider. You're creating new Objects with a data property that points to the Graphic, so in your change handler try:

var extent2:Extent = Graphic(cmb.selectedItem.data).geometry.extent;
0 Kudos
JasonLevine
Deactivated User
That makes complete sense.  Thank you Dasa, and Robert, for your help with this.

-Jason
0 Kudos
LemvigKommune
Deactivated User
Hi all

i've used this code and put it into a widget, with the corresponding xml-file.

and it's working well with just one Url, but i've would like it to iterate over more urls and put it all into the same arraycollection, but that i can't get to work.

this is a part of the xml-file.
<layer>
 <layerurl>http://gis.rksk.dk/ArcGIS/rest/services/AdresseLokalplan/MapServer/0</layerurl>
 <layeroutfield>ADR_NR_POST</layeroutfield>
 <layerzoomscale>1500</layerzoomscale>
</layer>


and this is a part of the mxml-file.
                                var lyrList:XMLList = configXML..layer;
    for (var i:int = 0; i < lyrList.length(); i++)
    {
     layerURL = lyrList.layerurl;
     layerOutField = lyrList.layeroutfield;
     layerZoomScale = lyrList.layerzoomscale;
    
    var comboQueryTask:QueryTask = new QueryTask();
    comboQueryTask.url = layerURL;
    comboQueryTask.useAMF = false;
    var comboQuery:Query = new Query();
    comboQuery.returnGeometry = true;
    comboQuery.where = "1=1";
    comboQuery.outFields = [layerOutField];
    comboQuery.outSpatialReference = map.spatialReference;
    comboQueryTask.execute(comboQuery);
    comboQueryTask.addEventListener(QueryEvent.EXECUTE_COMPLETE, onQueryComplete);
}

private function onQueryComplete(event:QueryEvent):void
   {
    var featureSet:FeatureSet = event.featureSet;
    for each (var graphic:Graphic in featureSet.features)
    {
     var fieldValue:String = graphic.attributes[layerOutField].toString();
     results.addItem({label: fieldValue, data: graphic});
    }   
    var graphicsExtent:Extent = GraphicUtil.getGraphicsExtent(featureSet.features);
    commExtent = graphicsExtent;    
   }
    


when i put more <layer> into the xml-file it fails

how do i get it to run the onQueryComplete function after each iteration ?

Thx in advance

Mads Gren
Lemvig
Denmark
0 Kudos
GeorgiannaStrode
Deactivated User
Hi Paddock:

I tried your sample codes but it does not work well in my case.

I replaced STATE_NAME in your codes with the field name I want to query in, and replace the two urls with the url of the specific layer where the field is in, and the url of the map server. When I run it and click the icon, it keeps spinning. I dont know which part I am doing wrong.

I would really appreciate it if you could help me on that.
0 Kudos
JuneAcosta
Frequent Contributor
Dasa,

I used the code you posted with a point layer. I get weird results with the zoom... does the code work for a point layer or just for a polygon layer?

june
0 Kudos