分享

ArcGIS API for Flex入门

 昵称QAb6ICvc 2017-08-24

摘要:ArcGIS最新推出了Flex API,主要面向基于ArcGIS Server 的RIA开发。RIA近来越来越火热,Flex/Flash在RIA领域又是绝对的翘楚,ArcGIS在这个时候推出Flex API实在是太理所当然了。如果你还不太了解Flex,那么你可能会知道Adobe公司的Flash。作为现在主要浏览器均支持的一个必备插 件,Flash占据了Web浏览98%的市场份额。Flash可以整合图片、音频、视频、矢量图画、动画等各种资源,并提供良好的交互,因此在浏览器上可 以提供给用户非常良好的体验。这就是Flash流行的原因。

一. 概述

【环 境】ArcGIS Server 9.3,ArcGIS API for Flex 1.0 beta,Adobe Flex Builder 3

ArcGIS 最新推出了Flex API,主要面向基于ArcGIS Server 的RIA开发。RIA近来越来越火热,Flex/Flash在RIA领域又是绝对的翘楚,ArcGIS在这个时候推出Flex API实在是太理所当然了。

如果你还不太了解Flex,那么你可能会知道Adobe公司的Flash。作为现在主要浏览器均支持的一个必 备插件,Flash占据了Web浏览98%的市场份额。Flash可以整合图片、音频、视频、矢量图画、动画等各种资源,并提供良好的交互,因此在浏览器 上可以提供给用户非常良好的体验。这就是Flash流行的原因。

Flex则是Adobe最近推出的SDK,旨在帮助程序员进行Flash 开发。要知道,Flash里面的影片剪辑、时间线等等概念都是为动画美工所熟知的,但是和程序员的思维实在是大相径庭。因此,Adobe推出了这个可以使 用xml、ActionScript(在Flash中同样存在)进行编程的工具——Flex。当然,Flex可以做的事情,Flash都可以做。Flex 就像是一个作坊,在作坊里工作你就可以顺利生产出Flash(*.swf)来——况且,这个工作并不复杂。

在Flex和Flash中主要 的开发语言是ActionScript(以下简称as),这是一种语法结构和JavaScript很像的脚本语言,也是对Flash进行控制的根本方法。 其实,Flex只需要as就可以工作了,其提供的mxml(xml)只不过为了方便开发人员进行布局和快速开发的一个工具。mxml文件最终都会编译成 as脚本,并在Flash中执行。

ArcGIS API for Flex(以下简称FlexAPI)能帮助你做什么呢?事实上这个API是以Flex组件库的形式存在的。当你在你的Flex项目中添加了 FlexAPI,你可以像开发桌面程序一样拖动一个Flex控件到你的应用中,做些简单的设置就可以进行GIS操作:浏览、查询……你可以想象一下你正在 使用ArcEngine进行开发……

二.配置开发环境和HelloWorld

在 这篇叙述如何进行开发环境配置的文档中,最后测试环境时使用了Flex API的一个Sample。我们来看一下那个Sample的具体内容(“Tutorial_Map.mxml”)。

在 “mx:application”元素(顾名思义,这就定义了一个Flex应用)中首先定义了mx和esri,它们分别是Flex和ArcGIS的命名空 间,通过命名空间就可以引用到相应的内容,比如“esri:Map”对应的就是API中的com.esri.ags.Map这个类。

事实 上,mxml文件会首先被编译成ActionScript,通过mxml定义和通过ActionScript定义在效果上是等效的。比如在mxml中添加 标签:
esri:Map
等同于as脚本:
import com.esri.ags.Map; 
var map:Map= new Map();


继续来看这个Sample,在定义了Map以后,又往其中添加了2个元 素:extent和ArcGISTiledMapServiceLayer。也就是在新建了一个Map以后,设定了当前的可视范围,然后再添加了一个切片 图层。做完这几步简单的工作以后,Map就可以渲染出一幅漂亮的地图了。我们可以看到,使用ArcGIS API for Flex来开发是一件非常简单的事情。

好,下面我们试着用ActionScript来替换xml标签来做相同的事情:
运行它,你 可以看到,效果和原来的Sample是完全一样的。

三.数据的绑定

在这一小节里,我们主要讨论数据绑定的问题。事实上这 是属于Flex的范畴,如果你对Flex语言很熟悉,那你完全可以跳过这一节。

在前面的小节,我们已经学会了如何在 FlexApplication中加入一个Map组件,并且在Map组件中添加了一个ArcGISTiledMapServiceLayer图层,当 然,ArcGISFlex不仅支持切片图层,还有ArcGISDynamicMapServiceLayer、 ArcGISMapServiceLayer、ArcGISImageServiceLayer、ArcIMSMapServiceLayer,这些类型 的图层都可以顾名思义,熟悉ArcGISServer的你肯定不陌生。

这时,如果你想要实现这样的功能:点击一个按钮(或者选中下拉框的 一个选项),当前的Map中的地图就自动地切换——就像GoogleMap一样,你可以选择卫星图或者切片地图。当然,你可以这样做:在每个按钮的 Click事件中,获得需要更新的图层URL,然后通知Map:换图层了!没有任何问题,但是,在Flex有更加“面对对象”的方法:数据绑定。

我 是一个很懒的人,所以我经常引用的代码就是ArcGISAPI for Flex自带的Sample(后面我说的Sample就是FlexAPI的例子,我就不重复说明了,这样的简称应该没有诸如RTFM之类的难懂吧)。这次 也不例外,让我们打开Sample中的agol.mxml。
我们注意,在Map元素的属性中,有一个url定义,当然这就是地图服务的地址。然而这个地址并不是一个通常 的字符串,在其中嵌入了一段“{servicePicker.selectedItem.toString()}”。这个servicePicker是什 么呢,往下看几行,我们可以看到,在这个FlexApplication中的ComboBox的id是servicePicker,这个ComboBox 就是供你来选择地图服务的。顺便提一下,Flex背后站着的其实是Flash,因此id在Flex中有着非常重要的作用。

好,我们看看这 段代码到底是什么意思。Flex组件默认监听了名为propertyChange的事件,当自身的数据改变的时候,它就会分发这一事件,这时,使用花括号 括起来的对象就会接受到对应的事件并更新自身的数据。“{servicePicker}”监听的是id为servicePicker的下拉框的组件,当我 们在下拉框选择了某个地图服务的时候,“{servicePicker.selectedItem.toString()}”就会根据这个下拉框的选择项 生成一个字符串,再把字符串拼接到Map的url属性中去。Map就会根据新的url获取数据并进行渲染。这就是一种“面对对象”的数据处理方式。

四.事件Event

前面讨论的主要是怎么样去操作Map,设定各种数据啊,通知它更新数据源啊等等。目前,你已经可以通过ArcGIS API for Flex渲染各种漂亮的地图了。下面,我们应当来想想怎么来做更多的事情了。

比如在你的Flex Application中,你希望在用户在点击Map的时候,获取到用户点击的坐标,然后到数据库去查找附近是不是有好吃的餐馆之类的。这个时候你应该想 到我们应该要处理Map的事件了。

这里插播一句,ArcGIS API for Flex最重要的就是Map组件,你完全可以把Map组件等同于其他原生的Flex组件来使用。——所以,如果你很熟悉Flex,那么本小节下面的内容你 可以跳过了。

好,我们打开Sample的“EventBasics.mxml”,在 onApplicationCreationComplete()方法(它监听了Application的创建完成事件)中,其中添加了Map组件的鼠标 click事件监听器:
       myMap.addEventListener(MouseEvent.CLICK, logMouseEvent);
其中的 logMouseEvent在下面进行了定义:
        public function logMouseEvent(event:MouseEvent):void
         {
                log.text = "* MouseEvent: " + event.type + "\n" + log.text;
        }

每当用户在Map上进行点击时,Map就会自动分发 MouseEvent.CLICK事件,而监听Click事件的logMouseEvent()方法就会被执行。运行一个这个 “EventBasics.mxml”,试着在地图上点击几下,有没有看到右面的文本变化?

当然,ArcGIS 的Map组件提供了许多的Event,涵盖地图操作、图层操作、查询操作、绘图操作等等,你可以在此基础上实现任何你想实现的功能。

五.任务Task

Task是ArcGIS Server的重要组成部分,一个Task可以执行某些特定的任务,比如Identify、Query等等。在这个小节,我们通过 IdentifyTask来认识Task的使用方法。

IdentifyTask是一个可以识别要素的任务,让我们打开Sample的 “IdentifySample.mxml”,看一下其中核心的代码。

我们首先注意一下在Flex Application中添加了这样一个IdentifyTask的标签:

我们设想的功能大概是这样的:先在地图上画一个多边形,然后识别多边形内的所有要素,最后在图上标注 出来。让我们看一下这个功能在Flex中是如何通过Task执行完成的:

首先是绘图,我首先需要在地图上画一个多边形,在ArcGIS API for Flex中有一个提供绘图的工具条com.esri.ags.toolbars.Draw,通过它我们可以很轻松地实现绘图功能:
上 所示,IdentifySample在Draw对象上添加一个事件监听器,当绘图完成时,执行drawEndHandler()方法,在这个方法中,我们 将继续绘图以后的工作。

在已经绘制了一个多边形以后,我们就需要执行IdentifyTask来进行要素识别了。先看一下代码:
          private function drawEndHandler(event rawEvent):void
            {
                var geometry : Geometry = event.geometry;

                var identifyParams : IdentifyParameters = new IdentifyParameters();
                identifyParams.returnGeometry = true;
                identifyParams.tolerance = 3;
                identifyParams.width = 600;
                identifyParams.height = 550;
                identifyParams.geometry = geometry;
                switch (layerOption.value)
                {
                    case "top":
                       identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_TOP;
                       break;
                    case "visible":
                       identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_VISIBLE;
                       break;
                    case "all":     
                       identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_ALL;
                       break;
                }
                identifyParams.mapExtent = map.extent;


                identifyTask.execute( identifyParams );
           }

在DrawEvent对象中,我们可以获取刚才绘图的 Geometry对象,这个Geometry对象用于Identify的参数设置中,如果你做过ArcEngine开发,你可以对比一下 SpatialFilter。好,再设置了一下需要搜索的图层和范围以后,你就可以执行这个IdentifyTask了,看到execute是不是很兴 奋?

然后呢?我们回头看看这个IdentifyTask的定义,其中注册了当Task完成时候执行的方 法:identifyCompleteHandler()。
           private function identifyCompleteHandler(event:IdentifyEvent):void
           {
               for each (var result:IdentifyResult in event.identifyResults)
               {
                   myGraphicsLayer.add(result.feature);
               }
           }
看明白了么?这个方法就是在GraphicLayer上把这个Task的结果画出来。

通过这个流程,你 应该明白了Task的作用和用法了吧。


六.有多少Task可以重来

上一小节我们了解了 FlexAPI中的Task用法,你可以把Task想象成一条命令,当你把命令发送到服务器的时候,服务器会执行并返回给你结果——当然,前提是要服务器 提供这个服务。上一节的例子是IdentifyTask,其它的Task大抵也可以触类旁通。可是,API的Task包的命名因为不同Task的功能不同 而并不很一致,有些Task的名称并不是以Task结尾,同时,并不是所有的Task都可以execute。所以,我们在这一小节重点讨论一下各种 Task的作用和用法。

1.FindTask
这是一个很简洁的Task,它的功能主要是通过 关键字来搜索要素的某些字段,如果符合则返回查找到的要素。你可以参考Sample的“FindTask.mxml”,下面是对Task定义的一些代码:
我们似乎已经可以摸到Task的一般套路,先生成一个参数对象,对这个Task需要完成的任务进行一些设定, 然后将Task与这些参数联系起来,最后执行等待服务器返回处理结果。这个FindTask就是这样,简洁明了。

2.GeometryService
这 是对几何对象进行处理的一个Task,可是它是以Service结尾,这代表它并不简单地给你execute一下的,它提供了处理多种任务的能力。比如缓 冲(buffer)、量测(lengths)等等。让我们打开Sample的“BufferSample.mxml”看看,这是一个缓冲的例子。

我 们可以看到,处理的过程和其它Task也没什么区别,只不过没有了execute(有你也不知道到底执行什么命令),取代它的是明确的任务名称,比如要进 行缓冲,那就是用buffer方法:
myGeometryService.buffer( bufferParameters );

好,那么随之而来的一个问题就是执行完了怎么办,怎么区分不同命令返回的结果?事 实上,你只要监听不同的时间好了,比如你执行buffer命令,那么你就监听BUFFER_COMPLETE事件(mxml 中:bufferComplete="..."),好了,只要你的方法监听到这个事件,你就可以在buffer完成后进行后续的处理了。

3.Geoprocessor
这 是GP服务对应的Task。GP服务很灵活,因此你在设置Geoprocessor任务参数(Object对象)的时候,需要给予更多的注意。在用法上它 并没有很多新意,具体可以参考一下Sample的“GeoprocessorMessageInABottle.mxml”。

4.IdentifyTask
识 别要素,老朋友了,具体参考上一节。

5.Locator
从地址获得要素或者从要素获得地址的 Task。让我们打开Sample的“LocatorTask.mxml”看一下,下面是执行命令的代码:
locateTask.addressToLocations(addy, null, new AsyncResponder(onResult, onFault));

Locator主要提供两个命 令:addressToLocations()和locationToAddress()。它的参数也是Object对象,因此提供了灵活的参数设置和更 多出错的机会。

6.QueryTask
查询要素。FindTask是搜索某些字段文本的命 令,而QueryTask则提供了文本查询和空间查询的能力。sample中的“QueryTaskOnMap.mxml”是一个文本查询的例子。让我们 对它进行一些修改以进行空间查询:

执行查询的命令是queryTask.execute( query, new AsyncResponder( onResult, onFault ));
让我们在它之前加上:
                query.geometry = map.extent;
                query.spatialRelationship = Query.SPATIAL_REL_INTERSECTS;

上面的map是Map组件的id(自己添加),同时,把 query原先定义的text属性删除。让我们运行以后再点击查询,拖动一下地图,是不是看到只有原先视口中的要素被高亮了出来?这就是空间查询的结果, 因为上面执行的查询是以当前地图范围为过滤条件的。

7.API学习路线
如果我的这一系列文章不对你的胃口,或者你更喜欢 官方一点的学习文档,我这里整理了一些在线资源和建议的学习路线,供你参考:)

首先,你是否了解Flex,如果你还不了解Flex和它的 开发环境,那么可以到这里看看:
Flex 入门
Flex 语言参考

如果你对Flex已经有了一定了解,并准备开始使 用ArcGIS API for Flex,那么首先推荐看一个ESRI的在线视频教你如何配置开发环境,工欲善其事必先利其器嘛。
《Creating an application using the ArcGIS API for Flex》

当你对Flex的MXML和 ActionScript语言都有所了解,同时已经配置好ArcGIS API for Flex并且可以创建Flex应用以后,案例驱动是最好的学习方法,下面是ArcGIS API for Flex的在线Sample及其源代码。
ArcGIS API for Flex 在线Sample

在 开发过程中,对ArcGIS API for Flex有任何疑问,最好的解决办法是查看API参考:
ArcGIS Flex API参考

最 后,说点和ArcGIS API forFlex无关的话题,那就是Flex在WebGIS中的作用。使用Flex最大的好处是无需对原来的GIS系统和网站进行重新设计和架构,只需适时 嵌入Flex应用即可达到非常好的效果。在这里,再附上一个Flex 3DMap的演示,看了这个演示你会对Flex如何促进WebGIS应用的表现能力有更为直观的了解:
http://thunderhead./readonlyurl/HeatMap3D.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章