[AS3] Google Maps API (Flash)

Standard

前陣子的案子使用到了 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 轉換後存入資料庫)

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

map.loadXML();

這是地圖 MovieClip 的 ActionSript:

// ===================================================================
// 引入 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 = [];
    // 省略關閉處理
}

One thought on “[AS3] Google Maps API (Flash)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *