Flex/第3回Flexを利用したGoogleMapsAPIforFlashによる地図表示 実験編 http://www.ark-web.jp/sandbox/wiki/329.html

[edit]

Flex/第3回Flexを利用したGoogleMapsAPIforFlashによる地図表示 実験編

[edit]

はじめに

『Google Maps API for Flash』を利用した地図表示について、全3回に分けて勉強していった内容を書いていくつもりです。

[edit]

目次

[edit]

JavaScriptと連携する

Flexを利用してFlashのみでGoogleMapsを描画する利点の1つとして、従来のGoogleMapsのようにJavaScriptを利用できないユーザのためにFlashを使う、というのがあるのですが、やむを得ずにJavaScriptとFlash(Flex)を連携したい場合は、ExternalInterface を利用することができます。

[edit]

1.MXMLを記述してコンパイルし、SWFファイルを作る

import flash.external.*;
(...)
  private function makeMarker(latlng:LatLng):Marker {
(...)
    newMarker.addEventListener(MapMouseEvent.CLICK, function(event:Event):void {
      var content:String = ExternalInterface.call("getContent", "ボク flashくん");
      newMarker.openInfoWindow(new InfoWindowOptions({content: content}));
    });
    
    return newMarker;
  }

HTML側は、↓このようにしています。

<script type="text/javascript">
function getContent(fromFlashStr) {
  return '東京タワー☆\n高さ333mの電波塔\nFlashからの伝言:'+ fromFlashStr;
}
</script>
[edit]

2.表示するウェブページを作り、アクセスして動作確認する

[edit]

このサンプルを一式ダウンロードする

[edit]

参考資料

[edit]

円を描画する

つくるぶのAdobe AIRの回で制作した『ohiruda』と同じ方法で円の描画を実装しようとしたんですが、map.fromLatLngToDivPixelや、map.getBoundsなどがGoogleMapsAPIForFlashのAPIにないため、実装できませんでした。。

これを利用していないものを見つけたので、そちらで実装してみました。
http://www.nanchatte.com/map/circle.html をGoogleMapsAPIForFlash向けに直しました。

[edit]

1.MXMLを記述してコンパイルし、SWFファイルを作る

import com.google.maps.overlays.Polyline;
import com.google.maps.overlays.PolylineOptions;
(...)
   private function onMapReady(event:Event):void {
     map.setCenter(new LatLng(35.658586,139.745429), 17, MapType.NORMAL_MAP_TYPE);
     map.addControl(new ZoomControl());
     map.addControl(new PositionControl());
     map.addControl(new MapTypeControl());
     
     // マップを描画
     drawMap(map.getCenter());
     
     // 縮尺を変えた場合、マーカーのみ再描画
     map.addEventListener(MapZoomEvent.ZOOM_END, function(event:Event):void {
       map.removeOverlay(marker);
       marker = makeMarker(new LatLng(35.658586,139.745429));
       map.addOverlay(marker);
     });
   }
   (...)
   // マップを描画する
   private function drawMap(oGLatLng:LatLng):void {
     map.clearOverlays();
     
     // マーカーセット
     marker = makeMarker(new LatLng(35.658586,139.745429));
     map.addOverlay(marker);
     
     map.setCenter(oGLatLng, 16); // サイズ16の東京タワーへ強制遷移
     
     // 円をセット
     var circle:Polyline = pseudoGCircle(oGLatLng, 0.5, 0xff0000, 5, 0.5);
     map.addOverlay(circle);
   }
   
   /**
    * pseudoGCircle (擬似-円描画)
    * @param point   中心地 GLatLng
    * @param radius  半径 km
    * @param color   PolylineOptionsに渡される
    * @param weight  PolylineOptionsに渡される
    * @param opacity PolylineOptionsに渡される
    * @return Polyline
    * 
    * 下記のpseudoGCircle関数は、
    * http://www.nanchatte.com/map/circle.html を
    * 利用させていただきました.
    */
   private function pseudoGCircle(point:LatLng, radius:Number, color:Number, weight:Number, opacity:Number):Polyline {
     var vertex:Number = 36;                // 頂点の数 36あればソレっぽくみえる
     var EquatorialRadius:Number = 6378137; // 赤道半径 (WGS-84)
     var F:Number = 298.257223563;          // 扁平率の逆数 (WGS-84)
 
     // 離心率の2乗
     var E:Number = ((2 * F) -1) / Math.pow(F, 2);
 
     // π × 赤道半径
     var PI_ER:Number = Math.PI * EquatorialRadius;
 
     // 1 - e^2 sin^2 (θ)
     var TMP:Number = 1 - E * Math.pow(Math.sin(point.latRadians()), 2);
 
     // 経度1度あたりの長さ(m)
     var arc_lat:Number = (PI_ER * (1 - E)) / (180 * Math.pow(TMP, 3/2)); 
 
     // 緯度1度あたりの長さ(m)
     var arc_lng:Number = (PI_ER * Math.cos(point.latRadians())) / (180 * Math.pow(TMP, 1/2)); 
 
     // 半径をm単位に
     var R:Number = radius * 1000;
 
     var points:Array = new Array(vertex);
     for (var i:Number = 0; i <= vertex; i++) {
       var rad:Number = (i / (vertex / 2)) * Math.PI;
       var lat:Number = (R / arc_lat) * Math.sin(rad) + point.lat();
       var lng:Number = (R / arc_lng) * Math.cos(rad) + point.lng();
       points[i] = new LatLng(lat, lng);
     }
     return new Polyline(points, new PolylineOptions(
       {
         strokeStyle: {
           thickness: weight,
           color: color,
           alpha: opacity
         }
       })
     );
   }
[edit]

2.表示するウェブページを作り、アクセスして動作確認する

[edit]

このサンプルを一式ダウンロードする

[edit]

参考資料

[edit]

四角の描画が何個まで耐えられるのか

前回、円を描画しましたが、一体Polylineはどれくらいまで描画できるのでしょうか?
理論的には何本でも描画できると思いますが、クライアントのブラウザが重くなってしまってはいけないので、その境はだいたいどれくらいかをアバウトながら探ります。

まずは、四角を縦横に描画するコードを書いてみます。

[edit]

1.MXMLを記述してコンパイルし、SWFファイルを作る

(...)
  // マップを描画する
  private function drawMap(oGLatLng:LatLng):void {
    map.clearOverlays();
    
    // サイズの設定
    var iSize:Number = loaderInfo.parameters['map_size'];
    
    map.setCenter(oGLatLng, iSize);
    
    
    // 複数の四角をオーバーレイとして登録する
    var oBaseSquareInfo:Object = 
    {
       top:    35.658586, left:  139.745429,
       bottom: 35.65733,  right: 139.746694,
       color:0xff0000, weight:3, opacity:0.8
    };
    var iMaxWSize:Number = loaderInfo.parameters['max_wsize'];
    var iMaxHSize:Number = loaderInfo.parameters['max_hsize'];
    
    var iStartTime:Number = getTimer();
    for (var h:Number = 0 ; h < iMaxHSize ; h++) {
      for (var w:Number = 0 ; w < iMaxWSize ; w++) {
        var oSquareInfo:Object = {};
        oSquareInfo['top']     = oBaseSquareInfo['top']    - 0.002 * h;
        oSquareInfo['bottom']  = oBaseSquareInfo['bottom'] - 0.002 * h;
        oSquareInfo['left']    = oBaseSquareInfo['left']   + 0.002 * w;
        oSquareInfo['right']   = oBaseSquareInfo['right']  + 0.002 * w;
        oSquareInfo['color']   = oBaseSquareInfo['color'];
        oSquareInfo['weight']  = oBaseSquareInfo['weight'];
        oSquareInfo['opacity'] = oBaseSquareInfo['opacity'];
        var square:Polyline = makeSquare(oSquareInfo);
        map.addOverlay(square);
      }
    }
    var iEndTime:Number = getTimer();
    
    // ベンチマーク結果をJSに渡す
    ExternalInterface.call("viewResult", "result:"+ (iEndTime - iStartTime) + "msec");
  }
  
  private function makeSquare(oSquareInfo:Object):Polyline {
    var points:Array = new Array();
    points.push(new LatLng(oSquareInfo['top'],    oSquareInfo['left']));
    points.push(new LatLng(oSquareInfo['top'],    oSquareInfo['right']));
    points.push(new LatLng(oSquareInfo['bottom'], oSquareInfo['right']));
    points.push(new LatLng(oSquareInfo['bottom'], oSquareInfo['left']));
    points.push(new LatLng(oSquareInfo['top'],    oSquareInfo['left']));
    
    return new Polyline(points, new PolylineOptions(
      {
        strokeStyle: {
          thickness: oSquareInfo['weight'],
          color: oSquareInfo['color'],
          alpha: oSquareInfo['opacity']
        }
      })
    );
  }
[edit]

2.表示するウェブページを作り、アクセスして動作確認する

[edit]

3.四角をどれくらい描画できるかを探る

四角の描画ができるようになったので、どれくらいで重いと感じるかをアバウトに調査します。
四角の数を動的に変えられるようにしたものを作りましたので、それを使います。

[edit]

4.まとめ

[edit]

このサンプルを一式ダウンロードする

[edit]

参考資料

[edit]

さいごに

GoogleMapsAPIforFlashは、JavaScript版と比べて利用できるAPIが少ないデメリットがありますが
JavaScriptが使えないがFlashプラグインは入っている…という特殊な環境では重宝しそうです。

今回、Flex的な機能を使っていないのでGoogleMapsAPIforFlashの利点は出し切れていないかもしれません。
地図とFlashムービーを連動させてみたり*1、その逆にFlash上に補足として地図を置いてFlash内を歩く
(PV3D等の3Dを想定)と地図も動くとか、Flash側で音データをストリーミングで流して同じサイト内でその
曲を聴いている人をマッピングするなど、アイディア次第で色々楽しめそうです。

投稿者竹村 | パーマリンク | コメント(0)

| append.gif

tag: FlexGoogleGoogleMapsGoogleMapsAPIforFlash


*1 Video Sync Map というデモがありますね

添付ファイル: file09square_benchmark.zip 863件 [詳細] file08make_circle.zip 874件 [詳細] file07to_javascript.zip 884件 [詳細] file09square_benchmark_06.gif 419件 [詳細] file09square_benchmark_05.gif 427件 [詳細] file09square_benchmark_04.gif 393件 [詳細] file09square_benchmark_03.gif 414件 [詳細] file09square_benchmark_02.gif 407件 [詳細] file09square_benchmark_01.gif 527件 [詳細] file09square_benchmark.gif 418件 [詳細] file08make_circle.gif 397件 [詳細] file07to_javascript.gif 400件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2008-06-18 (水) 20:25:33 (4141d)

アークウェブのサービスやソリューションはこちら