作者:Flyingis
本文严禁用于商业目的,如需转载请注明作者及原文链接,其他疑问请联系:dev.vip#gmail.com
在ArcGIS Flex API中探索Flex使用是一种不错的学习方法,可以相互辅助理解ArcGIS Flex API和Flex,这两天重新翻阅了一些官方资料,写一点小结,从之前的一篇事件开始。
ArcGIS Flex API是基于Flex API的一个开发库,开发之前需要导入agslib.swc,根据WebGIS所需的功能可以想到,事件是用户和地图进行交互的基础,没有丰富的事件交互机制就很难为用户提供完整的WebGIS应用体验,如果换成是自己去设计ArcGIS Flex API,我们会从哪些功能需求入手?
点击图层的地理要素进行查询,鼠标移动到查询图层的地理要素上方,异步弹出该要素基本信息窗口。没错,这些都是WebGIS的基本需求,那么通过一个sample看在ArcGIS Flex API如何使用事件。
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
pageTitle="Map Click (but not on pan & zoom)"
xmlns:esri="http://www.esri.com/2008/ags"
layout="absolute"
>
<mx:Script>
<![CDATA[/** * Problem: You want to capture a "click" on the map, but not a pan or other mouse navigation actions. *
Solution: Use mouseDown and panStart instead of the click property. */
import mx.controls.Button;
import mx.controls.Text;
import com.esri.ags.geometry.MapPoint;
import com.esri.ags.events.PanEvent;
private function mouseDownHandler(event:MouseEvent):void
{
if (!event.shiftKey)
{
myMap.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
}
private function panStartHandler(event:PanEvent):void
{
myMap.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
private function mouseUpHandler(event:MouseEvent):void
{
myMap.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
var mapPoint:MapPoint= myMap.toMapFromStage(event.stageX, event.stageY);
myMap.infoWindow.label = "You clicked here";
myMap.infoWindow.show( mapPoint ); // "Show the click"
}
]]>
</mx:Script>
<esri:Map id="myMap" mouseDown="mouseDownHandler(event)" panStart="panStartHandler(event)">
<esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>
</esri:Map>
</mx:Application>
PanEvent是ArcGIS Flex API中自定义的事件,继承了flash.events.Event,上面例子中所有事件的管理通过addEventListener和 removeEventListenser两个方法实现,并且通过鼠标对地图的点击动作的分解,实现在鼠标点击不同阶段的事件响应,属性信息的获取在 MouseUp阶段,toMapFromStage实现屏幕坐标到地图坐标的转换,并将结果显示在infoWindow中。
具体的组件中,ArcGISTiledMapServiceLayer和ArcGIS Javascript API中的功能相同,将缓存好的地图服务添加到页面上,"esri"是一个标识符,在mxml页面最上方"xmlns:esri="http://www.esri.com/2008/ags"申明,用以在mxml中使用已定义好的组件。
ArcGIS Flex API Events Demo包含了常用的一些事件,可以作为参考学习。从下面例子可以了解到,图层加载、图层添加删除、地图放大缩小、地图平移等都被ArcGIS Flex API Events进行了封装,加上原有的鼠标事件就可以基本满足WebGIS应用要求了。
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:esri="http://www.esri.com/2008/ags"
pageTitle="Event handling"
layout="absolute"
creationComplete="onApplicationCreationComplete()"
>
<mx:Script>
<![CDATA[
import flash.geom.Point;
import com.esri.ags.events.LayerEvent;
import com.esri.ags.events.ExtentEvent;
import com.esri.ags.events.MapEvent;
import com.esri.ags.events.PanEvent;
import com.esri.ags.events.ZoomEvent;
import com.esri.ags.geometry.MapPoint;
import mx.events.FlexEvent;
[Bindable] private var mapCoordX : Number = 0;
[Bindable] private var mapCoordY : Number = 0;
[Bindable] private var pixelCoordX : Number = 0;
[Bindable] private var pixelCoordY : Number = 0;
private function onMouseMove( event : MouseEvent ) : void
{
if (my Map.loaded)
{
var mapPoint : MapPoint = myMap.toMapFromStage(event.stageX, event.stageY);
mapCoordX = mapPoint.x;
mapCoordY = mapPoint.y;
var mapLocalPixelPoint : Point = myMap.globalToLocal( new Point(event.stageX, event.stageY) );
pixelCoordX = mapLocalPixelPoint.x;
pixelCoordY = mapLocalPixelPoint.y;
}
}
public function onApplicationCreationComplete():void
{
// Map Navigation Events
myMap.addEventListener(ExtentEvent.EXTENT_CHANGE, logExtentEvent);
myMap.addEventListener(PanEvent.PAN_START, logPanEvent);
myMap.addEventListener(PanEvent.PAN_UPDATE, logPanEvent);
myMap.addEventListener(PanEvent.PAN_END, logPanEvent);
myMap.addEventListener(ZoomEvent.ZOOM_START, logZoomEvent);
myMap.addEventListener(ZoomEvent.ZOOM_UPDATE, logZoomEvent);
myMap.addEventListener(ZoomEvent.ZOOM_END, logZoomEvent);
myMap.addEventListener(MouseEvent.CLICK, logMouseEvent);
myMap.addEventListener(MouseEvent.DOUBLE_CLICK, logMouseEvent);
myMap.addEventListener(MouseEvent.MOUSE_WHEEL, logMouseEvent);
myMap.addEventListener(MapEvent.LAYER_ADD, logMapEvent);
myMap.addEventListener(MapEvent.LAYER_REORDER, logMapEvent);
myMap.addEventListener(MapEvent.LOAD, logMapEvent);
aims.addEventListener(LayerEvent.LOAD, logLayerEvent);
log.text = "2. Application creation complete\n" + log.text;
}
public function onMapCreationComplete():void
{
myMap.infoWindow.addEventListener(FlexEvent.HIDE, logInfoWindowFlexEvent);
myMap.infoWindow.label = "Clicking the 'x' will \nthrow 'hide' event";
// put the infoWindow in the middle of the map
var myPoint:MapPoint = new MapPoint(0,0);
myMap.infoWindow.show(myPoint);
log.text = "1. Map creation complete\n" + log.text;
}
public function logInfoWindowEvent(event:Event):void
{
log.text = "* Event (infoWindow): " + event.type + "\n" + log.text;
}
public function logInfoWindowFlexEvent(event:FlexEvent):void
{
log.text = "* FlexEvent (infoWindow): " + event.type + "\n" + log.text;
}
public function logMouseEvent(event:MouseEvent):void
{
log.text = "* MouseEvent: " + event.type + "\n" + log.text;
}
public function logExtentEvent(event:ExtentEvent):void
{
log.text = "* ExtentEvent: " + event.type + "\n" + log.text;
}
public function logPanEvent(event:PanEvent):void
{
log.text = "* PanEvent: " + event.type + "\n" + log.text;
}
public function logZoomEvent(event:ZoomEvent):void
{
log.text = "* ZoomEvent: " + event.type + "\n" + log.text;
}
public function logMapEvent(event:MapEvent):void
{
log.text = "* MapEvent: " + event.type + "\n" + log.text;
}
public function logLayerEvent(event:LayerEvent):void
{
log.text = "* LayerEvent: " + event.type + "\n" + log.text;
}
]]>
</mx:Script>
<mx:HDividedBox width="100%" height="100%">
<esri:Map id="myMap"
mouseMove="onMouseMove(event)"
crosshairVisible="true"
creationComplete="onMapCreationComplete()"
>
<esri:extent>
<esri:Extent xmin="-45" ymin="-45" xmax="45" ymax="45">
<esri:SpatialReference wkid="4326"/>
</esri:Extent>
</esri:extent>
<esri:ArcIMSMapServiceLayer id="aims" creationComplete="log.text='MapLayer creation complete\n'+log.text;" load="log.text='MapLayer loaded\n'+log.text;"
serviceHost="http://www.geographynetwork.com"
serviceName="ESRI_Time"
/>
<esri:GraphicsLayer visible="true" creationComplete="log.text='GraphicLayer creation complete\n'+log.text;" load="log.text='GraphicLayer loaded\n'+log.text;">
<esri:Graphic toolTip="-70.488281,41.660156" visible="true">
<esri:geometry>
<esri:MapPoint x="-70.488281" y="41.660156" spatialReference="{new SpatialReference(4326)}"/>
</esri:geometry>
<esri:symbol>
<esri:SimpleMarkerSymbol id="symbol" color="0xFF0000" size="10" alpha="0.75"/>
</esri:symbol>
</esri:Graphic>
</esri:GraphicsLayer>
</esri:Map>
<mx:Panel layout="vertical" height="100%">
<mx:Text width="250" text="You can listen to many different events both our Map Navigation specific events, as well as general Flex events."/>
<mx:TextArea width="100%" height="100%" id="log"/>
<mx:HBox borderStyle="solid">
<mx:Label text="Pixel x: {pixelCoordX}" paddingBottom="0"/>
<mx:Label text="Pixel y: {pixelCoordY}" paddingBottom="0"/>
</mx:HBox>
<mx:HBox borderStyle="solid">
<mx:Label text="Map x: {mapCoordX.toFixed(4)}" paddingBottom="0"/>
<mx:Label text="Map y: {mapCoordY.toFixed(4)}" paddingBottom="0"/>
</mx:HBox>
<mx:Label text="spatial reference: {myMap.spatialReference.wkid}"/>
</mx:Panel>
</mx:HDividedBox>
</mx:Application>