ArcGIS.Server.9.3和ArcGIS API for Flex实现自己的Toc控件(三)
目的:
1.ArcGIS API for Flex没有提供现成的Toc控件,这里来实现自己的Toc控件。
准备工作:
1.在ArcGIS.Server.9.3发布一个叫USA的Map Service,并且把这个Service启动起来。
完成后的效果图:

开始:
1.启动Flex Builder3新建工程以及引入ArcGIS API for Flex library的开发包,这个过程前面2篇都讲过了这里就不啰嗦了。
2.新建LayersOnAndOff.mxml页面,然后在页面上添加Map控件以及设置ArcGISDynamicMapServiceLayer,添加一个ComboBox控件用来地图切换显示。具体代码如下:
<?xml version="1.0" encoding="utf-8"?>2
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundColor="white" xmlns:esri="http://www.esri.com/2008/ags" >3
<mx:Array id="arr">4
<mx:Object label="USA" data="http://jh-53a435fbc0e8/ArcGIS/rest/services/USA/MapServer" />5
<mx:Object label="USA_2D" data="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Population_World/MapServer" />6
</mx:Array>7
<mx:ComboBox id="myURL" selectedIndex="0" horizontalCenter="-329" dataProvider="{arr}" y="10">8
</mx:ComboBox>9
<esri:Map logoVisible="false" panArrowsVisible="true" width="463" height="288" x="33" y="40" borderStyle="solid" borderThickness="3">10
<esri:ArcGISDynamicMapServiceLayer id="myDynamicService" url="{myURL.selectedItem.data}" load="myDynamicService.defaultVisibleLayers()"/>11
</esri:Map>12
</mx:Application>3.对上面的代码做一下解释,首先添加了一个id为arr的对象数组作为ComboBox的数据源,arr的对象数组包含2个对象:一个是上面发布的USA得rest地址,一个是Esri提供的在线的rest地址。然后在Map控件的ArcGISDynamicMapServiceLayer的url属性绑定ComboBox的选择值,这样当ComboBox选择发生变化时地图也会根据rest地址进行切换显示。
4.接下来做Toc控件了,首先在src目录下新添加一个叫uc的目录,然后在uc下新建TreeToc.mxml文件这个就是用来实现Toc功能的。Toc控件这里是用Flex提供的Tree控件的基础上实现的,具体代码如下:
<?xml version="1.0" encoding="utf-8"?>2
<mx:Tree xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" fontSize="12">3
<mx:Script>4
<![CDATA[5
import mx.collections.ArrayCollection;6
import com.esri.ags.layers.ArcIMSMapServiceLayer;7
import com.esri.ags.layers.ArcGISDynamicMapServiceLayer;8
import com.esri.ags.events.LayerEvent;9
import com.esri.ags.layers.Layer;10
import com.esri.ags.layers.LayerInfo;11
import mx.utils.ObjectUtil;12
13
private var layerInfos:Array;14
//图层15
private var _layer:Layer;16
//图层是否更新标识17
private var _layerChanged:Boolean;18
//获取图层19
public function get layer():Layer20
{21
return _layer;22
}23
//设置图层24
public function set layer(value:Layer):void25
{26
_layer = value;27
_layerChanged=true;28
invalidateProperties();29
}30
//设置组件属性31
override protected function commitProperties():void32
{33
if (_layerChanged)34
{35
_layerChanged = false;36
if(layer)37
{38
//为layer添加完成后取消鼠标忙碌显示的监听事件39
layer.addEventListener(Event.COMPLETE, removeBusyCursor, false, 0, true);40
//为layer添加发生错误后取消鼠标忙碌显示的监听事件41
layer.addEventListener(IOErrorEvent.IO_ERROR, removeBusyCursor, false, 0, true);42
43
if(layer.loaded)44
{45
//如果layer载入完成为DataGrid设置数据源46
setDataProvider();47
}48
else49
{50
//如果未载入完成为layer添加载入监听事件51
layer.addEventListener(LayerEvent.LOAD, layerLoadHandler, false, 0, true);52
}53
}54
}55
super.commitProperties();56
}57
//设置数据源58
private function setDataProvider():void59
{60
if(layer is ArcGISDynamicMapServiceLayer)61
{62
layerInfos=ArcGISDynamicMapServiceLayer(layer).layerInfos;63
}64
else if(layer is ArcIMSMapServiceLayer)65
{66
layerInfos = ArcIMSMapServiceLayer(layer).layerInfos;67
}68
registerClassAlias("com.esri.ags.layers.LayerInfo", LayerInfo);69
//ObjectUtil.copy方法接受一个对象做为参数而返回一个在内存的新位置的此对象的深度拷贝,类似克隆70
layerInfos = ObjectUtil.copy(layerInfos) as Array;71
dataProvider = layerInfos;72
//labelField="name";73
74
}75
76
private function layerLoadHandler(event:LayerEvent):void77
{78
setDataProvider();79
}80
//显示图层方法81
public function showLayer(layerInfo:LayerInfo):void82
{83
var visibleLayers:ArrayCollection;84
if(layer is ArcGISDynamicMapServiceLayer)85
{86
//获取当前可见图层列表87
visibleLayers=ArcGISDynamicMapServiceLayer(layer).visibleLayers;88
//在当前可见图层列表中加入要显示的图层89
visibleLayers.addItem(layerInfo.id);90
}91
else if(layer is ArcIMSMapServiceLayer)92
{93
//获取当前可见图层列表94
visibleLayers=ArcIMSMapServiceLayer(layer).visibleLayers;95
//在当前可见图层列表中加入要显示的图层96
visibleLayers.addItem(layerInfo.id);97
}98
//设置鼠标显示状态99
if (visibleLayers)100
{101
cursorManager.setBusyCursor();102
}103
}104
//隐藏图层方法105
public function hideLayer(layerInfo:LayerInfo):void106
{107
var visibleLayers:ArrayCollection;108
if(layer is ArcGISDynamicMapServiceLayer)109
{110
//获取当前可见图层列表111
visibleLayers=ArcGISDynamicMapServiceLayer(layer).visibleLayers;112
//查找要隐藏的图层的index113
var index:int=visibleLayers.getItemIndex(layerInfo.id);114
//在当前可见图层列表中去除要隐藏的图层115
if (index != -1)116
{117
visibleLayers.removeItemAt(index);118
}119
}120
else if(layer is ArcIMSMapServiceLayer)121
{122
//获取当前可见图层列表123
visibleLayers=ArcIMSMapServiceLayer(layer).visibleLayers;124
//查找要隐藏的图层的index125
var index2:int=visibleLayers.getItemIndex(layerInfo.id);126
//在当前可见图层列表中去除要隐藏的图层127
if (index2 != -1)128
{129
visibleLayers.removeItemAt(index2);130
}131
}132
//设置鼠标显示状态133
if (visibleLayers)134
{135
cursorManager.setBusyCursor();136
}137
}138
139
private function removeBusyCursor(event:Event):void140
{141
//删除忙光标142
cursorManager.removeBusyCursor();143
}144
]]>145
</mx:Script>146
<mx:itemRenderer>147
uc.TreeRenderer148
</mx:itemRenderer>149
</mx:Tree>150

5.对上面的代码做一下解释,首先Toc控件是在Tree控件的基础上实现的,这个Tree控件获取Layers数据作为数据源进行绑定显示,同时提供了显示图层隐藏图层等方法。最后这个Tree添加了一个叫uc.TreeRenderer的itemRenderer(项渲染器),也就是说Tree的每一个节点都是由这个itemRenderer来负责显示。那也就是说还需要实现uc.TreeRenderer的功能。
6.在uc目录下新增加TreeRenderer.mxml的文件,这个因为是itemRenderer所以需要implements="mx.controls.listClasses.IDropInListItemRenderer",具体代码如下:
<?xml version="1.0" encoding="utf-8"?>2
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" horizontalAlign="left" implements="mx.controls.listClasses.IDropInListItemRenderer">3
<mx:Script>4
<![CDATA[5
import com.esri.ags.layers.LayerInfo;6
import mx.controls.listClasses.BaseListData;7
8
//图标图片9
[Bindable] 10
[Embed(source="assets/Dataframe.GIF")]11
public var layericon:Class; 12
13
private var _listData:BaseListData;14
15
public function get listData():BaseListData16
{17
return _listData;18
}19
20
public function set listData(value:BaseListData):void21
{22
_listData = value;23
}24
//checkbox的点击事件25
private function clickHandler(event:MouseEvent):void26
{27
var layerInfo:LayerInfo = LayerInfo(data);28
29
if (cb.selected)30
{31
layerInfo.defaultVisibility = true;32
//调用TreeToc显示图层方法33
TreeToc(listData.owner).showLayer(layerInfo);34
}35
else36
{37
layerInfo.defaultVisibility = false;38
//调用TreeToc隐藏图层方法39
TreeToc(listData.owner).hideLayer(layerInfo);40
}41
}42
]]>43
</mx:Script>44
<mx:CheckBox id="cb" selected="{data.defaultVisibility}" click="clickHandler(event)"/>45
<mx:Image source="{layericon}"/>46
<mx:Label text="{data.name}"/>47
48
</mx:HBox>49

8.这样完成了Toc控件的开发,接下来是要在LayersOnAndOff.mxml页面使用这个控件,增加如下代码(红色部分):
<?xml version="1.0" encoding="utf-8"?>2
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundColor="white" xmlns:esri="http://www.esri.com/2008/ags" xmlns:uc="uc.*" >3
<mx:Array id="arr">4
<mx:Object label="USA" data="http://jh-53a435fbc0e8/ArcGIS/rest/services/USA/MapServer" />5
<mx:Object label="USA_2D" data="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Population_World/MapServer" />6
</mx:Array>7
<mx:ComboBox id="myURL" selectedIndex="0" horizontalCenter="-329" dataProvider="{arr}" y="10">8
</mx:ComboBox>9
<esri:Map logoVisible="false" panArrowsVisible="true" width="463" height="288" x="33" y="40" borderStyle="solid" borderThickness="3">10
<esri:ArcGISDynamicMapServiceLayer id="myDynamicService" url="{myURL.selectedItem.data}" load="myDynamicService.defaultVisibleLayers()"/>11
</esri:Map>12
<uc:TreeToc layer="{myDynamicService}" height="288" width="210" x="504" y="40" borderThickness="3"/>13
</mx:Application> 14


浙公网安备 33010602011771号