Using Query

Version 3.7

Tip:

In addition to using a query task, you may also want to consider working with a FeatureLayer as it provides similar functionality. More information can be found at the FeatureLayer topic in addition to the sample, Search with FeatureLayer.

Query task

In this topic, you will learn how to use a query task to query information from ArcGIS for Server service. You will use Query, QueryTask, and FeatureSet to query a layer in a map and display the results. The typical four steps involved in a query process are as follows:

  1. Set up the Map and GraphicsLayer.
  2. Set up the query task with a query filter.
  3. Execute the query task with user inputs, for example, by selecting features on a map, choosing a value from a list, or typing a value.
  4. Display the query results returned in a FeatureSet. The FeatureSet is comprised of both geometry and attributes of the selected features. The geometry can be used for highlighting the features on the map and attributes can be used to populate a DataGrid or a ToolTip.

The example used in this topic is a QueryTask where the user types in the name of a city. Based on this input, all cities that match the name are displayed on the map. See the complete code at the end of the Executing the query section.

Setting up the layers

The Map and its layers are used to provide a context to displaying the query results. The GraphicsLayer is used to symbolize and display the geometries of the query results. The following code snippet shows a map with an ArcGIS Server tiled map service layer and a graphics layer added to the map. The features that are rendered by the graphics layer will use the symbol defined by infoSymbol1, which is explained later in this topic.

<esri:Map id="map">
    <esri:ArcGISTiledMapServiceLayer
        url="http://server.arcgisonline.com/ArcGIS/rest/services/
             World_Physical_Map/MapServer"/>
    <esri:GraphicsLayer id="myGraphicsLayer" symbol="{infoSymbol1}"/>
</esri:Map>

It is not always necessary to have a map to perform a query. In situations where you just want to populate a DataGrid with the query results, a map is not needed. See the Query result in table sample as an example.

Setting up the query task

The QueryTask is set to a uniform resource locator (URL) of the layer that the query will work against. The URL includes the layer ID. In the following code example, the layer ID is 0:

<esri:QueryTask id="queryTask"
    url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/
         Specialty/ESRI_StatesCitiesRivers_USA/MapServer/0"
/>

The Query defines the criteria that will be used for executing the query. The actual filter is set by the text attribute , i.e. shorthand for a WHERE clause using LIKE operator that is bound to the value of a text input component that is discussed later in this topic. The field used is the display field defined in the map document. You can determine the display field for a layer in the Services Directory. Since you're going to display the results of the query, set the returnGeometry attribute to true.

In this example, a list of output fields is included in outFields. When you specify the output fields, limit the fields to only those you expect to use in the query or the results. The fewer fields you include, the faster the response. You must use the actual field names rather than the aliases although these aliases can be used in the results.

<esri:Query id="query" text="{qText.text}" returnGeometry="true">
    <esri:outFields>
        <mx:String>CITY_NAME</mx:String>
        <mx:String>STATE_NAME</mx:String>
    </esri:outFields> 
</esri:Query>

Note:

If querying a Featurelayer, set the returning outfields on the Featurelayer rather than the query. More about this and Featurelayers can be found at Feature Layer.

Executing the query

Displaying the results of the query involves adding the symbology to the graphic and adding the graphic itself to the graphics layer. The symbology can be applied directly to a graphics layer, and all graphics added to that graphics layer will then inherit that symbology.

Recall that when you added the graphics layer, you set the symbol to infoSymbol1. The following code shows the declaration of infoSymbol1, which is a symbol of type InfoSymbol. The InfoSymbol has an infoRenderer that defines how information is rendered. In the following example, data.CITY_NAME and data.STATE_NAME are the outfields that were previously set in the query.

If the infoRenderer component inherits from a parent that implements IDataRenderer, all the attributes of the graphic are available via the dataproperty. In the following example, the component VBox has a parent 'container' that implements IDataRenderer. For more information, refer to the Adobe Flex 3 Language reference.

<esri:InfoSymbol id="infoSymbol1">
    <esri:infoRenderer>
        <mx:Component>
            <mx:VBox>
                <mx:Label text="{data.CITY_NAME}"/>
                <mx:Label text="{data.STATE_NAME }"/>
            </mx:VBox>
        </mx:Component>
    </esri:infoRenderer>
</esri:InfoSymbol>

After the successful execution of the query, the callback function onResult() is called. One of the arguments to the function is a FeatureSet object that contains the results of the query. The features of the FeatureSet can be directly assigned to the graphicProvider of the graphics layer to be rendered on the map.

In case of a failure, the callback function onFault() is called, which, in the following example, shows an alert box with information about the failure:

private function doQuery():void
{
    queryTask.execute(query, new AsyncResponder(onResult, onFault));
    function onResult(featureSet:FeatureSet, token:Object = null ):void
    {
        myGraphicsLayer.graphicProvider = featureSet.features;
    }
    function onFault(info:Object, token:Object = null):void
    {
        Alert.show( info.toString() );
    }
}

The following is the complete code for the scenario discussed in this topic:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               xmlns:esri="http://www.esri.com/2008/ags"
               xmlns:s="library://ns.adobe.com/flex/spark"
               pageTitle="Query Task (with a map)">

    <s:layout>
        <s:VerticalLayout gap="10"
                          horizontalAlign="center"
                          paddingBottom="20"
                          paddingLeft="25"
                          paddingRight="25"
                          paddingTop="20"/>
    </s:layout>

    <fx:Script>
        <![CDATA[
            import com.esri.ags.Graphic;
            import com.esri.ags.FeatureSet;
            import mx.controls.Alert;
            import mx.rpc.AsyncResponder;

            private function doQuery():void
            {
                queryTask.execute(query, new AsyncResponder(onResult, onFault));
                function onResult(featureSet:FeatureSet, token:Object = null):void
                {
                    // No code needed in this simple sample, since the
                    // graphiclayer is bound to the query result using
                    // graphicProvider="{queryTask.executeLastResult.features}"
                }
                function onFault(info:Object, token:Object = null):void
                {
                    Alert.show(info.toString(), "Query Problem");
                }
            }
        ]]>
    </fx:Script>

    <fx:Declarations>
        <!-- Layer with US Cities -->
        <esri:QueryTask id="queryTask"
              showBusyCursor="true"
              url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/
                   Specialty/ESRI_StatesCitiesRivers_USA/MapServer/0"
                   useAMF="false"/>

       <esri:Query id="query"
             outSpatialReference="{myMap.spatialReference}"
             returnGeometry="true"
             text="{qText.text}">
          <esri:outFields>
             <fx:String>CITY_NAME</fx:String>
             <fx:String>STATE_NAME</fx:String>
          </esri:outFields>
      </esri:Query>
      
      <esri:InfoSymbol id="infoSymbol1">
         <esri:infoRenderer>
            <fx:Component>
               <mx:VBox>
                  <mx:Label text="{data.CITY_NAME}"/>
                  <mx:Label text="{data.STATE_NAME }"/>
               </mx:VBox>
            </fx:Component>
         </esri:infoRenderer>
      </esri:InfoSymbol>
    </fx:Declarations>

    <s:Panel backgroundColor="0xB2BFC6" height="60" 
       title="Query a layer (search for a city)">
       <s:layout>
          <s:HorizontalLayout/>
       </s:layout>
       <s:TextInput id="qText"
          enter="doQuery()"
          text="San Jose"
          width="100%"/>
       <s:Button click="doQuery()" label="Do Query"/>
    </s:Panel>

   <esri:Map id="myMap">
      <esri:extent>
         <esri:Extent xmin="-14298000" ymin="2748000" 
               xmax="-6815000" ymax="7117000">
            <esri:SpatialReference wkid="102100"/>
         </esri:Extent>
      </esri:extent>
      <esri:ArcGISTiledMapServiceLayer
       url="http://server.arcgisonline.com/ArcGIS/rest/services/
            World_Physical_Map/MapServer"/>
         <esri:GraphicsLayer
               id="myGraphicsLayer"
               graphicProvider="{queryTask.executeLastResult.features}"
               symbol="{infoSymbol1}"/>
   </esri:Map>
</s:Application>

Performance considerations

There is a direct correlation between performance and the number of features selected; certain queries are unrealistic or request too much data. The following list offers suggestions to enhance performance:

  • If a large number of features is selected, it can take some time to draw the graphics on the map. The type of feature also makes a difference. Points draw much faster than lines and polygons. Therefore, use point graphics, e.g. MapPoint or MultiPoint, whenever possible.
  • If you're retrieving tabular data and don't intend to add graphics to the map, you should not request geometry.
  • If queries are too large on a regular basis, limit the query to a smaller area or refine the query so fewer features are returned at one time.
  • To prevent queries that request unlimited numbers of features (for example, empty WHERE statements and statements that are always true), use MaxRecordCount to set the maximum number of features. By default, the maximum for ArcGIS Server 10.x is 1000 features, 500 features for ArcGIS Server 9.3. Prior to ArcGIS for Server 10.1, you could modify this for a specific MapService in its configuration file. For a default windows installation, the file is C:\Program Files\ArcGIS\server\user\cfg\[YourMapService].cfg. As of version 10.1, this can easily be configured when publishing your map service, see Editing service properties in Manager, specifically the Maximum Number of Records Returned by Server parameter listed in the Parameters tab on the left.
  • Queries on cached layers don't have scale dependencies. This means that features for a layer can be queried even if the layer is not displayed on the map for a given scale. Thus, your query should not be accessible for a layer if displaying the results does not make sense to the end user.


In this topic