我们之前分别品尝过Yahoo! Maps可口的甜饼、辛辣的烧饼,经过长时间的等待后,最近Yahoo终于发布了其旗下产品的Flash AS3开发类库,该类库包含Answers、Weather、Search、Upcoming.org及Maps等多项产品的开源AS3类库,开始了对As3的全面支持,Yahoo ActionScript 3 API大餐降临人间,今天我们就来和大家说说在Flex 2中怎样使用Yahoo!Maps AS3类库来创建我们自己的Yahoo!Maps Flex2应用…
我们之前分别品尝过Yahoo! Maps可口的甜饼、辛辣的烧饼,经过长时间的等待后,最近Yahoo终于发布了其旗下产品的Flash AS3开发类库,该类库包含Answers、Weather、Search、Upcoming.org及Maps等多项产品的开源AS3类库,开始了对As3的全面支持,Yahoo ActionScript 3 API大餐降临人间,今天我们就来和大家说说在Flex 2中怎样使用Yahoo!Maps AS3类库来创建我们自己的Yahoo!Maps Flex2应用。
从本次发布的Yahoo! Maps AS3类库的框架结构来看,Yahoo并没有将其Maps产品开发真正转向AS3转向Flex 2,这并不是一个真正意义的Yahoo! Maps As3类库,而只是一组通过ExternalInterface调用的Yahoo! Maps As2类库的AS3封装。实际所有的地图操作都是通过As2 API进行的。所以官方对该类库的称呼是:Yahoo! Maps AS3 Communication Kit,因为它只是一个As3到As2的通信包而已,不过却很精巧
该AS3通信包的核心组件是com.yahoo.webapis.maps.YahooMapService,该类继承mx.controls.SWFLoader,它的作用就是载入As2类库,并在载入AS2 SWF文件时,通过URL将AS3的ID等信息传递给AS2。而As3与As2之间的跨虚拟机通信也很简单,所有的通信都是通过HTML页面中的负责载入SWF的Object对象来交互的,首先在As2端通过ExternalInterface.addCallback方法将与Yahoo!Maps相关的API方法添加到HTML中Object对象上以提供给AS3调用(例如:ExternalInterface.addCallback( ’setPanTool’ + id, this, setPanTool )),而AS3/Flex2端则通过ExternalInterface.call方法调用前面As2端添加到HTML Object对象上的方法(如:ExternalInterface.call(super.swfDomId + “.setPanTool” + super.UUID,data:bool))来对Yahoo!Maps进行操作。相应的,As3/Flex2端将用来监听Yahoo!Maps事件的方法通过ExternalInterface.addCallback添加到HTML页面中的Object对象中,而在As2监听到了Yahoo!Maps相应的事件时,通过ExternalInterface.call来调用As3中的事件监听方法。整个交互的过程简单和精巧,对ExternalInterface的应用简直到了炉火纯青的地步,如果您觉得我表述的不清楚,可以看下面的以上原理部分概念图,因为Flex中监听Yahoo!maps事件与调用的过程类似只不过是正好相反的过程,所以没有将其画出。您如果花点时间好好看看Yahoo!Maps As3类库您一定会有很大收获的。
说了半天原理,现在我们开始动手构建我们的Yahoo!Maps应用,首先下载Yahoo!As3类库,将下载的zip文件解压,然后将source/as3目录添加到您的Flex工程的代码路径就可以了,另外在examples/maps/pipes目录下的as2map.swf是实际与Yahoo!Maps服务进行交互的As2类库,请将其复制到您的Flex工程的bin目录中。详细的安装方法设置方法请看官方说明。
要在Flex2中构建Yahoo!Maps应用,首先我们需要声明Yahoo!Maps使用的命名空间,例如:
[xml]
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:yahoo="com.yahoo.webapis.maps.*"
layout="absolute">
然后再定义以下几个变量:
- SWFDOMID:String,与HTML页面中的<OBJECT/>标签的ID号一致,供调用Object上的外部方法使用,一般FlexBuilder生成的HTML页面中Object标签的id为Flex主程序的文件名。所以我们这里一般定义SWFDOMID为使用Yahoo!Maps服务的Flex2 Mxml文件名。
- UNIQUEID:int,用于在AVM通信过程中唯一标识应用,避免但应用多个实例的情况下出现冲突。官方的做法使用使用mx.utils.getTimer()来生成UNIQUEID。
- YAHOOAPIKEY:String,向Yahoo申请的开发基于Yahoo!服务的API Key。如果您没有,可以到这里申请。
- MAPSWF:String,As2 Lib SWF文件完整路径名,如as2map.swf。
下面是定义好以上变量的代码:
[xml]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:yahoo="com.yahoo.webapis.maps.*"
layout="absolute">
<mx:Script>
<![CDATA[
import flash.utils.getTimer;
private const SWFDOMID:String = "YahooAS3Maps";
private const UNIQUEID:int = getTimer();
private const YAHOOAPIKEY:String = "InsertYourAPIKeyHere";
private const MAPSWF:String = "as2map.swf";
]]>
</mx:Script>
</mx:Application>
接着,我们实际将Yahoo!Maps添加到我们的应用中,代码很简单仅仅只需要增加一个yahoo:YahooMapService标签就可以了:
[xml]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:yahoo="com.yahoo.webapis.maps.*"
layout="absolute">
<mx:Script>
<![CDATA[
import flash.utils.getTimer;
private const SWFDOMID:String = "YahooAS3Maps_Prac1";
private const UNIQUEID:int = getTimer();
private const YAHOOAPIKEY:String = "InsertYourAPIKeyHere";
private const MAPSWF:String = "as2map.swf";
]]>
</mx:Script>
<yahoo:YahooMapService id="myAS2Map" UUID="{UNIQUEID}"
swfDomId="{SWFDOMID}" apiId="{YAHOOAPIKEY}" mapURL = "{MAPSWF}"
horizontalCenter="0" verticalCenter="0" />
</mx:Application>
以上代码我们已经将Yahoo!Maps载入到了我们的Flex2应用中,因为载入地图数据需要时间,如果网络或其他的问题,这个载入过程可能失败,所以在添加后续的功能前,我们需要知道什么时候地图载入了、载入失败是否失败。这个很容易,只需要监听YahooMapService的onMapLoad和onMapError事件就可以了,代码如下:
[xml]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:yahoo="com.yahoo.webapis.maps.*"
layout="absolute" creationComplete="init();" >
<mx:Script>
<![CDATA[
import flash.utils.getTimer;
import mx.controls.Alert;
private const SWFDOMID:String = "YahooAS3Maps_Prac2";
private const UNIQUEID:int = getTimer();
private const YAHOOAPIKEY:String = "Bw7URnLV34GfW9XPiq2zQOoVbmh0h7S5s2W6F3qya9uDVR2HDqpodcYvpcWc";
private const MAPSWF:String = "as2map.swf";
private function init():void {
myAS2Map.addEventListener('onMapLoad', onMapLoaded);
myAS2Map.addEventListener('onMapError', onMapError);
}
private function onMapLoaded(ev:Object):void {
}
private function onMapError(errorCode:String, httpStatus:String):void {
Alert.show(errorCode + '\n' + httpStatus, 'Load Error');
}
]]>
</mx:Script>
<yahoo:YahooMapService id="myAS2Map" UUID="{UNIQUEID}"
swfDomId="{SWFDOMID}" apiId="{YAHOOAPIKEY}" mapURL = "{MAPSWF}"
horizontalCenter="0" verticalCenter="0" />
</mx:Application>
您可以能已经注意到了,前面示例中的地图只是显示出来,不能进行任何的如拖动等的交互操作,还不能像实际的Yahoo!Maps一样可以鼠标点击或拖动,下面我们将逐步完善我们的代码以实现一个完之的Yahoo!Maps应用。
首先添加鼠标点击和拖动操作支持,在Yahoo!Maps载入后,我们在onMapLoaded先初始化一个com.yahoo.webapis.maps.methodgroups.PanTool类,然后使用PanTool.setPanTool(true)使得Pantools可用:
[xml]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:yahoo="com.yahoo.webapis.maps.*"
layout="absolute" creationComplete="init();" >
<mx:Script>
<![CDATA[
import flash.utils.getTimer;
import mx.controls.Alert;
/***this is the new line***/
import com.yahoo.webapis.maps.methodgroups.*;
private const SWFDOMID:String = "YahooAS3Maps_Prac3";
private const UNIQUEID:int = getTimer();
private const YAHOOAPIKEY:String = "Bw7URnLV34GfW9XPiq2zQOoVbmh0h7S5s2W6F3qya9uDVR2HDqpodcYvpcWc";
private const MAPSWF:String = "as2map.swf";
private function init():void {
myAS2Map.addEventListener('onMapLoad', onMapLoaded);
myAS2Map.addEventListener('onMapError', onMapError);
}
private function onMapLoaded(ev:Object):void {
/***this is the new line***/
var panTools:PanTool = new PanTool(myAS2Map);
panTools.setPanTool(true);
}
private function onMapError(errorCode:String, httpStatus:String):void {
Alert.show(errorCode + '\n' + httpStatus, 'Load Error');
}
]]>
</mx:Script>
<yahoo:YahooMapService id="myAS2Map" UUID="{UNIQUEID}"
swfDomId="{SWFDOMID}" apiId="{YAHOOAPIKEY}" mapURL = "{MAPSWF}"
horizontalCenter="0" verticalCenter="0" />
</mx:Application>
接着与前面类似我们使用Widgets添加导航控件(NavigatorControl)和卫星地图控件(SatelliteControl):
[xml]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:yahoo="com.yahoo.webapis.maps.*"
layout="absolute" creationComplete="init();" >
<mx:Script>
<![CDATA[
import flash.utils.getTimer;
import mx.controls.Alert;
import com.yahoo.webapis.maps.methodgroups.*;
private const SWFDOMID:String = "YahooAS3Maps_Prac4";
private const UNIQUEID:int = getTimer();
private const YAHOOAPIKEY:String = "Bw7URnLV34GfW9XPiq2zQOoVbmh0h7S5s2W6F3qya9uDVR2HDqpodcYvpcWc";
private const MAPSWF:String = "as2map.swf";
private function init():void {
myAS2Map.addEventListener('onMapLoad', onMapLoaded);
myAS2Map.addEventListener('onMapError', onMapError);
}
private function onMapLoaded(ev:Object):void {
var panTools:PanTool = new PanTool(myAS2Map);
panTools.setPanTool(true);
/***this is the new line***/
var widgets:Widgets = new Widgets(myAS2Map);
widgets.showNavigatorWidget(true);
widgets.showSatelliteControlWidget(true);
}
private function onMapError(errorCode:String, httpStatus:String):void {
Alert.show(errorCode + '\n' + httpStatus, 'Load Error');
}
]]>
</mx:Script>
<yahoo:YahooMapService id="myAS2Map" UUID="{UNIQUEID}"
swfDomId="{SWFDOMID}" apiId="{YAHOOAPIKEY}" mapURL = "{MAPSWF}"
horizontalCenter="0" verticalCenter="0" />
</mx:Application>
以上我们已经在Flex2应用中显示了一个有完整功能的Yahoo!Maps,我们还想监控一下地图操作信息,比如说在地图缩放过程中给用户一个正在缩放的提示,目前的API中,我们可以监听Maps操作过程中的如下事件:
- onMapMove
- onPanStart
- onPanStop
- onToolAdded
- onToolChanged
- onToolRemoved
- onMapZoom
- markerGeocode_Result
- markerGeocode_Error
- mapGeocode_Result
- mapGeocodeError
- swfMarkerAdded
- onZoomStop
- onZoomStart
- dragStart
- dragStop
- getCenter_Result
- getBounds_Result
- onLocalSearchResult
- onLocalSearchError
监听的方法也很简单,只需要用UNIQUEID先初始化一个com.yahoo.webapis.maps.events.MapEventDispatcher(该类初始化时回向HTML中的Object对象添加相应的回调方法以AS2 Maps中有事件发生时告知AS3端),然后再调用MapEventDispatcher.addEventListener添加事件监听就可以了,以下代码监听onZoomStop和onZoomStart事件,在用户缩放地图的时候显示缩放状态:
[xml]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:yahoo="com.yahoo.webapis.maps.*"
layout="absolute" creationComplete="init();" >
<mx:Script>
<![CDATA[
import flash.utils.getTimer;
import mx.controls.Alert;
import com.yahoo.webapis.maps.methodgroups.*;
//new line here
import com.yahoo.webapis.maps.events.MapEventDispatcher;
private const SWFDOMID:String = "YahooAS3Maps_Event";
private const UNIQUEID:int = getTimer();
private const YAHOOAPIKEY:String = "Bw7URnLV34GfW9XPiq2zQOoVbmh0h7S5s2W6F3qya9uDVR2HDqpodcYvpcWc";
private const MAPSWF:String = "as2map.swf";
//new line here
private var MEDispatcher:MapEventDispatcher;
private function init():void {
myAS2Map.addEventListener('onMapLoad', onMapLoaded);
myAS2Map.addEventListener('onMapError', onMapError);
}
private function onMapLoaded(ev:Object):void {
var panTools:PanTool = new PanTool(myAS2Map);
panTools.setPanTool(true);
var widgets:Widgets = new Widgets(myAS2Map);
widgets.showNavigatorWidget(true);
widgets.showSatelliteControlWidget(true);
//new line here
MEDispatcher=new MapEventDispatcher(UNIQUEID);
MEDispatcher.addEventListener("onZoomStart",onZoomStart);
MEDispatcher.addEventListener("onZoomStop",onZoomStop);
}
private function onZoomStart(ev:Object):void{
lb_status.text="zoom start";
}
private function onZoomStop(ev:Object):void{
lb_status.text="zoom stop";
}
private function onMapError(errorCode:String, httpStatus:String):void {
Alert.show(errorCode + '\n' + httpStatus, 'Load Error');
}
]]>
</mx:Script>
<mx:VBox horizontalAlign="center" horizontalCenter="0" verticalCenter="0">
<yahoo:YahooMapService id="myAS2Map" UUID="{UNIQUEID}"
swfDomId="{SWFDOMID}" apiId="{YAHOOAPIKEY}" mapURL="{MAPSWF}"/>
<mx:Label id="lb_status" />
</mx:VBox>
</mx:Application>
怎么样,Yahoo!Maps API很容易使用吧,除了我们上面提到的操作,Yahoo!Maps AS3 API还提供了很多其他的操作,更多信息请查看API文档。
大餐已经上齐,就等您去发挥您的创意,创建您自己的Yahoo!Maps Flex应用了!

O comments at "Yahoo!Maps:开胃点心后大餐上齐!"
Comment Now!