Winter 2013

A Flex(ible) Power Legend

By Gido Langen, Surveyor General Branch, Government of Canada

This article as a PDF.

This article as a PDF.

The application at full extent with legend showing the United States

The application at full extent with legend showing the United States

Editor's note: This article shows how functionality can be added to a web map application using the ArcGIS API for Flex. This example shows one way to implement a dynamic legend. To examine the listings referenced in this article, download them from the ArcUser website.

While the ArcGIS API for Flex legend class suits most web mapping applications perfectly well, it limits users' control over layer visibility. Sometimes it would be desirable to give users just such control, especially where features are concentrated in small areas. For example, small pockets of federally administered land spread across the country may contain many individual features from numerous classes. Users may want to change the visibility of one layer versus another dependent on their specific needs.

One layer turned off in legend

One layer turned off in legend

This article presents the implementation of a dynamic legend using the ArcGIS API 3.0 for Flex that permits scale-dependent layer availability similar to that of the native legend class but also gives users the capability of turning individual layers on and off. In addition, it is spatially aware—the legend changes based on the spatial extent of features in an associated graphics layer. Group and layer parameters are controlled by an XML legend file on the server;Listing 1 shows lines from a sample of this XML legend file. The entire file is available from the sample dataset for this article.

On start-up, the compiled SWF file reads the XML legend file that is enclosed by the <layers> </layers> element. It includes two tags: <group> and <layer>. Each group tag can include multiple layer tags. Both tags have multiple attributes whose values are used to build the legend in the Flex panel. Each name attribute becomes a legend entry, and the minscale and maxscale attributes define the visibility of groups and layers.

So far, there is nothing new in this process. But wait—the code creates a check box for each <group> and <layer> tag, allowing users to interactively turn them on and off.

One layer invisible in legend

One layer invisible in legend

Better yet, all <group> and <layer> tag entries are spatially aware. The code uses a graphics layer to further control visibility. In this example, the graphics layer includes polygons that represent individual US states. The screen center location determines the currently active state and its FIPS code.

A group or layer only becomes visible if the FIPS code is within the range of values listed in the tag's states attribute. If it is, the legend dynamically changes. Each <layer> tag also has an id attribute that has a value that corresponds to the layer ID value used by the map service. These values are used to set the visibleLayers array of the map service. Tiny PNG files (measuring only 28 by 16 pixels) are used to represent the symbol for each layer.

To see an example of a larger web application built using this method, visit the Natural Resources of Canada website.

Making the Code Work

Follow these five steps to make the example in Listing 2 work:

  1. Type the sample legend.mxml code into your Flash Builder code window.
  2. Create the four PNG files and save them in the Flash Builder SRC directory.
  3. Create the legend.xml listing as an ASCII text file and save it in the BIN-DEBUG directory.
  4. Run the code. All spatial data referenced is available from ArcGIS Online.
  5. Run the application, zoom in and out, and pan around in the web page.
The legend showing only the Eastern region

The legend showing only the Eastern region

This sample was compiled using Flash Builder 4.6 and the ArcGIS API 3.0 for Flex.

Further Information

For more information, contact Gido Langen, geomatics applications specialist for the Surveyor General Branch, at 780-495-2399 or gido.langen@NRCan.gc.ca.

About the Author

Gido Langen has more than 20 years of work experience with Esri products. He loves making the software accessible to users and helping them exploit their data.

Listing 1: XML legend file

<group id="2002" name="Western US" minscale="9541235" maxscale="0"
     states="US,AK,WA,OR,CA,HA,HI,ID,MT,WY,NV,UT,CO,AZ,NM" checked="true" expanded="true">
   <layer id="1" name="State names" minscale="30000000" maxscale="5000000"
     states="US,AK,WA,OR,CA,HA,HI,ID,MT,WY,NV,UT,CO,AZ,NM" checked="true"/>
   <layer id="0" name="Highways" minscale="20000000" maxscale="1000000"
     states="US,AK,WA,OR,CA,HA,HI,ID,MT,WY,NV,UT,CO,AZ,NM" checked="true"/>
   <layer id="2" name="Counties" minscale="50000000" maxscale="0"
     states="US,AK,WA,OR,CA,HA,HI,ID,MT,WY,NV,UT,CO,AZ,NM" checked="true"/>
</group>
Listing 1: A portion of the legend.xml file used to create the legend in the Flex panel

Listing 2: XMXL legend file

// Establishes map layers and "spatially aware" states graphics layer
private function initApp():void {

     var MapLayers:Array = new Array(); // Array that references that three layers of the map service
     MapLayers.push(0); //highways
     MapLayers.push(2); //counties
     MapLayers.push(1); //state names
     MapService.visibleLayers = new ArrayCollection(MapLayers);

     // Query on the States layer to get all the states as graphics to populate
     // "spatially aware" graphics layer
     qytStates.execute(qryStates, new AsyncResponder(onResult, onFault));
     function onResult(featureSet:FeatureSet, token:Object = null):void {
         States.graphicProvider = featureSet.features;
         refreshLegend();
     }

     // A problem might occur on initial load
     function onFault(info:Object, token:Object = null):void {
         Alert.show(info.toString(), "Query Problem");
     }
}

// Reads legend.xml file and add an event if the loading is successful
// onLegendLoaderComplete
private function initLegend():void {
     var LegendLoader:URLLoader = new URLLoader();
     LegendLoader.load(new URLRequest("legend2.xml"));
     LegendLoader.addEventListener(Event.COMPLETE, onLegendLoaderComplete);

     // Populates global variable LegendXML on successful loading
     // this variable contains the content of legend.xml file
     // will be used to create the contents of legend panel
     function onLegendLoaderComplete(evt:Event):void {
        LegendXML = new XML(evt.target.data);
Listing 2: A portion of legend.xmxl code showing that map layers are established and made spatially aware to influence the legend display (Download legend.mxml and legend.xml.)
Contact Us | Privacy | Legal | Site Map