前陣子的案子使用到了 Google Maps API(Flash 版),來整理一下,我想之後還有機會用到的。

簡單來講需求是這樣:
點擊場景上的某物件,會叫出 Google 地圖小視窗,呈現該物件的移動路線。
而 XML 配置如下:

<markers>
<marker person="人名1" descrip="描述1" address="台北縣" lat="23.23512" lng="121.12343"/>
<marker person="人名2" descrip="描述2" address="桃園縣" lat="24.12544" lng="120.23453"/>
</markers>

物件會被傳遞給不同的人,每個點都有自己的經緯度。
(經緯度是經由後端程式將地址透過 Google Maps API 轉換後存入資料庫)

在場景上的物件被點擊後,會秀出地圖 MC 並執行地圖 MC 的 loadXML() 事件。
(應該還會傳遞點擊物件的id,以載入不同的XML內容,但此處省略)

map.loadXML();

這是地圖 MC 的 AS:

// ===================================================================
// 引入 Google Maps API
// ===================================================================
import com.google.maps.overlays.MarkerOptions;
import com.google.maps.LatLngBounds;
import com.google.maps.MapEvent;
import com.google.maps.MapMouseEvent;
import com.google.maps.Map;
import com.google.maps.InfoWindowOptions;
import com.google.maps.overlays.Marker;
import com.google.maps.overlays.Polyline;
import com.google.maps.overlays.PolylineOptions;
import com.google.maps.MapType;
import com.google.maps.LatLng;
import com.google.maps.styles.StrokeStyle;
import com.google.maps.controls.ZoomControl;
import com.google.maps.services.ClientGeocoderOptions;
import com.google.maps.services.ClientGeocoder;
import com.google.maps.services.GeocodingEvent;

// ===================================================================
// 宣告
// ===================================================================
// XML檔案位置
var xmlFile:String = "test.xml";
// 存放資料陣列
var locations:Array=new Array();
// 地圖物件
var map:Map;

// ===================================================================
// 讀取 XML 事件
// ===================================================================
function loadXML():void{
    var loader:URLLoader=new URLLoader();
    // 完成載入後執行 completeXMLHandler 事件
    loader.addEventListener(Event.COMPLETE,completeXMLHandler);

    var XMLRequest:URLRequest=new URLRequest(xmlFile);
    try
    {
       loader.load(XMLRequest);
    }
    catch(error:Error)
    {
       trace('無法載入 XML 檔案');
    }
}

// ===================================================================
// 完成載入 XML 事件
// ===================================================================
function completeXMLHandler(event:Event):void{

        var markersXML:XML = new XML(event.target.data);
        var markers:XMLList = markersXML.marker;
        var markersCount:int = markers.length();
        var i:Number;

        // 依照節點數量跑迴圈
        for (i=0; i < markersCount; i++) {
			var obj:Object=new Object();
            var markerXml:XML = markers[i];
            // 人名
            obj.person = markerXml.@person;
            // 描述
			obj.descrip = markerXml.@descrip;
			// 地址
            obj.address = markerXml.@address;
            // 經緯度
            obj.latlng = new LatLng(markerXml.@lat, markerXml.@lng);

            // 將資料塞入 locations 陣列中
			locations.push(obj);
        }
	trace("XML LOAD COMPLETE!");

	// 若已經存在 map 物件
	if( this.getChildByName("map") != null ){
		trace("map is exist!");
		// 清除地圖上的東西
		map.clearOverlays();
		// 呼叫 onMapReady 事件
		onMapReady();
	} else {
		// 建立地圖物件
		map = new Map();
		// 賦予 name
		map.name = "map";
		// Google Maps API Key
		map.key = "ASDASASDFASxzcasdqwddvsdfwsrfWERWFAa";
		map.setSize(new Point(450, 350));
		this.addChild(map);
		map.x = -215;
		map.y = -135;

		// 加入偵聽:地圖準備完畢
		map.addEventListener(MapEvent.MAP_READY, onMapReady);
		// 加入偵聽:地圖滾輪事件
		map.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
	}
}

// ===================================================================
// 地圖準備完畢的事件
// ===================================================================
function onMapReady(event:Event=null):void {
	trace("map ready!");

		trace("make Marker");

		// 宣告 LatLngBounds 類型的 bounds 變數
		var bounds:LatLngBounds = new LatLngBounds();
		// 宣告上一個點的物件
		var lastLocation:Object = null;

		// 跑地點列表
		for (var i:int = 0; i < locations.length; i++) {

			// 目前地點
			var currentLocation:Object = locations[i];
			// 呼叫 createMaker 事件,建立地圖上的標記
			createMarker(currentLocation, (i+1));

			// 如果上一個點變數不為空,就畫路徑線
			if (lastLocation != null) {
				createPolyline(lastLocation, currentLocation);
			}

			// 把上一個點指定為目前的點
			lastLocation = currentLocation;
			// 邊界
			bounds.extend(locations[i].latlng);
		}
		// 把中心點設為上面幾個點的中心點,並調整為最適大小
		map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

}

// ===================================================================
// 建立 Marker 事件
// ===================================================================
function createMarker(currentLocation:Object, number:int):void {
	var opts:MarkerOptions = new MarkerOptions();
	// marker 上帶數字
	opts.label = String(number);
	var marker:Marker = new Marker(currentLocation.latlng, opts);

	// 在 marker 上加入點擊偵聽,秀出相關資訊(從 locations 陣列中取出的人名、描述)
	marker.addEventListener(MapMouseEvent.CLICK, function(e:Event):void {;
		marker.openInfoWindow(new InfoWindowOptions({contentHTML: "<b>" + currentLocation.person + "</b><br/>" + currentLocation.descrip}));
	});

	// 加入到地圖上
	map.addOverlay(marker);
}

// ===================================================================
// 畫路徑事件
// ===================================================================
function createPolyline(startLocation:Object, endLocation:Object):void {
	var opts:PolylineOptions = new PolylineOptions();
	// 設定線的樣式
	opts.strokeStyle = new StrokeStyle({color: 0xFF0000,thickness: 4,alpha: 0.7});
	opts.geodesic = true;
	var latlngs:Array = [startLocation.latlng, endLocation.latlng];
	var polyline:Polyline = new Polyline(latlngs, opts);
	// 加入到地圖上
	map.addOverlay(polyline);
}

// ===================================================================
// 滑鼠滾輪事件
// ===================================================================
var zoomRate:Number = 1;
function onMouseWheel(e:MouseEvent):void {
	var zoom:Number = map.getZoom();
	if (e.delta>0) {
		map.setZoom(zoom+zoomRate);
	} else {
		map.setZoom(zoom-zoomRate);
	}
}

// ===================================================================
// 關閉地圖 MC 事件
// ===================================================================
function _close(e:Event = null){
	// 這邊要把 locations 陣列清掉,不然下次加入會累加
	locations = [];
	// 省略關閉處理
}