ArcGIS for Java_Flex实现自定义的Toc控件
ArcGIS for Java_ArcGIS for Flex示例3
3.Flex实现自定义的Toc控件
1)Demo.mxml(完整)
1 <?xml version="1.0" encoding="utf-8"?>
2 <!-- 3.ArcGIS Server 9.3 和 ArcGIS API for Flex实现自己的Toc控件
3 ArcGIS API for Flex沒有提供现成的Toc控件
4 前提准备:
5 1.ArcGISDynamicMapServiceLayer动态图层数据服务
6 采用发布的JNL的rest地址(http://219.146.85.39:8339/ArcGIS/rest/services/JNL/MapServer)
7 2.ArcGISTiledMapServiceLayer切片数据服务:
8 采用Esri提供的rest世界地图数据服务(http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer)
9 -->
10 <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
11 backgroundColor="white" xmlns:esri="http://www.esri.com/2008/ags"
12 xmlns:uc="uc.*">
13 <!-- 1)添加一个id为arr的对象数组作为ComboBox的数据源-->
14 <mx:Array id="arr">
15 <!-- 数组包含2个对象:一个是发布的rest地址;一个是Esri提供的在线rest地址-->
16 <mx:Object label="JNL" data="http://219.146.85.39:8339/ArcGIS/rest/services/JNL/MapServer"/>
17 <mx:Object label="World" data="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
18 </mx:Array>
19 <!-- 2)添加ComboBox控件,用来地图切换显示,数据源来自id为arr的数组对象-->
20 <mx:ComboBox id="myURL" selectedIndex="0" horizontalCenter="-329" dataProvider="{arr}" y="10">
21 </mx:ComboBox>
22 <esri:Map panArrowsVisible="true" logoVisible="false" width="663" height="388"
23 x="33" y="40" borderStyle="solid" borderThickness="3">
24 <!-- Map控件的ArcGISDynamicMapServiceLayer的url属性绑定ComboBox的选择值
25 当ComboBox的选择发生变化时地图也会根据rest地址进行切换显示。-->
26 <esri:ArcGISDynamicMapServiceLayer id="myDynamicService" url="{myURL.selectedItem.data}"
27 load="myDynamicService.defaultVisibleLayers()"/>
28 </esri:Map>
29 <!-- 添加TreeToc,且设置一个layer的属性值是绑定myDynamicService(注意x,y的值决定TreeToc控件的位置;height,width决定控件大小,超出范围出现滚动条)-->
30 <uc:TreeToc layer="{myDynamicService}" height="288" width="233" x="706" y="40" borderThickness="3"/>
31 </mx:Application>
效果图:
2)实现Toc功能TreeToc.mxml:
1 <?xml version="1.0" encoding="utf-8"?>
2 <!-- Toc控件
3 1) 在src目录下添加一个uc的目录,在uc下新建TreeToc.mxml文件来实现Toc功能。这里是在Flex提供的Tree控件的基础上实现的。
4 2) Tree控件获取Layers数据作为数据源进行绑定显示,同时提供显示图层隐藏图层等方法。
5 3) Tree控件添加一个叫uc.TreeRenderer的itemRenderer(项渲染器),也就是Tree的每一个节点都由这个itemRenderer来负责显示。
6 也就需要实现uc.TreeRenderer的功能
7 4) 在uc目录下增加TreeRenderer.mxml文件。-->
8 <mx:Tree xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" fontSize="12">
9 <mx:Script>
10 <![CDATA[
11 import com.esri.ags.layers.ArcGISDynamicMapServiceLayer;
12 import mx.controls.Label;
13 import mx.collections.ArrayCollection;
14 import com.esri.ags.layers.ArcIMSMapServiceLayer;
15 import com.esri.ags.events.LayerEvent;
16 import com.esri.ags.layers.Layer;
17 import com.esri.ags.layers.LayerInfo;
18 import mx.utils.ObjectUtil;
19
20 private var layerInfos:Array;
21 //图层
22 private var _layer:Layer;
23 //图层是否更新标识
24 private var _layerChanged:Boolean;
25 //获取图层
26 public function get layer():Layer
27 {
28 return _layer;
29 }
30 //设置图层
31 public function set layer(value:Layer):void
32 {
33 _layer=value;
34 _layerChanged=true;
35 invalidateProperties();
36 }
37 //设置组件属性
38 override protected function commitProperties():void
39 {
40 if(_layerChanged){
41 _layerChanged=false;
42 if(layer)
43 {
44 //为layer添加完成后取消鼠标忙碌显示的监听事件
45 layer.addEventListener(Event.COMPLETE,removeBusyCursor,false,0,true);
46 //为layer添加发生错误后取消鼠标忙碌显示的监听事件
47 layer.addEventListener(IOErrorEvent.IO_ERROR,removeBusyCursor,false,0,true);
48 if(layer.loaded)
49 {
50 //如果layer载入完成为DataGrid设置数据源
51 setDataProvider();
52 }
53 else
54 {
55 //如果未载入完成为layer添加载入监听事件
56 layer.addEventListener(LayerEvent.LOAD,layerLoadHandler,false,0,true);
57 }
58 }
59 }
60 super.commitProperties();
61 }
62 //设置数据源
63 private function setDataProvider():void
64 {
65 if(layer is ArcGISDynamicMapServiceLayer)
66 {
67 layerInfos=ArcGISDynamicMapServiceLayer(layer).layerInfos;
68 }
69 else if(layer is ArcIMSMapServiceLayer)
70 {
71 layerInfos=ArcIMSMapServiceLayer(layer).layerInfos;
72 }
73 registerClassAlias("com.esri.ags.layers.LayerInfo",LayerInfo);
74 //ObjectUtil.copy方法接受一个对象作为参数而返回一个在内存的新位置的此对象的深度拷贝,类似克隆
75 layerInfos=ObjectUtil.copy(layerInfos) as Array;
76 dataProvider=layerInfos;
77 //labelField="name";
78 }
79 private function layerLoadHandler(event:LayerEvent):void
80 {
81 setDataProvider();
82 }
83 //显示图层方法
84 public function showLayer(layerInfo:LayerInfo):void
85 {
86 var visibleLayers:ArrayCollection;
87 if(layer is ArcGISDynamicMapServiceLayer)
88 {
89 //获取当前可见图层列表
90 visibleLayers=ArcGISDynamicMapServiceLayer(layer).visibleLayers;
91 //在当前可见图层列表中加入要显示的图层
92 visibleLayers.addItem(layerInfo.id);
93 }
94 else if(layer is ArcIMSMapServiceLayer)
95 {
96 //获取当前可见图层列表
97 visibleLayers=ArcIMSMapServiceLayer(layer).visibleLayers;
98 //在当前可见图层列表中加入要显示的图层
99 visibleLayers.addItem(layerInfo.id);
100 }
101 //设置鼠标显示状态
102 if(visibleLayers)
103 {
104 cursorManager.setBusyCursor();
105 }
106 }
107 //隐藏图层方法
108 public function hideLayer(layerInfo:LayerInfo):void
109 {
110 var visibleLayers:ArrayCollection;
111 if(layer is ArcGISDynamicMapServiceLayer)
112 {
113 //获取当前可见图层列表
114 visibleLayers=ArcGISDynamicMapServiceLayer(layer).visibleLayers;
115 //查找要隐藏的图层的index
116 var index:int=visibleLayers.getItemIndex(layerInfo.id);
117 //在当前可见图层列表中去除要隐藏的图层
118 if(index!=-1)
119 {
120 visibleLayers.removeItemAt(index);
121 }
122 }
123 else if(layer is ArcIMSMapServiceLayer)
124 {
125 //获取当前可见图层列表
126 visibleLayers=ArcIMSMapServiceLayer(layer).visibleLayers;
127 //查找要隐藏的图层的index
128 var index2:int=visibleLayers.getItemIndex(layerInfo.id);
129 //在当前可见图层列表中去除要隐藏的图层
130 if(index2!=-1)
131 {
132 visibleLayers.removeItemAt(index2);
133 }
134 }
135 //设置鼠标显示状态
136 if(visibleLayers)
137 {
138 cursorManager.setBusyCursor();
139 }
140 }
141 private function removeBusyCursor(event:Event):void
142 {
143 //删除忙光标
144 cursorManager.removeBusyCursor();
145 }
146
147 ]]>
148 </mx:Script>
149 <mx:itemRenderer>
150 uc.TreeRenderer
151 </mx:itemRenderer>
152 </mx:Tree>
3)实现uc.TreeRenderer功能TreeRenderer.mxml:
1 <?xml version="1.0" encoding="utf-8"?>
2 <!-- 实现uc.TreeRenderer功能
3 1) 在uc目录下增加TreeRenderer.mxml文件,
4 这里因为是itemRenderer,所以需要implements="mx.controls.listClassed.IDropInListItemRenderer"
5 2) 在HBox控件中包含一个CheckBox、一个Image、一个Label(空间内三项一字排列,每行左对齐),且为CheckBox添加点击事件可以控制图层的隐藏显示。
6 -->
7 <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" horizontalAlign="left"
8 implements="mx.controls.listClasses.IDropInListItemRenderer">
9 <mx:Script>
10 <![CDATA[
11 import com.esri.ags.layers.LayerInfo;
12 import mx.controls.listClasses.BaseListData;
13
14 //图标图片
15 [Bindable]
16 //src下创建目录assets,存放图片Dataframe.GIF
17 [Embed(source="assets/Dataframe.GIF")]
18 public var layericon:Class;
19
20 private var _listData:BaseListData;
21
22 public function get listData():BaseListData
23 {
24 return _listData;
25 }
26
27 public function set listData(value:BaseListData):void
28 {
29 _listData=value;
30 }
31 //checkbox的点击事件
32 private function clickHandler(event:MouseEvent):void
33 {
34 var layerInfo:LayerInfo=LayerInfo(data);
35 if(cb.selected)
36 {
37 layerInfo.defaultVisibility=true;
38 //调用TreeToc显示图层方法
39 TreeToc(listData.owner).showLayer(layerInfo);
40 }
41 else
42 {
43 layerInfo.defaultVisibility=false;
44 //调用TreeToc隐藏图层方法
45 TreeToc(listData.owner).hideLayer(layerInfo);
46 }
47 }
48 ]]>
49 </mx:Script>
50 <mx:CheckBox id="cb" selected="{data.defaultVisibility}" click="clickHandler(event)"/>
51 <mx:Image source="{layericon}"/>
52 <mx:Label text="{data.name}"/>
53 </mx:HBox>
4)在Demo.mxml页面使用Toc控件:
<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.*">
… …
<!-- 添加TreeToc,且设置一个layer的属性值是绑定myDynamicService(注意x,y的值决定TreeToc控件的位置;height,width决定控件大小,超出范围出现滚动条)-->
<uc:TreeToc layer="{myDynamicService}" height="288" width="233" x="696" y="40" borderThickness="3"/>
</mx:Application>