1
3
目录
一 初级篇 ......................................................................................................................................... 4
环境搭建.................................................................................................................................. 4
概述 ................................................................................................................................. 4
相关资源 .......................................................................................................................... 4
创建基本程序 .................................................................................................................. 5
参考资料及其他 .............................................................................................................. 6
地图的创建 ............................................................................................................................. 6
概述 ................................................................................................................................. 6
创建地图 .......................................................................................................................... 7
事件(Event) ................................................................................................................. 8
绘制与符号化 ......................................................................................................................... 9
概述 ................................................................................................................................. 9
绘图控件的使用 .............................................................................................................. 9
符号化.............................................................................................................................. 9
地图的浏览 .................................................................................................................... 10
TASK之 QUERY & FIND & IDENTIFY ................................................................................................. 10
概述 ............................................................................................................................... 10
在 mxml文档中嵌入 ActionScript.................................................................................. 11
QueryTask ........................................................................................................................ 11
FindTask ........................................................................................................................... 13
IdentifyTask ...................................................................................................................... 15
InfoWindow ..................................................................................................................... 17
二 中级篇 ....................................................................................................................................... 18
地理定位(LOCATOR) ............................................................................................................ 18
概述 ............................................................................................................................... 18
地理编码(GeoCode) .................................................................................................. 18
逆地理编码(Reverse Geocode) ................................................................................... 20
地理处理(GEOPROCESSING) .................................................................................................. 21
几何服务(GEOMETRY SERVICE) .............................................................................................. 22
打印地图(PRINT) ................................................................................................................ 23
GEORSS的读取 ....................................................................................................................... 24
GeoRSS概述 .................................................................................................................... 24
GeoRSS读取 .................................................................................................................... 24
三 高级篇 ....................................................................................................................................... 26
WEBSERVICE 的使用 ................................................................................................................. 26
ESRI TILEMAP 四叉树索引研究 ................................................................................................ 28
自定义控件的开发 ................................................................................................................ 31
与 GOOGLE MAP 的融合 .......................................................................................................... 32
4
一 初级篇
环境搭建
概述
ArcGIS API for Flex 是 ESRI 2008年新推出的WebGIS客户端开发包,用于富
互联网应用程序 RIA(Rich Internet Applications)的开发,为 ArcGIS Server 提
供了一套全新的开发方式,其优点是运行速度快,为用户提供优秀的用户体验。
使用 ArcGIS API for Flex 可以实现如下效果:
1)显示地图数据并与之交互
2)在服务器上执行空间处理模型并显示结果
3)基于 ArcGIS Online的地图服务显示自己的业务数据
4)根据属性或者位置查找数据并显示结果
5)查找地址并显示结果
6)创新结果的显示方式
7)创建Mushups应用
相关资源
ArcGIS API for Flex 线上帮助系统的网址:
ArcGIS API for Flex 下载地址:
开发 ArcGIS API for Flex 的程序需要 flex 环境的支持。
Flex SDK 3下载地址:
&pkgtype=1
为了开发方便,最好使用 Flex Builder开发环境,从 Adobe 官方网站下载试
5
用版:
创建基本程序
1)打开 Flex Builder,创建一个 Flex 工程(名称 Demo)。
2)右键单击工程名,选择属性,在属性对话框中选择 Flex Build Path如图 1-1 ,
选择 Libaray Path选项卡,单击 Add SWC 把下载的 ArcGIS API for Flex添加进去,
环境就配置好了。
图 1-1
在 文件中输入下面这代码:
<?xml version="" encoding="utf-8"?>
<mx:Application
xmlns:mx="
xmlns:esri="
pageTitle="First ArcGIS API for Flex program"
styleName="plain">
<esri:Map crosshairVisible="true">
<esri:ArcGISTiledMapServiceLayer
url="
" />
</esri:Map>
</mx:Application>
这是一个最基础的ArcGIS API for Flex应用程序,编译运行即可。
6
完整的例子可以在/samples/ 下面找到。
参考资料及其他
文章部分内容参考了以下文章:
关于配置环境的详细信息还可以参考下面的视频:
地图的创建
概述
地图(map)是 ArcGIS API for Flex中最重要的对象之一,map负责对 layer
进行组织,在逻辑上 map可以包含任意多个 layer。
在 ArcGIS API for Flex中,主要包括以下几种 layer:
ArcGISDynamicMapServiceLayer :用户通过 ArcGIS Server REST API以动态地
图服务的形式对数据进行访问(Allows you to work with a dynamic map service
resource exposed by the ArcGIS Server REST API)。
ArcGISImageServiceLayer:用户通过 ArcGIS Server REST API以影像服务的形式
对数据进行访问(Allows you to work with an image service resource exposed by the
ArcGIS Server REST API)。
ArcGISTiledMapServiceLayer :用户通过 ArcGIS Server REST API以影像服务的
形式对数据进行访问(Allows you to work with a cached map service resource
exposed by the ArcGIS Server REST API)。
ArcIMSMapServiceLayer :用户可以访问 ArcIMS image service 提供的数据
(Allows you to work with an ArcIMS image service)。
GraphicsLayer:用于显示用户在客户端绘制的图形要素的图层,该图层可以
包含一个或多个图形要素( A layer that contains one or more Graphic features)。
7
创建地图
使用 ArcGIS API for Flex 创建一个地图,在 mxml文件中直接使用<esri:Map>
标签即可,如下:
<esri:Map width="100%" height="50%" id="EsriMap" resize="EsriMapResize(event);"
extentChange="ESRIMapExtentChange(event);" mouseMove="OnDrawMouseMove(event)" />
<esri:Map>标签定义一个 map对象,其中 width,height,id为 map的属性,
resize="EsriMapResize(event);"extentChange="ESRIMapExtentChange(event);"
mouseMove="OnDrawMouseMove(event)" 为 map的消息以及消息响应函数。
关于 map的属性和消息的详细列表请参考以下地址:
map创建好之后,使用 layer把需要访问的数据加载到 map上,在<esri:Map>
标 签 下 面 创 建 <esri:ArcGISTiledMapServiceLayer > 子 标 签 。
<esri:ArcGISTiledMapServiceLayer >标签定义一个 layer对象,如下:
<esri:ArcGISTiledMapServiceLayer url="
_StreetMap_World_2D/MapServer" />。
其最重要的属性就是 url,url 定义了访问数据的地址,在上面的代码中 url
指向一个 arcgisonline 提供的 TiledMap服务。
有关 arcgisonline提供的服务信息请查看下面地址:
控制 map的初始显示范围,在<esri:Map>标签下创建<esri:extent>标签即可。
使用<esri:extent>标签来定义一个范围对象,例如设定 map显示的范围为北京地
区:
<esri:extent>
<esri:Extent xmin="114" ymin="38" xmax="116" ymax="42"/>
</esri:extent>
注意标签的大小写,标签是大小写敏感的。
在这个例子中,我们将添加上面提到的 3种类型的 layer到 map中,并控制
其初始显示范围为北京地区,如下面代码:
<esri:Map >
<esri:ArcGISTiledMapServiceLayer visible="{ == 0}"
url="
8
" />
<esri:ArcGISDynamicMapServiceLayer visible="{ == 1}"
url="
ation_World/MapServer"/>
<esri:ArcIMSMapServiceLayer visible="{ == 2}"
serviceHost=""
serviceName="ESRI_World" />
<esri:extent>
<esri:Extent xmin="114" ymin="38" xmax="116" ymax="42"/>
</esri:extent>
</esri:Map>
事件(Event)
地图创建之后,如果要得到当前鼠标单击位置的坐标,则需要处理 Map 的
事件,通过响应事件来获取鼠标单击位置的坐标。在 ActionScript中的事件和 JAVA
的事件类似,是一种典型的观察者模式。
在 ArcGIS API for Flex中提供的事件主要有:
DrawEvent、 ExtentEvent、 FindEvent、GeometryServiceEvent、GeoprocessorEvent、
GraphicEvent 、 IdentifyEvent 、 LayerEvent 、 LocatorEvent 、MapEvent 、
MapImageEvent NavigationEvent、PanEvent 、QueryEvent 、ZoomEvent 。
关于事件的详细描述可以参考下面的地址:
下面的例子实现一个简单的事件响应:当双击 map的时候,弹出对话提示正
在双击 map。
修改<esri:Map>标签,响应 doubleClick事件。
<esri:Map doubleClick="('doubleClick Map')">
为了能够使用Alert,在 <mx:Application>下面插入下面代码:
<mx:Script>
<![CDATA[
import ;
]]>
</mx:Script>
关于mxml文件中嵌入ActionScript脚本部分将在后面详细讲解。
完整的例子可以在/samples/ 下面找到。
9
绘制与符号化
概述
ArcGIS API for Flex 在客户端提供了强大的绘制功能,丰富的符号支持,可以
通过简单的调用来完成复杂的绘制工作,达到很好的交互效果,提供完美的用户
体验。
绘图控件的使用
完成客户端的绘制功能,需要在 map上定义一个 GraphicsLayer,客户端绘制
的结果都会添加到 GraphicsLayer 上。
使用<esri:GraphicsLayer> 标签定义一个 GraphicsLayer 对象。
<esri:GraphicsLayer id="myGraphicsLayer"/>
id 唯一标识一个 GraphicsLayer。
GraphicsLayer创建后,进行绘制工作只要使用 ArcGIS API for Flex提供的 draw
工具即可。 ArcGIS API for Flex已经对绘制进行了很好的封装,通过简单的调用
即可完成复杂的绘制工作,类似于 AE中的 drawToolbar。
首先,定义一个 draw 控件,使用<esri:Draw>标签来完成创建工作,如下面
的代码:
<esri:Draw id="drawToolbar" map="{myMap}" graphicsLayer="{myGraphicsLayer}" />
id 唯一标识一个 Draw对象,map属性绑定到需要绘制的地图上,graphicsLayer
属性绑定到需要绘制到的 graphicsLayer上。
Draw对象创建后,调用 Draw的 activate方法来激活所需要的工具进行交互
的绘制,例如绘制多边形,只需要调用 activate()函数即可,其中
POLYGON 为 Draw的静态成员。
在绘制完图形后,释放掉绘制工具,调用 deactivate()函数即可。
符号化
在 map 中对绘制的图形进行符号化,设置 Draw 对象的 markerSymbol,
10
lineSymbol,fillSymbol属性即可。其中 markerSymbol为点的符号,lineSymbol为
线的符号,fillSymbol为填充符号。
设置 Draw 对象的 markerSymbol,lineSymbol,fillSymbol 属性之前,需要创建
markerSymbol, lineSymbol, fillSymbol 对象。以 markerSymbol 为例 ,使用
<esri:SimpleMarkerSymbol> 标签定义一个 markerSymbol,如下面代码:
<esri:SimpleMarkerSymbol id="sms" style="square" color="0xFF0000" size="11"/>
id 唯一标识一个 markerSymbol,style 属性为 markerSymbol 的风格,color
属性为 markerSymbol的颜色,size属性为 markerSymbol的大小。
lineSymbol和 fillSymbol的定义与 markerSymbol类似。
地图的浏览
与 Draw控件类似,在 ArcGIS API for Flex中提供了地图浏览的工具,通过简
单的调用,就能够实现放大、缩小、平移、复位等地图浏览操作。
使用<esri:Navigation>标签定义地图浏览控件:
<esri:Navigation id="navToolbar" map="{myMap}"/>
map属性绑定需要进行浏览操作的地图。
Navigation对象创建后,使用 Navigation的 activate方法来激活需要的工具进
行浏览。例如放大操作:
activate(_IN);
释放浏览工具,调用 Navigation对象的 deactivate()函数即可。
完整的例子可以在 samples/下面找到。
Task之 Query & Find & Identify
概述
在 GIS系统中,Query 、Find 、 Identify都是最常用,最基本的功能,也是
使用频率最高的功能之一。在 ArcGIS API for Flex中提供了 QueryTask,FindTask,
IdentifyTask来完成 Query 、Find 、 Identify的功能。
这些 Task共同的特点是,在客户端组织好参数信息,执行,在服务器端返回
11
结果,对结果在客户端处理。
在 mxml文档中嵌入 ActionScript
在使用 QueryTask,FindTask,IdentifyTask 之前,首先介绍一下如何在 mxml
文档中嵌入 ActionScript.。通过在 mxml文档中嵌入 ActionScript脚本我们可以更
加灵活的使用 ArcGIS API for Flex。
关于 ActionScript的语法可以参考 ActionScript的相关书籍。
要在 mxml文档中嵌入 ActionScript,需要使用<mx:Script>标签:
<mx:Script>
<![CDATA[
]]>
</mx:Script>
ActionScript是一种类 java 语言,它本身有一个 AVM,把 ActionScript编译成
java 的代码,然后再通过 JVM转换成字节码执行。
QueryTask
在 ArcGIS API for Flex中进行查询操作,需要定义一个查询任务面板。
使用<esri:QueryTask>标签来定义一个查询任务面板。
<esri:QueryTask id="queryTask"
url="
us_USA/MapServer/5">
<esri:Query id="query"
text="{}"
returnGeometry="true"
spatialRelationship="esriSpatialRelEnvelopeIntersects">
<esri:outFields>
<mx:String>MED_AGE</mx:String>
<mx:String>POP2007</mx:String>
</esri:outFields>
</esri:Query>
</esri:QueryTask>
id 唯一标识这个查询任务,url指定查询服务的地址。
<esri:Query>定义一个查询,text 属性指定查询的内容,<esri:OutFields>子标
签定义 Query 查询的结果返回哪些字段的内容。
QueryTask 定义好之后,在界面上定义一个文本输入框和一个查询按钮来调
用这个 QueryTask:
<mx:Panel title="Query a layer (search for a state)"
layout="horizontal" backgroundColor="0xB2BFC6" borderStyle="solid">
12
<mx:TextInput width="100%" id="qText" enter="doQuery()"text="California"/>
<mx:Button label="Do Query" click="doQuery()"/>
</mx:Panel>
文本输入框用来输入查询的内容,button 用来执行查询的动作。
下面实现查询功能:
首先,使用 import 指令引入我们需要的命名空间,和 java基本一样。
<mx:Script>
<![CDATA[
import ;
import ;
import ;
import ;
import ;
]]>
</mx:Script>
其次,定义 doQuery()函数(注意 ActionScript代码要放到<mx:Script>标签中):
private function doQuery() : void
{
( query, new AsyncResponder( onResult, onFault ));
}
在 doQuery()函数中直接调用了 queryTask的 execute 方法,这是一个异步调
用。成功响应 onResult函数,失败则响应 onFault函数。最后查询得到的结果将
在 onResult 函数中处理。
下面是 onResult函数的定义以及实现:
private function onResult( featureSet : FeatureSet, token : Object = null ) : void
{
var displayFieldName : String = ;
for each ( var myGraphic : Graphic in )
{
// ToolTip
= "The 2007 population of "
+ [displayFieldName] + " was "
+ ()
+ "\nMedian Age: " + _AGE + ".";
// show on map
( myGraphic );
}
}
查询结果返回一个 FeatureSet,在 onResult函数中遍历这个 FeatureSet,然
后把每个 feature 绘制到 GraphicLayer上,并显示 ToolTip。
13
如果查询失败,则在 onFault函数中对失败进行处理,如下代码:
private function onFault( info : Object, token : Object = null ) : void
{
( () );
}
弹个对话框出来告诉用户失败的详细信息。
完整例子可以在 samples/
FindTask
在 ArcGIS API for Flex中执行 Find任务,需要使用 FindTask。
使用<esri:FindTask >标签定义一个 FindTask对象,如下面的代码:
<esri:FindTask id="findTask" executeComplete="executeCompleteHandler(event)"
url="
rs_USA/MapServer/find"/>
id 唯一标识 FindTask,executeComplete 事件指定 Find任务完成后调用的函
数,url指定提供 Find服务的地址。
使用 FindTask,还需要一个 FindParameters对象来指定查找的参数。
<esri:FindParameters id="myFindParams" returnGeometry="true" contains="true"
searchText="{}" layerIds="[2]" searchFields="['STATE_ABBR','STATE_NAME']"
/>
id 唯一标识 FindParameters,searchText指定查找的字符串,searchFields指
定在哪些字段查找。
定义好 FindTask和 FindParameters之后,在界面上定义一个文本输入框和一
个 button来完成 Find功能的调用工作。
<mx:HBox width="100%" height="40" backgroundColor="0xDDDDFF" paddingTop="10"
horizontalAlign="center">
<mx:Text text="Search for names of States"/>
<mx:TextInput maxWidth="400" id="fText" enter="doFind()" text="NEW"/>
<mx:Button label="Find" click="doFind()"/>
</mx:HBox>
文本输入框用来输入查找的内容,button 用来执行查询的动作。
实现 Find功能:
首先,使用 import 指令引入需要的命名空间:
import ;
其次,定义 doFind()函数:
14
Private function doFind():void
{
( myFindParams );
}
在doFind()函数中 FindTask对象直接调用了execute方法,并把 FindParameters
对象做为传入参数。
下面实现 executeCompleteHandler()函数,这个函数在定义 FindTask 的时候
被指定为响应 executeComplete 事件的函数,即当 Find 任务完成的时候会响应
executeCompleteHandler()函数,Find得到的结果将在这个函数里进行处理。
private function executeCompleteHandler( event : FindEvent ) : void
{
();
var graphic : Graphic;
= "Found " + + " results.";
for (var i : Number = 0; i < ; i++)
{
graphic = [i].feature;
= [i].foundFieldName + ": " +
[i].value;
(graphic);
}
}
在 executeCompleteHandler函数中遍历 Find的结果,给每一个 graphic 添加
一个 toolTip,显示该结果对应的字段名和字段值。
同时把查询到的结果显示到 DataGrid中:
<mx:DataGrid
dataProvider="{}"
scroll="true" width="100%" height="40%">
<mx:columns>
<mx:DataGridColumn dataField="layerId" headerText="Layer ID" width="70"/>
<mx:DataGridColumn dataField="layerName" headerText="Layer Name"/>
<mx:DataGridColumn dataField="foundFieldName"
headerText="Found Field Name"/>
<mx:DataGridColumn dataField="value" headerText="Found Field Value"/>
</mx:columns>
</mx:DataGrid>
只要把 DataGrid 的 dataProvider绑定到 就可以了。
完整例子可以在 samples/
15
IdentifyTask
Identify 是 GIS中比较常用的工具之一,在 ArcGIS API for Flex中,使用 Identify
Task来实现 Identify 的功能。
使用<esri:IdentifyTask>标签来定义一个 Identify Task对象,如下面代码:
<esri:IdentifyTask id="identifyTask"
identifyComplete="identifyCompleteHandler(event)"
url="
CitiesRivers_USA/MapServer"/>
id 唯一标识 IdentifyTask ,identifyComplete事件绑定 identifyCompleteHandler()
函数,url指定 IdentifyTask服务的地址。
执行 Identify,需要定义一个 IdentifyParameters对象。下面使用 ActionScript
来定义一个 IdentifyParameters 对象,使用<IdentifyParameters>标签也可以完成
同样的工作。
var identifyParams : IdentifyParameters = new IdentifyParameters();
= true;
= 3;
= 600;
= 550;
= geometry;
= _OPTION_ALL;
= ;
( identifyParams );
其中 tolerance是容差半径,geometry 是用来做 identify的几何。
下面在界面上使用鼠标交互来完成 Identify:
首先,定义一个 draw控件 :
<esri:Draw id="drawToolbar" map="{map}"
graphicsLayer="{myGraphicsLayer}" drawEnd="drawEndHandler(event)">
drawEnd事件绑定到 drawEndHandler(event)函数,这个事件会在绘制完成后触发。
使用 ActionScript脚本实现 drawEndHandler和 identifyCompleteHandler函数:
首先,引入命名空间:
import ;
import ;
import ;
import ;
import ;
import ;
import ;
16
import ;
其次,定义并实现 drawEndHandler()函数:
private function drawEndHandler(event:DrawEvent):void
{
var geometry : Geometry = ;
var identifyParams : IdentifyParameters = new IdentifyParameters();
= true;
= 3;
= 600;
= 550;
= geometry;
= _OPTION_ALL;
= ;
( identifyParams );
}
在 drawEndHandler()函数中定义了一个 identifyParams ,每次调用
drawEndHandler 的时候,identifyTask 都会把 identifyParams 作为传入参数调用
execute方法去执行。执行完成后会响应 identifyCompleteHandler()函数。
定义并实现 identifyCompleteHandler()函数:
private function identifyCompleteHandler(event:IdentifyEvent):void
{
for each (var result:IdentifyResult in )
{
();
switch ()
{
case :
{
var mp:MapPoint = as MapPoint;
var txt :Text=new Text();
="Point";
=txt;
(mp);
break;
}
case :
{
var lin:Polyline = as Polyline;
var txt :Text=new Text();
="Line";
=txt;
();
17
break;
}
case :
{
var pgn:Polygon= as Polygon;
var txt :Text=new Text();
="polygon";
=txt;
();
break;
}
}
}
}
在 identifyCompleteHandler()函数中,遍历 identifyResults,将 identifyResults
添加到 GraphicsLayer上。
完整例子可以在 samples/
InfoWindow
InfoWindow是 ArcGIS API for Flex中提供的类似于标注的窗口,可以用来显
示用户自定义的信息,可以是文本、图片,也可以是复杂的自定义组件。
使用 InfoWindow,只要设置 map的 infoWindow属性即可。如下面代码:
var canvas:Canvas = new Canvas();
var txtTem :Text = new Text();
= "aa";
(txtTem);
= canvas;
var mapPnt2:MapPoint = new MapPoint(,);
(mapPnt2);
content设置 infoWindow的内容,show方法设置 infoWindow的显示位置。
关于 InfoWindow的使用已经结合在上一小节中(IdentifyTask),例子以及代
码请参考上例。
18
二 中级篇
地理定位(Locator)
概述
地理定位(Locator)即地理编码(Geocode)又称地址匹配(address-matching),
是指建立地理位置坐标与给定地址一致性的过程。也是指在地图上找到并标明每
条地址所对应的位置。地理编码是 GIS中比较重要的一个功能。
地理编码(GeoCode)
在 ArcGIS API for Flex 中使用地理编码和执行查询任务类似,首先使用
<esri:Locator>标签定义一个 Locator对象:
<esri:Locator
id="locateTask"
url="
A/GeocodeServer"/>
id 唯一标识 Locator,url指向提供 Locator服务的地址。
Locator 定义之后,在界面上定义一组文本输入框和一个执行按钮来调用这
个 Locator:
<mx:Panel title="Find an address" top="5" horizontalCenter="0">
<mx:Form>
<mx:FormItem label="Street">
<mx:TextInput width="100%" id="address" text="380 New York St"/>
</mx:FormItem>
<mx:FormItem label="City">
<mx:TextInput width="100%" id="city" text="Redlands"/>
</mx:FormItem>
<mx:FormItem label="Zip Code or postal code">
<mx:TextInput width="100" id="zip" text="92373"/>
</mx:FormItem>
<mx:FormItem label="State/Province">
<mx:TextInput width="100" id="state" text="CA"/>
</mx:FormItem>
<mx:FormItem label="Country">
<mx:ComboBox id="country" selectedIndex="1">
19
<mx:ArrayCollection>
<mx:String>Canada</mx:String>
<mx:String>USA</mx:String>
</mx:ArrayCollection>
</mx:ComboBox>
</mx:FormItem>
<mx:FormItem>
<mx:Button label="Find Address" click="doQuery()"/>
</mx:FormItem>
</mx:Form>
<mx:Text id="myInfo" width="100%" color="0x00FF00" textAlign="center" />
</mx:Panel>
文本输入框用来输入地址的详细信息,button 用来执行查询的动作。
实现地理编码的功能:
首先,定义一个 Object来存储地址的详细信息,包括 Address,City,State,
Zip,Country等信息。
然后,定义一个 Array来存储输出字段的名称。
最后,把 myAddress 和 myOutFields 作为输入参数调用 locateTask 对象的
addressToLocations方法。
具体代码请参考下面的代码:
private function doGeoCode() : void
{
var myAddress:Object = {
Address: ,
City: ,
State: ,
Zip: ,
Country:
};
var myOutFields:Array = ["Loc_name"];
(myAddress, myOutFields, new AsyncResponder(onResult,
onFault));
function onResult( candidates : Array, token : Object = null ) : void
{
if ( > 0)
{
var addressCandidate : AddressCandidate = candidates[0];
var myGraphic : Graphic = new Graphic();
= ;
= mySymbol;
20
= ();
= "graphic";
( myGraphic );
( );
= "<b>Found:</b><br/>"
+();
}
else
{
= "<b><font color='#FF0000'>Found
nothing :(</b></font>";
("Sorry, couldn't find a location for this address"
+ "\nAddress: " +
+ "\nCity: " +
+ "\nZIP Code: " +
+ "\nState: " +
+ "\nCountry: " + );
}
}
function onFault( info : Object, token : Object = null ) : void
{
= "<b>Failure</b>" + ();
("Failure: \n" + ());
}
}
其中,addressToLocations的定义为:
public function addressToLocations(address:Object, outFields:Array = null, responder:IResponder
= null):void
关于该函数的详细信息请参考下面地址:
该方法是一个异步调用的方法,成功则调用 onResult()函数,失败则调用
onFault 函数。这个过程和查询任务的调用过程相同。在 onResult 函数中我们处
理返回的结果,地图中心平移到返回的地址,并增加一个点来标识。在 onFault
中我们处理失败,将通过对话框返回错误信息。
逆地理编码(Reverse Geocode)
逆地理编码就是把地理坐标解析成对应的地址。Locator 也提供的进行逆地
理 编 码的 函数 ,即 locationToAddress 方 法 。该 方法 的调 用方 式 和
21
addressToLocations方法相同,只是参数略有不同。locationToAddress方法的定义
为:
locationToAddress(location:MapPoint, distance:Number = 0, responder:IResponder = null)
关于该函数的详细信息请参考下面地址:
完整例子可以在 samples/下面找到。
地理处理(Geoprocessing)
在ArcGIS API for Flex中可以使用GP服务来进行地理处理。在ArcGISOnline 上
的 gp 服 务 有 CreateDriveTimePolygons 和 Viewshed , 下 面 以
CreateDriveTimePolygons服务为例来实现在 ArcGIS API for Flex中调用 GP服务。
首先,使用<esri:Geoprocessor >标签定义一个 gp服务,url指向提供 gp服务
的地址。
<esri:Geoprocessor id="gp" url="
ces/Network/ESRI_DriveTime_US/GPServer/CreateDriveTimePolygons" />
定义 GP对象后,再定义一个 GP的参数对象来传递参数,如下面代码:
var params:Object = {
"Input_Location" : featureSet,
"Drive_Times" : driveTimes
};
其中参数 Input_Location 和 Drive_Times与发布的 GP服务相关,不同的 GP
服务有不同的参数。
关于 GP参数设置的详细信息请参考下面地址:
定义好 GP 对象和 GP 参数对象之后,下面实现在地图上单击,然后计算
DriveTimes,并把得到的结果绘制在地图上的功能。
其中 GP调用的代码如下:
var featureSet:FeatureSet = new FeatureSet([graphic]);
var params:Object = {
"Input_Location" : featureSet,
"Drive_Times" : driveTimes
};
(params, new AsyncResponder( onResult, onFault ));
function onResult(
gpResult : ExecuteResult,
22
token : Object = null
) : void
{
var pv : ParameterValue = [0];
var fs : FeatureSet = as FeatureSet;
= ;
}
function onFault( info : Object, token : Object = null ) : void
{
( () );
}
定义好 GP之后,直接调用 GP的 execute的方法即可,成功响应 onResult,
失败响应 onFault。
关于 GP调用的详细信息请参考下面地址:
完整例子可以在 samples/目录下找到。
几何服务(Geometry Service)
Geometry Service 顾名思义,就是提供针对几何层级的服务,例如
Project, Simplify , Buffer,Areas And Lengths , Lengths 等。
详细信息可以参考下面地址:
ver
上面的地址发布了 5个 Geometry Service:Project, Simplify , Buffer,Areas
And Lengths , Lengths。
下面以 Buffer为例,来实现在 ArcGIS API for Flex中调用 Geometry service。
首先,使用<esri:GeometryService>标签定义一个 GeometryService对象。
<esri:GeometryService id="myGeometryService"
url="
id 唯一标识 Geometry Service,url指定提供 Geometry Service的地址。
和 Identify工具类似,进行 Buffer操作首先要创建一个需要做 buffer的几何,
然后定义一个 BufferParameters ,执行 Buffer操作,最后将 buffer的结果绘制到
GraphicsLayer上。
下面介绍一下 BufferParameters参数的意义:distances为 buffer半径,features
23
为需要做 buffer的要素集合,unit 为单位,bufferSpatialReference为 buffer操作
时的空间参照系。
Buffer调用的代码如下:
var bufferParameters : BufferParameters = new BufferParameters();
= [point];
= [3000];
= _METER;
=newSpatialReference( 602113);
(_COMPLETE, bufferCompleteHandler);
( bufferParameters );
关键的部分是 参数设置的 features 一定要有空间
参考系,不然 Buffer不成功。
关于 Geometry Service的详细信息请参考下面地址:
其余的绘制操作,将结果绘制到 GraphicsLayer上的操作请参考 节绘制与
符号化部分。
完整例子可以在 samples/目录下找到。
打印地图(Print)
在 Flex 中打印地图全部依赖于 Flex的打印功能。
在 Flex 中打印,使用 的功能即可。因为 flex的打印
功能实现比较简单,所以就不做详细讲解。主要的内容就是定义一个 FlexPrintJob
对象,然后调用 FlexPrintJob对象的 send()方法把打印指令发送给打印机。
代码如下:
private function doPrint(myFlexPrintJobScaleType:String):void
{
var myPrintJob:FlexPrintJob = new FlexPrintJob();
if (())
{
try
{
24
= false;
(myPanel, myFlexPrintJobScaleType);
= true;
}
catch (e:Error)
{
( () );
}
();
}
}
详细示例可以在 samples/中找到。
GeoRSS的读取
GeoRSS概述
GeoRSS是指给 RSS feed添加位置信息或者地理标签到的一种协议,它标准化
了表达地理信息的方式,简捷并高效地满足了给Web内容添加位置信息的需求。
时空信息在 RSS里以 XML格式指定,和 RSS 、RSS 、RSS 、Atom甚至其
他基于 XML格式的文件协作,实现在网络上编码时空信息。
GeoRSS 提供了一种地理位置搜索与聚合的方案,并且可以用于地理分析、
地理搜索、地理聚合。例如在指定地点 10公里范围内,所有可能受地震影响的
地物的信息,在自己出行道路中出现交通事故的位置点等等。只要 RSS包含了地
理位置信息,就可以将应用进行扩展。
GeoRSS读取
在 ArcGIS API for Flex 中虽然没有直接对 GeoRSS进行支持,但在 ArcGIS API
for Flex 的 samples 里 提 供 了 对 GeoRSS 读 取 的 库 , 在
arcgis_api_for_flex_1_0\ArcGIS_Flex\samples\src\com\esri\ags\samples目录下面,
以 as文件的形式存在,主要包括 3个 as文件:,,
。
关于 GeoRSS读取可以详细剖析这三个文件,下面主要介绍如何使用这个库
25
来读取 GeoRSS。
首先,使用<samples:GeoRSSProvider>标签定义一个 GeoRSSProvider 对象,
如下面代码:
<samples:GeoRSSProvider id="georss" error="errorHandler(event)"/>
id 唯一标识 GeoRSSProvider。
然后,定义一个 ComboBox和一个 Button。
<mx:ControlBar>
<mx:Spacer width="100%"/>
<mx:ComboBox id="cb" dataProvider="{arr}" labelField="url"/>
<mx:Button label="Load" click="load_clickHandler()"/>
<mx:Spacer width="100%"/>
</mx:ControlBar>
ComboBox 用来存储 GeoRSS提供者的地址,Button用来加载 GeoRSS。
其中 ComboBox的属性 dataProvider绑定 arr。arr的定义如下:
private var arr : Array = [
{url:"feed://
label:"Earthquake",
georssFunction:usgs},
{url:"feed://
label:"Image",
georssFunction:gdacs},
{url:"
ws?format=xml",
label:"News",
georssFunction:reuters},
{url:"feed://
200",
label:"UFO",
georssFunction:flickr}
];
其中 georssFunction为进行解释 url提供的 GeoRSS的回调函数。每个地址提
供的 GeoRSS的结构都是不同的,所以要写回调函数自己去解析。
关于 GeoRSS的更多详细信息请参考下面的地址:
Button 的 click 事件响应 load_clickHandler()函数:
private function load_clickHandler() : void
26
{
= m_image;
= ;
= ;
= ;
}
load_clickHandler()函数实现很简单,只是把 combox中选中的 GeoRSS的 url
和回调函数的名字赋值给 georss对象。
其中回调函数的定义如下:
private function rsoe(
arrcol : ArrayCollection,
x : XML
) : void
{
const geometry : Geometry = (x);
const graphic : Graphic = new Graphic( geometry, sms1);
= ;
( graphic );
}
arrcol : ArrayCollection为返回参数,带回解析后的 graphic。
x : XML为传入参数,传入需要解析的 xml。
不同来源的 GeoRSS回调函数实现是不同的,但参数必须保持一致。
最后定义一个:GraphicsLayer 对象,把 绑定到 GraphicsLayer 的
graphicProvider属性上。
<esri:GraphicsLayer graphicProvider="{}"/>
完整例子可以在 samples/里找到。
三 高级篇
WebService 的使用
Flex 本身对 webservices 有着良好的支持,我们可以调用互联网上的各种
webservices来结合 ESRI的 map 做出自己想要的东西。
下面以在地图上显示天气预报为例,介绍 Flex中调用 webservices。
首先,找到提供天气预报的 webservices:
27
?
然后,使用 <mx:WebService>标签定义一个WebService对象:
<mx:WebService id="weatherWS"
wsdl="
showBusyCursor="true"/>
id唯一标识 webservice,wsdl指向提供 webservice的地址。
在 Application 创建完成的时候调用这个 webservice,得到结果后直接显示
到 map上 。
在<mx:Application>标签的 creationComplete事件绑定 Init()方法:
creationComplete="Init()"
使用 ActionScript脚本实现 Init()方法:
private function Init():void
{
(, WSGetWeatherResult);
("武汉");
}
在 Init()方法中首先添加 WebService 调用后 ResultEvent的 Listener,结果返
回 后 响 应 WSGetWeatherResult 方 法 。 然 后 调 用 WebService 的
getWeatherbyCityName方法去取天气预报的数据。
getWeatherbyCityName 方法是下面 webservice提供的方法:
?
下面实现 WSGetWeatherResult 方法,用来读取得到的天气预报数据并进行
处理。
private function WSGetWeatherResult(event:ResultEvent):void
{
(,WSGetWeatherResult);
var arrC:ArrayCollection = as ArrayCollection;
if( > 0)
{
var str:String = (0).toString();
var str2:String = (1).toString();
var vbox :VBox = new VBox();
var vbox2 :VBox = new VBox();
var hbox :HBox = new HBox();
var canvas:Canvas = new Canvas();
var path:String = "assets\\weather\\";
var img1 :Image = new Image;
28
var index1 :int = new int((8).toLocaleString());
(picArray[index1]);
(img1);
var img2 :Image = new Image;
var index2 :int = new int((9).toLocaleString());
(picArray[index2]);
(img2);
var txtTem :Text = new Text();
= (5).toString();
var txtWea :Text = new Text();
= (6).toString();
var txtWind :Text = new Text();
= (7).toString();
(txtTem);
(txtWea);
(txtWind);
(hbox);
(vbox);
(vbox2);
= canvas;
var mapPnt2:MapPoint = new MapPoint(,);
(mapPnt2);
}
}
在上面函数中把得到的天气预报数据进行解析,把对应的天气图片,气温等
信息分类整理,使用 infoWindow显示出来。
完整例子可以在 samples/下面找到。
ESRI Tilemap 四叉树索引研究
注:这里仅限于讨论下面地址提供的 tilemap服务:
MapServer。
因为 ESRI 提供了 cache map功能 ,用户可以自己定义图片的大小和切割方
式。
ESRI Tilemap四叉树索引和 google map 的四叉树索引是有区别的,区别在于
google map在第一次分幅的时候分为 4片,但 esri tilemap只分为 2片,相当于
在第三和第四象限没有图。只有(0,0)(0,1)的时候才有图,这就造成了 google map
29
和 ESRI Tilemap融合的时候比较复杂,不能使用相同的分幅方法。
在下面的例子里,实现了根据显示级别(nzoom),以及经纬度取 ArcGISOnline
服务器上对应的图片。图片是 512*512的。这个算法是用 ActionScript来实现的,
也可以用其他语言去实现。
算法的核心思想是通过经纬度算出其在 nzoom level 上所对应的图片的索
引,然后拼成 url去服务器端取数据。
url 的拼接规则为:
"
D/MapServer/tile/"+nZoom+"/"+yIndex+"/"+xIndex.
其中 nZoom 为显示级别,15>nZoom>=0,yIndex 为当前经纬度对应的图片
的 Y方向索引, xIndex 为当前经纬度对应的图片的 X方向索引。
算法流程:
1 将 X轴下移 90个单位,保证第一次分幅只能分成 2幅。
2 使用四叉树编码的方式对当前(X,Y)坐标解析。
3 对四叉树编码进行解析,得到当前坐标对应图片的索引值。
算法实现为:
private function GetTileXY(nZoom:int,mp:Point):Point
{
var wx:Number;
var wy:Number;
var cx:Number;
var cy:Number;
var xArray:Array = new Array();
var yArray:Array = new Array();
cx = 0;
cy = -90;
wx = wy = 180;
var i:int = 0;
var x:int = 0;
var y:int = 0;
for (i = 0; i <= nZoom; i++)
{
if ( >= cx)
{
if ( >= cy)
{
30
(1);
(0);
cx += wx/2;
cy += wy/2;
}
else
{
(1);
(1);
cx += wx/2;
cy -= wy/2;
}
}
else
{
if ( < cy)
{
(0);
(1);
cx -= wx/2;
cy -= wy/2;
}
else
{
(0);
(0);
cx -= wx/2;
cy += wy/2;
}
}
wx = wx/2;
wy = wy/2;
}
for(i = nZoom;i >=0;i--)
{
x = x+xArray[i]*(2,nZoom-i);
y = y+yArray[i]*(2,nZoom-i);
}
var pnt :Point = new Point(x,y);
return pnt;
}
完整例子可以在 samples/ 目录下找到。
31
自定义控件的开发
ArcGIS API for Flex 本身只提供了 Navigation和 ScaleBar两个控件,如果需要
添加自己的控件,则需要自己实现。下面以实现一个能在地图上动态显示当前鼠
标经纬度的控件为例子,介绍如何实现自定义控件。
1 定义控件类,继承 UIComponent ,实现 IMapAware接口:
public class ESRIStatusBar extends UIComponent implements IMapAware
{
private var m_map:Map;
private var m_stateLabel:TextField;
public function ESRIStatusBar()
{
m_stateLabel = new TextField();
= 152;
}
}
在 ESRIStatusBar类里定义一个 TextField来显示坐标,并在 ESRIStatusBar类
的构造函数里初始化。
2 重载 createChildren函数:
override protected function createChildren() : void
{
();
var pnt:Point = new Point;
if()
{
var mapPnt:MapPoint = new MapPoint(,);
pnt = (mapPnt);
= -150;
= -16;
}
addChild(m_stateLabel);
return;
}
createChildren函数用来把 stateLabel添加到 DisplayList中,用来在地图上显
示。
3 实现 public function set map(map:Map) : void 函数:
public function set map(map:Map) : void
{
32
m_map = map;
(_MOVE,mouseMoveHandler);
(_CHANGE, extentChangeHandler);
}
set map(map:Map)用来把当前地图对象传递给 ESRIStatusBar控件,使控件能
够响应 map色事件,操纵 map上的对象。
4 添加自己的功能代码;
首先,添加对 map的MOUSE_MOVE事件的响应
(_MOVE,mouseMoveHandler);
其次,在 mouseMoveHandler中动态取得鼠标位置转换成经纬度坐标显示在
TextField上。
private function mouseMoveHandler(event:MouseEvent):void
{
if(m_map)
{
if()
{
var mapPoint : MapPoint = (,
);
= "x="+()+" ,
y="+();
}
}
}
最后,将这个 ESRIStatusBar加入到 map上:
var statusBar:ESRIStatusBar = new ESRIStatusBar();
IMapAware(statusBar).map = EsriMap;
(statusBar);
完整例子可以在 samples/下面找到。
与 Google Map 的融合
(注意,该例子使用的是 google map flex api 现在 google 网站上提供下
载的 api是 ,使用 google map flex api 将无法显示地图和控件)。
本程序的目的就是使用 Flex + google map 的基础数据+ESRI强大的分析功能
给用户提供一个良好用户体验的 GIS大众应用。
该程序的思路如下:
33
首先是绘制一个点,然后调用 ArcGIS API for Flex提供的 Geometry Service做
一个缓冲区(buffer),再通过调用 ArcGIS API for Flex 提供的 GP服务根据得到的
buffer去查询在 buffer内的人口数,最后通过 google map 的 InfoWindow显示出
来。
其中 ArcGIS API for Flex中 Geometry service,GP的调用前面已经讲过,下面
主要讲一下 gmap数据和 ESRI数据的转换,主要逻辑在GMapAddOverlay()函数中,
如下面代码:
private function GMapAddOverlay(geometry: ):void
{
switch( )
{
case :
{
var pnt :MapPoint = geometry as MapPoint ;
var markerA:Marker = new Marker(new LatLng(, ),new
MarkerOptions({strokeStyle: new StrokeStyle({color: 0x987654}),fillStyle: new FillStyle({color:
0x223344, alpha: }),radius: 12,hasShadow: true}));
(markerA);
}
break;
case :
var ii:int = 0;
var jj:int = 0;
var geometryPolyline: =
geometry as ;
var pnt1Array:Array = new Array();
for(ii = 0; ii <;ii++)
{
for(jj = 0; jj <[ii].length; jj++)
{ (new
LatLng((ii,jj).y,(ii,jj).x));
} }
var polyline: = new
(pnt1Array, new PolylineOptions({strokeStyle: new
StrokeStyle({color: 0xFF0000,thickness: 4,alpha: })}));
(polyline);
break;
case :
var i:int = 0;
var j:int = 0;
var geometryPolygon : = geometry as
34
;
var pntArray:Array = new Array();
for(i = 0; i <;i++)
{
for(j = 0; j <[i].length; j++)
{
(new
LatLng((i,j).y,(i,j).x));
}
}
var polygon: = new
(pntArray,new PolygonOptions({ strokeStyle: new
StrokeStyle({color: 0x223355,thickness: 4,alpha: }), fillStyle: new FillStyle({color:
0x223355,alpha: })}));
(polygon);
break;
}
}
ArcGIS API for Flex和 google map中几何类型的对应关系如下:
ArcGIS API for Flex google map
MapPoint Marker
Polyline Polyline
Polygon Polygon
在 GMapAddOverlay()函数中对上面 3种几何类型进行转换,将 ArcGIS API for
Flex中的几何数据转换成 google map 中的几何数据并调用 addOverlay函数添加
到地图上。
完整例子可以在 samples/目录下找到。
一 初级篇
环境搭建
概述
相关资源
创建基本程序
参考资料及其他
地图的创建
概述
创建地图
事件(Event)
绘制与符号化
概述
绘图控件的使用
符号化
地图的浏览
Task之Query & Find & Identify
概述
在mxml文档中嵌入 ActionScript
QueryTask
FindTask
IdentifyTask
InfoWindow
二 中级篇
地理定位(Locator)
概述
地理编码(GeoCode)
逆地理编码(Reverse Geocode)
地理处理(Geoprocessing)
几何服务(Geometry Service)
打印地图(Print)
GeoRSS的读取
GeoRSS概述
GeoRSS读取
三 高级篇
WebService 的使用
ESRI Tilemap 四叉树索引研究
自定义控件的开发
与Google Map 的融合