ArcGIS RIA开发实践【Flex篇】

ArcGIS RIA开发实践【Flex篇】

I、 ArcGIS Flex API 基础
Flex的历史和现状

Flex的前身是Flash,Flash是极为流行的互联网矢量动画解决方案,目前据统计97%的浏览器都安装有Flash Player插件用以播放swf动画,其中未安装的3%还有很多是因为某些场合的安全限制导致的,可以说Flash是极为普及的RIA平台。

但是由于Flash是一个动画制作软件,其中有很多比如时间轴、影片剪辑等程序员不容易理解的概念,因此Macromedia公司推出了Flex。Flex抛弃了许多动画设计术语,转而使用程序员喜欢的方式开发RIA应用,并且Flex能编译生成可以在Flash Player中运行的swf文件,这无疑吸引了大量程序员,并且实现了和Flash平台的无缝拼接,从而利用Flash平台多年积累的大量素材、美工和设计者。

Adobe公司在2005年收购了Macromedia公司,并在第一时间将Flex/Flash冠以Adobe的商标推向市场,可见其对RIA市场和Flex/Flash的重视。

目前,可以说Adobe Flex/Flash是最流行且最成熟的RIA平台。

ArcGIS Flex API概述

ArcGIS Flex API是我自己使用的ArcGIS API for Flex的简称,在本文中将一直使用这个名称。

ArcGIS Flex API是ArcGIS在RIA领域的第一个产品,因此选择了最为成熟的Flex/Flash平台。使用ArcGIS Flex API可以开发运行于浏览器中的Web应用或者运行于桌面的AIR应用,它基于ArcGIS Server的REST接口,所有的功能都可以在REST SDK中找到影子。

使用ArcGIS Flex API开发的Flex应用可以非常便捷地使用地图功能和REST接口提供的GIS查询及分析功能;同时,ArcGIS Flex API专注于GIS功能的实现而不重复地创造组件,因此可以让你的业务和GIS方便地结合起来。

具体关于ArcGIS Flex API可以实现哪些功能,我们在下面的章节中将进行详细的讲解。

一些基本概念

首先,让我们先来了解一些ArcGIS Flex API中的基本概念。事实上你会发现这里的概念和桌面或ADF开发都有相通之处,不过为了强调一些重点,顺便介绍些ArcGIS Flex API中的特殊之处,这里还是先对这些内容做点介绍。

1 MapServiceLayer

MapServiceLayer对应的是ArcGIS发布的地图服务,它们是一对一的关系,每个地图服务在ArcGIS Flex API中都会以一个图层的形式出现。不同种类的地图服务将会对应不同的MapServiceLayer,ArcGIS Flex API中主要有以下几种MapServiceLayer:

ArcGISDynamicMapServiceLayer

ArcGIS Server发布的动态地图服务

ArcGISTiledMapServiceLayer

ArcGIS Server发布的切片地图服务

ArcGISImageServiceLayer

ArcGIS Image Server发布的影像服务

ArcIMSMapServiceLayer

ArcIMS发布的地图服务

2 GraphicLayer与Graphic

GraphicLayer并不对应到服务器端的某个地图服务,它完全是客户端的图层。因此,GraphicLayer在客户端数据表达方面有非常重要的作用,它可以根据各种情况动态地在客户端显示一些符号化的几何对象——Graphic。

ArcGIS Flex API中的Graphic是一个继承于UIComponent的类,因此它的表现和Canvas、Button等普通的Flex组件一样,在地图中Graphic就是一个可视化的、可响应鼠标事件的客户端要素。

Graphic有3个很重要的属性:geometry、symbol和attributes。其中geometry属性定义的是一个几何对象,它是Graphic的基础,因为Graphic要表达的就是这个几何对象;symbol属性则定义了这个几何对象通过什么符号表现出来;attributes则可以存放一系列与空间信息无关的属性数据。从上面可以发现,Graphic可以被理解成是一个在客户端符号化的要素。关于Graphic的geometry和symbol属性所对应的Geometry类和Symbol类,接下来在这里做一点更详细的说明。

3 Geometry

Geometry是GIS中很基本的概念,ArcGIS Flex API中定义了如下几何对象:

MapPoint

Multipoint

多点

Polyline

多段线

Polygon

多边形

Extent

边界范围

我们可以发现ArcGIS Flex API主要定义了点、线、面这些简单对象,事实上这和REST SDK中的几何对象是一一对应的,当ArcGIS Flex API和服务器交互的时候,这些几何对象都会被转化成字符串形式的JSON格式发送到服务器。

4 Symbol

Symbol定义了Geometry使用什么符号表现出来。在ArcGIS Flex API中,一般使用MarkerSymbol定义点的符号、LineSymbol定义线的符号、FillSymbol定义填充的符号,另外还有TextSymbol、InfoSymbol等其它符号帮助进行其它信息的辅助表达。下面列出的是ArcGIS Flex API中提供的常用的Symbol:

SimpleMarkerSymbol

简单点符号

SimpleLineSymbol

简单线符号

SimpleFillSymbol

简单填充符号

CartographicLineSymbol

制图线符号,可定义端点、折点样式

PictureMarkerSymbol

图片[1]点符号

PictureFillSymbol

图片填充符号

TextSymbol

文字符号

InfoSymbol

信息提示符号

CompositeSymbol

复合符号[2]

下面是上面这些符号的预览:

地图功能组件

在这小节中,我们主要介绍ArcGIS Flex API中对于一般地图功能的实现和使用。在这里让我们暂时先抛开“GIS”,去熟悉一下“地图”,毕竟地图是GIS可视化和功能交互的基石。

1 Map组件

Map是ArcGIS Flex API中唯一的可视化组件,它可以直接被放置到Flex应用中进行布局、展现。

Map可以被看作是一个地图, ArcGIS Flex API中所有的操作和功能都会在Map中进行,因此Map是一个特别重要的对象。如果在应用中有别的业务组件或模块需要和地图交互(比如把业务数据标到图上),那么只要它们可以获得Map对象的引用就可以了(比如一种做法就是在它们的构造函数中设置),所有和GIS相关的功能都可以通过Map来实现。

Map中包含各种Layer,这在GIS中非常容易理解——地图中需要加入若干个图层。在ArcGIS Flex API中,Map中的Layer有两种,一种是对应某个地图服务的MapServiceLayer、一种是用以绘制自定义要素的GraphicLayer,这里我们先看一下如何在Map中加载某个地图服务(MapServiceLayer)及其效果。

<esri:Map id="map">

<esri:ArcGISTiledMapServiceLayer

url="http://localhost:8399/arcgis/rest/services/China/map/MapServer"/>

</esri:Map>

图 6 Map和MapServiceLayer

默认的Map中还有几个其它的元素,包括控制地图缩放的zoomSlider、地图比例尺scaleBar以及ESRI的logo。如果你不需要这些元素,都可以通过Map中对应的属性对它们进行隐藏,下面我们看一下代码和隐藏后的效果:

<esri:Map id="map" zoomSliderVisible="false" scaleBarVisible="false" logoVisible="false">

<esri:ArcGISTiledMapServiceLayer

url="http://localhost:8399/arcgis/rest/services/China/map/MapServer"/>

</esri:Map>

图 7 隐藏不需要的元素后的Map

需要顺便提一下的是,ESRI的logo能被隐藏掉的前提条件是你使用的是本地的ArcGIS Server服务。另外,zoomSlider和scaleBar除了可以被隐藏掉,还可以通过定制样式来改变外观,或许你仅仅是讨厌默认的外观但却需要这个功能。

以下的CSS代码将Map的zoomSlider移到了右边,并且对它按钮的样式、滑块位置等一系列外观做了定制,接着我们就可以看到新的zoomSlider的样子了:

<mx:Style>

.mapStyle{ navigation-style-name: navigationStyle;}

.navigationStyle{

top: 6;

right: 6;

navigation-minus-button-style-name: navigationMinusButton;

navigation-plus-button-style-name: navigationPlusButton;

navigation-slider-style-name: navigationSlider;

}

.navigationMinusButton {

disabledSkin: Embed(source="assets/zoomout.png");

downSkin: Embed(source="assets/zoomout.png");

overSkin: Embed(source="assets/zoomout.png");

upSkin: Embed(source="assets/zoomout.png");

}

.navigationPlusButton{

disabledSkin: Embed(source="assets/zoomin.png");

downSkin: Embed(source="assets/zoomin.png");

overSkin: Embed(source="assets/zoomin.png");

upSkin: Embed(source="assets/zoomin.png");

}

.navigationSlider{

dataTipPlacement: "left";

tickColor: #FFFFFF;

tickLength: 10;

tickOffset: 13;

tickThickness: 3;

}

</mx:Style>

<esri:Map id="map" styleName="mapStyle"></esri:Map>

图 8 改变zoomSlider样式后的Map

另外,Map还有一些默认隐藏的外观设置,比如地图四周的导航按钮、地图中心的十字符号,包括拉框缩放的方框样式等都可以进行设置,下面是修改了一些样式的Map:

图 9 更改一些隐藏外观样式后的Map

从上面我们可以看到,Map有很灵活的可配置性,它的各种元素的外观也很容易定制;当然,如果实在有特殊的需要,Map也可以通过隐藏所有元素来提供给你一个非常干净的地图组件,你则可以在此基础上加上自己的内容。

在有了一个令自己满意的Map的基础上,你就可以使用ArcGIS Flex API中很多激动人心的功能了——同时你会慢慢发现,所有的功能都是紧紧围绕着这个Map的。

2 Navigation工具

当准备好一个满意的Map的时候,我们已经可以在地图中看到我们在ArcGIS Server中发布的服务了。在这个时候,我们可能马上想到的是如何去操作地图,比如缩放、漫游、前进、后退等等地图导航功能。在这个时候你或许已经发现,当前地图默认的操作是漫游(Pan);同时,你滚动鼠标滚轮的时候地图会进行缩放;如果按住shift键并在地图上拖动时会出现一个矩形框,松开鼠标后地图会缩放到框中的范围。似乎Map已经可以进行地图导航了。

然而,当你想要切换地图到拉框缩小状态或者别的什么操作,或许就感到有点无所适从了。这时,我们友好的Navigation工具就正式登场了。

Navigation提供了对Map进行导航的诸多功能,通过它可以实现漫游、拉框放大、拉框缩小等类似ADF中Tool的功能和前一视图、后一视图、全图等类似ADF中Command的功能。但是,它并不是一个工具条,而是提供了一些功能,你可以自定义工具条和一些按钮然后绑定到Navigation的功能上。

首先让我们看一下Navigation中漫游、拉框放大、拉框缩小等功能和工具条按钮的绑定。这些类似Tool的功能有个特点就是同时只有一个按钮需要被激活,它指示了当前Map的操作状态,因此我们可以借助Flex中的ToggleButtonBar作为这些功能的宿主。下面的代码定义了一个ToggleButtonBar并绑定了Navigation的上面几个功能:

<mx:Script>

<![CDATA[

private function itemClickHandler(event:ItemClickEvent):void

{

switch (event.index)

{

case 0:{ nav.activate(Navigation.PAN , true);break; }

case 1: {nav.activate(Navigation.ZOOM_IN , true); break; }

case 2: {nav.activate(Navigation.ZOOM_OUT , true); break; }

}

}

]]>

</mx:Script>

<esri:Navigation id="nav" map="{map}"/>

<esri:Map id="map">

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

</esri:Map>

<mx:HBox horizontalAlign="center" width="100%">

<mx:ToggleButtonBar id="tbb" itemClick="itemClickHandler(event)">

<mx:dataProvider>

<mx:Array>

<mx:String>漫游</mx:String>

<mx:String>拉框放大</mx:String>

<mx:String>拉框缩小</mx:String>

</mx:Array>

</mx:dataProvider>

</mx:ToggleButtonBar>

</mx:HBox>

当我们点击ToggleButtonBar中某个按钮时,itemClickHandler这个监听被触发,于是Navigation就会根据当前ToggleButtonBar所选中的按钮来设置Map的操作状态——调用Navigation的activate方法。而Navigation之所以可以和Map联动,是因为Navigation有个map属性会存放Map的引用。

下面是添加了ToggleButtonBar的效果:

图 10 绑定了漫游、拉框放大、拉框缩小等功能的ToggleButtonBar

下面再让我们看一下Navigation中前一视图、后一视图、全图等功能和工具条按钮的绑定。这些类似Command的按钮每个都会实现单一的功能,不过,需要注意的是,前一视图、后一视图的按钮并不是一直可用,比如如果用户从来没有点击过前一视图按钮,那么后一视图按钮肯定是不可用的对吧?这些细节Navigation也已经为你考虑到了,下面我们看一下如何定义这些按钮并绑定到Navigation的功能上:

<mx:Button label="前一视图"

click="nav.zoomToPrevExtent()"

enabled="{!nav.isFirstExtent}"/>

<mx:Button label="后一视图"

click="nav.zoomToNextExtent()"

enabled="{!nav.isLastExtent}"/>

<mx:Button label="全图"

click="nav.zoomToFullExtent()"/>

从这里可以看到,Navigation不仅可以改变Map的操作状态,还有直接操作Map的方法,通过对这些方法的调用,Navigation就可以是Map根据你的需要切换视图。下面是添加了这几个功能按钮的效果:

图 11 绑定了前一视图、后一视图、全图等功能的按钮

到现在为止,我们已经知道怎么样使用Map来展现服务器端的地图服务,然后使用Navigation去导航地图,所以对地图的浏览已经基本可以说无所不能了。下面,或许你已经开始更多地考虑用户怎么和地图进行更多的交互了,比如客户端绘制。

3 Draw工具

Draw是ArcGIS Flex API另外一个和Navigation性质类似的工具。Draw工具提供了在客户端绘制各种几何对象的功能,类似Navigation的使用那样,我们用一个ToggleButtonBar去绑定Draw工具的功能:

<mx:Script>

<![CDATA[

private function itemClickHandler(event:ItemClickEvent):void

{

switch (event.index)

{

case 0:{draw.activate(Draw.MAPPOINT);break;}

case 1:{draw.activate(Draw.MULTIPOINT);break;}

case 2:{draw.activate(Draw.LINE);break;}

case 3:{draw.activate(Draw.POLYLINE);break;}

case 4:{draw.activate(Draw.FREEHAND_POLYLINE);break;}

case 5:{draw.activate(Draw.POLYGON);break;}

case 6:{draw.activate(Draw.FREEHAND_POLYGON);break;}

case 7:{draw.activate(Draw.EXTENT);break;}

}

}

]]>

</mx:Script>

<esri:Draw id="draw" map="{map}" graphicsLayer="{drawGraphicsLayer}" markerSymbol="{sms}" lineSymbol="{sls}" fillSymbol="{sfs}" />

<esri:Map id="map">

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

<esri:GraphicsLayer id="drawGraphicsLayer"/>

</esri:Map>

<mx:HBox width="100%" horizontalAlign="center">

<mx:ToggleButtonBar id="tbb" itemClick="itemClickHandler(event)">

<mx:dataProvider>

<mx:Array>

<mx:String>点</mx:String>

<mx:String>多点</mx:String>

<mx:String>直线</mx:String>

<mx:String>多线</mx:String>

<mx:String>手绘多线</mx:String>

<mx:String>多边形</mx:String>

<mx:String>手绘多边形</mx:String>

<mx:String>矩形</mx:String>

</mx:Array>

</mx:dataProvider>

</mx:ToggleButtonBar>

</mx:HBox>

<esri:SimpleMarkerSymbol id="sms" style="{SimpleMarkerSymbol.STYLE_DIAMOND}" color="0xFFFF00" size="12"/>

<esri:SimpleLineSymbol id="sls" style="{SimpleLineSymbol.STYLE_DASHDOT}" color="0x00FF00" width="2"/>

<esri:SimpleFillSymbol id="sfs" style="{SimpleFillSymbol.STYLE_DIAGONAL_CROSS}">

<esri:outline>

<esri:SimpleLineSymbol color="0xFF0000" width="2"/>

</esri:outline>

</esri:SimpleFillSymbol>

同样,当我们点击ToggleButtonBar中某个按钮时,Draw工具会根据当前ToggleButtonBar所选中的按钮来激活某个绘制功能。可选的几何对象类型包括点、多点、直线、多线、手绘多线、多边形、手绘多边形、矩形。同时,%E

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值