2010年8月19日周四_insideTheAPI_usingQuery_6.3

/******************************************************************************************************/

//Using Query

//Version 2.0

//2010年8月19日_周四

/******************************************************************************************************/

Working with Queries

NOTE: The following discussion assumes that you are familiar with the basic concepts of Flex.

Query Task

In this tutorial, you will learn how to use a query task to query information from an ArcGIS Server service. You will use Query, QueryTask, and FeatureSet to query a layer in a map and display the results. There are usually four steps involved in a query process:

Setting up the Map and GraphicsLayer

Setting up the query task with a query filter

Executing the query task with user inputs, for example - by selecting features on a map, choosing a value from a list, or typing a value.

Displaying 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.

//

查询

注意:下面的讨论假设你熟悉基本的Flex概念。

查询任务

在这个教程里面你,你将会学习如何使用Querytask来查询来自AcGISServer 服务中的信息。你将会使用Query,QueryTask,和FeatureSet对地图中的一个图层进行查询并展示查询的结果。 在一个查询处理中通常有四个步骤:

1:设置Map和GraphicLayer

2:设置Query Task和query filter。

3:使用用户的输入来执行查询,比如:在地图上选择一个Features,从一个列表中选择一个值,或者输入一个值。

4:展示FeatureSet中返回来的查询结果。FeatureSet集合了所选择要素的空间信息和属性信息 。geometry可以用于在地图上高亮显示Features,attributes(属性信息)可以用来填充DataGrid和ToolTip。

The example below 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 complete code at the end of this 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 code snippet() below 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", that will be explained later.

<esri:Map id="map">

    <esri:ArcGISTiledMapServiceLayer

        url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/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 sample).

下面的例子是一个QueryTask的例子,在这里用户输入一个程序的名称、基于这个输入,所有的城市中和这个城市名称相匹配的都显示在地图上。在本章的结尾查看完整的代码。

设置图层

地图和他的图层被用来作为北京来展示查询的结果。GraphicsLayer被用来符号化和展示查询结果的geometry信息。 下面的代码显示一个使用了ArcGISServer tiled 地图服务图层,并且map对象添加了一个Graphic Layer. 被graphics图层renderer的要素集将会使用由infoSymbol1定义的样式。这个而将会在后面讨论。

<esri:Map id="map">

    <esri:ArcGISTiledMapServiceLayer

        url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer"/>

    <esri:GraphicsLayer id="myGraphicsLayer" symbol="{infoSymbol1}"/>

</esri:Map>

并不是在任何的时候都需要一个地图来执行查询。 当你仅仅想使用一个QueryResults来填充一个DataGrid的时候,是不需要一个Map对象的。

Setting up the query task

The QueryTask sets up the URL of the layer that the query will work with. Note the URL includes the layer ID. In the code example below 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 (shorthand for a WHERE clause using LIKE operator) that is bound to the value of a text input component that we will see later. The field used is the display field defined in the map document. You can determine the display field for a layer in Services Directory. Since we want to display the results of our query we set the attribute "returnGeometry" to true.

In this example, a list of output fields is included in outFields. When you specify the output fields, you should 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 will be. You must use the actual field names rather than the aliases (the aliases can be used in the results).

设置查询任务

QueryTask 设置一个URL指向一个图层,QueryTask就是和这个图层一起工作。,注意:URL中包含图层的ID。在下面的例子中,图层的的ID值为0。<esri:QueryTask id="queryTask" url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/0" />

Query定义了查询的准则,这些准则将会在查询中使用。 真正的Filter是由”TEXT”属性的设置的,这个属性和一个text输入组件想绑定,我们在下面也见将看到这个组件。使用的field也是在地图文档中定义的field。你可以在服务路径为一个图层定义显示的display字段值。因为我们想展示查询的结果,所以我们设置returnGeometry属性为true。

在这个例子中,一系列的输出fields包含在outFields中。 当你指定了output fields,那么你就要限制在查询或者结果使用的字段值包含在这些你想使用

的字段值当中。包含的字段值越少,反映也就越快。你必须使用真实的字段名称而不是字段的别名(别名可以在查询结果中使用)。

<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>

Executing the query

In an application the query is executed based on inputs provided by the user. In the example below a panel is created with a text input for typing the name of the city to search and a button to execute the query. The click event of the button calls the doQuery() method, the first argument is the query criteria that we had previously defined and the second argument is an asynchronous responder. The responder sets the callback functions onResult() and onFault() that handles the success and failure of the query respectively.

执行查询

在一个应用程序中,查询的执行是基于用户提供的输入信息。在下面的例子中,创建了一个panel,里面包含一个text输入控件,用来输入要搜索的城市名称,以及一个用来执行查询的按钮。 Button的单击事件调用doQuery()方法,第一个参数是我们在前面就已经定义好的擦和查询的先限制,第二个参数是一个反应,这个反应设置了Cllback函数onResult()和onFault()函数处理成功和失败的查询。

<mx:Panel title="Search for a city" layout="horizontal"

    backgroundColor="0xB2BFC6" borderStyle="solid">

    <mx:TextInput width="100%" id="qText" enter="doQuery()" text="San Jose"/>

    <mx:Button label="Do Query" click="doQuery()"/>

</mx:Panel>

private function doQuery():void

    {

        queryTask.execute(query, new AsyncResponder(onResult, onFault));

    }

Displaying query results

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.

You may remember that when we added the graphics layer we set the symbol to "infoSymbol1". The code below 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 example below, "data.CITY_NAME" and "data.STATE_NAME" are the outfields that we previously set in the query.

展示查询结果

展示查询结果涉及到添加到一个symbology到graphic图层,并将Graphic本身添加到Graphic图层。Symbology可以被直接应用到一个grapihc图层,所有添加到这个Graphic图层中的Graphic都会继承这个symbology。

你可能会想起,当我们添加一个Graphic图层,我们设置symbol为” infoSymbol1”.下面的代码展示了infoSymbol1的声明,infoSymbol1是一个InfoSymbol类型。InfoSymbol有一个infoRenderer,它定义了信息是如何被renderer的。 在下面的例子中,"data.CITY_NAME"和"data.STATE_NAME"是我们在前面在Query中定义的outfields。

If the component that you use as the infoRenderer has in its inheritance chain a parent that implements IDataRenderer then all the attributes of the graphic are available via the "data" property. In the example below the component "VBox" has a parent "Container" that implements the IDataRenderer. For more information refer to the Adobe Flex 3 Language reference.

如果你把component当做infoRenderer使用,并且他有一个实现了IdataRenderer的父容器,那么Graphic所有属性通过Data属性都是可以获取的。在下面的例子当中,VBOX组件有一个父容器实现IdataRenderer。 更多的消息请查询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 example below show an alert box with information about the failure.

查询成功完成后,回调函数onResult()被调用。 其中的一个参数就是FeatureSet对象,她包含着查询的结果。FeatureSet的Features可以被直接分配到Graphic 图层的graphicProvider,然后再地图上提供。

如果查询失败回调函数onFault()被调用。在下面的例子中,onFault()函数通过一个对话框展示失败的相关的信息

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 complete code for the scenario discussed in this section is below,

<?xml version="1.0" encoding="utf-8"?>

<s:Applicationxmlns: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 States -->

        <esri:QueryTask id="queryTask"

                        showBusyCursor="true"

                        url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5"

                        useAMF="false"/>

        <esri:Query id="query"

                    outSpatialReference="{myMap.spatialReference}"

                    returnGeometry="true"

                    text="{qText.text}">

            <esri:outFields>

                <fx:String>MED_AGE</fx:String>

                <fx:String>POP2007</fx:String>

            </esri:outFields>

        </esri:Query>

    </fx:Declarations>

    <s:Panel backgroundColor="0xB2BFC6"

             height="60"

             title="Query a layer (search for a state)">

        <s:layout>

            <s:HorizontalLayout/>

        </s:layout>

        <s:TextInput id="qText"

                     enter="doQuery()"

                     text="California"

                     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}"/>

    </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 list below 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 (MapPoint or MultiPoint) whenever possible.

展现,需要考虑的问题。

这里有一个直接的联系,在于表现和选中的features的数量。一些查询是不现实或者查询的数据过多。 下面的有些增体验的一些建议。

如果一个很大数目的Feature被选中的话,他可能需要花费一些时间将Graphic绘制在地图上。Feature的种类当然也使他们产生了一些区别。点绘制的要比线和多边形要快,因此,如果可能尽量使用点Graphic(单个点,或者多个点)。

If you are retrieving tabular data and do not 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 (e.g., 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.0 is 1000 features (and 500 features for for ArcGIS Server 9.3). You can 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

Queries on cached layers do not 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.

如果你重新获取tabular 数据并且不打算添加Graphics到地图。你应该不需要返回geometry 。

如果基于查询原则的面积非常大,那么就限制在一个小的区域查询或者重新定义查询条件,因此在同一事件返回Features的数量就少。

为了防止请求查询的FEATURES没有数量的限制,使用MaxRecordCount设置查询Features的最大数量。 默认情况下,ArcGIS Server 10最大的查询数量是1000个Features。(ArcGIS Server 9.3版本下是500个)。你可以在配置文件中为制定的MapService设置MaxRecordCount。对于一个默认的window安装,配置文件在C:\Program Files\ArcGIS\server\user\cfg\[YourMapService].cfg。

基于缓存图层的查询没有比例依赖。这个就意味着,即使一个图层没有以一定的比例显示在地图上,那么她仍然可以从这个图层中查询Features.

原文地址:https://www.cnblogs.com/xingchen/p/1804127.html