Flash版googleMapをFlexで簡単に使えるようにしてみたの続き

こないだの続きで、
FlexでgoogleMapを簡単に使えるように改良してみた。

とりあえず
・マーカーの配置
・拡大縮小

Flexから簡単にできるように。
Flex側で書くコードは、

<?xml version="1.0" encoding="utf-8"?>
<mx:Application 
    xmlns:mx="http://www.adobe.com/2006/mxml" 
    xmlns:aslex="control.*"
    layout="absolute" 
    width="100%" height="100%" backgroundColor="#FFFFFF" viewSourceURL="srcview/index.html">
	<mx:ArrayCollection id="marker">
		<aslex:MapMarker lat="35.680921" lng="139.709258" content="今日" mapevent_click="{trace('clickされた')}"/>
		<aslex:MapMarker lat="35.580821" lng="139.709258" content="テスト" mapevent_click="{trace('clickされた')}"/>
		<aslex:MapMarker lat="35.780621" lng="132.709258" content="テスト" showInfo="false"/>
		<aslex:MapMarker lat="35.880421" lng="139.709258" content="テスト" mapevent_click="{trace('clickされた')}"/>
	</mx:ArrayCollection>
	
	
	<mx:VBox>        
			<aslex:GoogleMapComponent id="map" width="400" height="400" zoom="10"
				apiKey="ABQIAAAAtwFK8HNrohzEhID1DyTMpxSe3jFFaq_CEt0xAqiwgvHbpGZhdBRoYeTeKyvOl2GbHLt-upZoMUfglA"
				markers="{marker}"/>
			<mx:HBox>				
				<mx:Button click="map.zoomIn();" label="拡大"/>
				<mx:Button click="map.zoomOut()" label="縮小"/>
			</mx:HBox>
    </mx:VBox>
 
</mx:Application>

googleのサンプルコードよりはやっぱシンプル!!
これで以下のような画面が完成。

コンポーネントの標準では、『東京駅』がmxmlから指定した新宿駅の場所になってます。

上記サンプルは
http://aslex.org/map/GoogleMapTest.html

においてあるのでよかったら見てください。

mxml以外のソースコード
http://aslex.org/map/srcview/index.html
です。

上記ソースを持ってきて入れれば
使う側はmxmlだけで簡単にgooglemapが使えます。


ちなみに今後は、
・markerにいろいろな設定をする(titleとかhtmlとか)
・marker間に線を引けるようにする

とかしてみたいですね。
もちろん使う側はmxmlのみで。

Flash版googleMapをFlexで簡単に使えるようにしてみた

cnetで『グーグル、「Google Maps」をFlashから利用するAPIを公開
を見て、早速使ってみたのだが、やっぱりActionScript
がんばって書くよりもFlexで使えた方が楽なので
とりあえずFlexで使えるようにしてみた。

その結果地図を表示するアプリは以下のように実装できるようになった。

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:aslex="control.*" layout="absolute">
	<aslex:GoogleMapComponent id="map" width="100%" height="100%" lat="35.690921" lng="139.700258" zoom="13"/> 
</mx:Application>

すばらしく、シンプル!!
これで以下のような画面が完成。

コンポーネントの標準では、『東京駅』がmxmlから指定した新宿駅の場所になってます。


上記のソースを動かす場合には、
GoogleMapComponent.asをcontrol/以下に配置する必要があります。

ソースの位置関係は、

|--libs
|   |_ map_flex_1_1.swc (googleからDLしてくる
|
|--src
    |--control
    |     |_ GoogleMapComponent.as
    |
    |_ GoogleMapTest.mxml (上に書いてあったソース)

ちなみに以下が
GoogleMapComponent.asのソース

package control
{
	import com.google.maps.LatLng;
	import com.google.maps.Map;
	import com.google.maps.MapEvent;
	import com.google.maps.MapType;
	
	import flash.geom.Point;
	
	import mx.core.UIComponent;
	import mx.events.ResizeEvent;
	
	public class GoogleMapComponent extends UIComponent
	{
		private var _map:Map;
		public function GoogleMapComponent() 
		{
			super();
			_map = new Map();
			_map.addEventListener(MapEvent.MAP_READY,onMapReadyHandler);
			addEventListener(ResizeEvent.RESIZE,resizeHandler)
			addChild(_map);
		
		}
		
		
		private function resizeHandler(e:ResizeEvent):void{
			_map.setSize(new Point(this.width,this.height));
		}		
		
		private function onMapReadyHandler(e:MapEvent):void{
			setMapPoint();
		}
		
		private function setMapPoint():void{
			_map.setCenter(new LatLng(_lat,_lng), _zoom, MapType.NORMAL_MAP_TYPE);
		}
		
		private var _zoom:Number = 14;
		public function set zoom(value:Number):void{
			_zoom = value;
			if(_map.isLoaded())_map.setZoom(value);
		}
		
		public function get zoom():Number{
			return _map.getZoom();	
		}

		/**
		 * 経度を設定する
		 */		
		public function set lng(value:Number):void{
			_lng = value;
			if(_map.isLoaded())setMapPoint();
		}
		
		public function get lng():Number{
			return _map.getCenter().lng();
		}
		
		private var _lng:Number = 139.767084;
		
		/**
		 * 緯度を設定する
		 */
		public function set lat(value:Number):void{
			_lat = value;
			if(_map.isLoaded())setMapPoint();
		}
		
		public function get lat():Number{
			return _map.getCenter().lat();	
		}
		
		private var _lat:Number = 35.681099;
		

	}
}


明日、markerとかをmxml側から簡単に配置できるように
してみようかな。

にしても、APIKeyをflashversに書かなきゃいけない
仕様どうにかならないかな…as内に書きたい

5分で作るaction script3 サンプル 4のその2(ボタンの作成)

第4回 ボタンの作成(応用編)

前回作ったActionScript版のボタンは
Flex2版のボタンと違って
ラベルの設定ができない寂しいものでした。
なので今回はActionScriptでも
ラベルのつけれるボタンのサンプルです。


package {
	import flash.display.Sprite;
	import flash.display.SimpleButton;
	import flash.text.TextField;
	import flash.display.StageScaleMode;
	import flash.display.StageAlign;
	import flash.text.TextFieldAutoSize;

	public class ASButton extends Sprite
	{
		
		[Embed(source='up.png')]
		private var upImg:Class;
		
		[Embed(source='down.png')]
		private var downImg:Class;
		
		[Embed(source='over.png')]
		private var overImg:Class;
		
		
		private const paddingLeft:int = 3;
		private const paddingRight:int =3;
		private const paddingTop:int =3;
		private const paddingBottom:int =3;
		
		
		public function ASButton()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;

			var btn:SimpleButton = createBtn("文章を読む",upImg,downImg,overImg);
			
			addChild(btn);
			
		}
		
		private function createBtn(label:String,upSkin:Class,downSkin:Class,overSkin:Class):SimpleButton{
			var btn:SimpleButton = new SimpleButton;
			
			
			var up:Sprite = withLabelSkin(label,upSkin);
			var down:Sprite = withLabelSkin(label,downSkin);
			var over:Sprite = withLabelSkin(label,overSkin);
			
			btn.upState = up;
			btn.downState = down;
			btn.overState = over;
			btn.hitTestState = up;
			
			return btn;
			
			
		}
		
		
		private function withLabelSkin(labelStr:String,imageClass:Class):Sprite{
			var canvas:Sprite = new Sprite();
			var label:TextField = new TextField();
			var image:* = new imageClass();
			label.text =labelStr;
			label.autoSize = TextFieldAutoSize.LEFT;
			
			label.x = paddingLeft;//真ん中にしたいならこっち(label.width -label.textWidth)/2;
			label.y = paddingTop;//真ん中にしたいならこっち(label.height-label.textHeight)/2; 
			image.width = label.width + paddingLeft + paddingRight;
			image.height = label.height + paddingTop + paddingBottom;
			
			canvas.addChild(image);
			canvas.addChild(label);
			
			return canvas;			
		}
	}
}

解説

		private const paddingLeft:int = 3;
		private const paddingRight:int =3;
		private const paddingTop:int =3;
		private const paddingBottom:int =3;

ボタンですので各種部分に
paddingを用意してみました。

		private function createBtn(label:String,upSkin:Class,downSkin:Class,overSkin:Class):SimpleButton{

こいつは前回のボタン作成のときに使ったソースを
ラップして呼びやすくしただけで
前回と中身は一緒です。

		private function withLabelSkin(labelStr:String,imageClass:Class):Sprite{
			var canvas:Sprite = new Sprite();
			var label:TextField = new TextField();
			var image:* = new imageClass();
			label.text =labelStr;
			label.autoSize = TextFieldAutoSize.LEFT;
			
			label.x = paddingLeft;//真ん中にしたいならこっち(label.width -label.textWidth)/2;
			label.y = paddingTop;//真ん中にしたいならこっち(label.height-label.textHeight)/2; 
			image.width = label.width + paddingLeft + paddingRight;
			image.height = label.height + paddingTop + paddingBottom;
			
			canvas.addChild(image);
			canvas.addChild(label);
			
			return canvas;			
		}
			
		

ここで各状態に応じたボタンを作成します。
『label.autoSize = TextFieldAutoSize.LEFT;』を使うことに
よってTextFieldが中のデータに応じたサイズにリサイズしてくれます。
ちなみにTextFieldにこれを設定しない場合は、
高さ50px 幅も実際のテキストの幅より大きいサイズと
いうかなり適当なサイズになっているので特に問題なければ必ず設定しましょう。

あとimageは背景ですが、今回は、ラベルがあるので
背景のサイズをlabelのサイズに準じたサイズにしてあげます。

以上で終わりです。

5分で作るFlex2(mxml) サンプル 4(ボタンの作成)

第4回 ボタンの作成

ActionScriptで書く時に比べたら
相変わらず拍子抜けするほど簡単です。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:Button/>
</mx:Application>

解説

mxml言語での開発では、基本的には

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	
この間に何かを書く

</mx:Application>

必要があります。

	<mx:Button/>

mxコンポーネントのButtonクラスを使用することで
ボタンが表示されます。
文字などの表示については次回。

にしてもAsとFlexを比較すると
Flexのほうが拍子抜けするほど簡単で嫌になってきますね…

5分で作るaction script3 サンプル 4(ボタンの作成)

第4回 ボタンの作成

ActionScript3で以下のように記述すると
画面上にボタンが表示されるようになります。
ただボタンといってもmousedown、
mouseup、mouseoverに応じて状態を
変えてくれるオブジェクトで
テキストも何も表示してくれないケチなやつです。


package {
	import flash.display.Sprite;
	import flash.display.SimpleButton;

	public class ASButton extends Sprite
	{
		
		[Embed(source='up.png')]
		private var upImg:Class;
		
		[Embed(source='down.png')]
		private var downImg:Class;
		
		[Embed(source='over.png')]
		private var overImg:Class;
		
		
		public function ASButton()
		{
			var btn:SimpleButton = new SimpleButton;
			
			
			var up:Sprite = new Sprite();
			up.addChild(new upImg());
			
			var down:Sprite = new Sprite();
			down.addChild(new downImg());
			
			var over:Sprite = new Sprite();
			over.addChild(new overImg());
			
			btn.upState = up;
			btn.downState = down;
			btn.overState = over;
			btn.hitTestState = up;
			
			addChild(btn);
			
		}
	}
}

解説

		[Embed(source='up.png')]
		private var upImg:Class;
		
		[Embed(source='down.png')]
		private var downImg:Class;
		
		[Embed(source='over.png')]
		private var overImg:Class;

とりあえず各種状態に応じた画像を
三枚用意してあげます。それぞれ
mouseUp、mouseDown、mouseOver状態の画像です。

	var btn:SimpleButton = new SimpleButton;


これがボタンの元となるSimpleButtonクラスです。
あまりにもSimple過ぎて使いづらいんですけどね…

			var up:Sprite = new Sprite();
			up.addChild(new upImg());
			
			var down:Sprite = new Sprite();
			down.addChild(new downImg());
			
			var over:Sprite = new Sprite();
			over.addChild(new overImg());
			
			btn.upState = up;
			btn.downState = down;
			btn.overState = over;
			
		

一度Spriteの中に画像を入れてますが
これはちょっと先で活用するのでこうしています。

で『btn.upState』はmouseUp状態に指定するDisplayオブジェクトを渡しています。
これによりmouseUp(つまりmouseOut)の状態のときはこれが表示されるようになります。

他の『downState』『overState』も同様です。

	btn.hitTestState = up;

これでSimpleButtonクラスの不思議なところ。
実はこのSimpleButtonクラスは、マウスのあたり判定を
自分とはまったく無関係のオブジェクトを指定することができたりもします。

まっ今回はいわゆるボタンとして使いたいので
upオブジェクトにmouseが当たるかどうかで
判断しろということにするので以上のように書きました。

5分で作るFlex2(mxml) サンプル 3(画像ファイルの読み込み)

第3回 画像ファイルの読み込み

以下のように書くとデータが読みこめます。
イベントハンドリングを行わない場合は
簡潔にかけますが、エラー処理したい場合は
しっかり書きましょう。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:Image source="http://yino.sakura.ne.jp/hatena/blue.png"/>
</mx:Application>

解説

mxml言語での開発では、基本的には

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	
この間に何かを書く

</mx:Application>

必要があります。

<mx:Image source="http://yino.sakura.ne.jp/hatena/blue.png"/>	

mxコンポーネントのimageクラスを使用することで
画像を読み込むことができます。
第二回(画像の埋め込み)で説明したときと違い、Embedは使用しません。

ただしここでもFlashセキュリティポリシーの問題を考慮しなくてはなりません。

5分で作るaction script3 サンプル 3(画像ファイルの読み込み)

第3回 画像ファイルの読み込み

第3回は第二回(画像の埋め込み)
と違い、画像の読み込みです。

以下のように記述すると
外部URL上にあるデータを取得してきて
画面に表示することができます。

各種イベントハンドラは別に書かなくても
動きますが、エラー処理や進行状況の
確認をしたい場合には書きましょう。

package {
	import flash.display.Sprite;
	import flash.display.Loader;
	import flash.net.URLRequest;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.HTTPStatusEvent;
	import flash.events.ProgressEvent;

	public class ImageLoader extends Sprite
	{
		public function ImageLoader()
		{
			var loader:Loader = new Loader();
			var url:URLRequest = new URLRequest("http://yino.sakura.ne.jp/hatena/blue.png");
            		loader.addEventListener(Event.COMPLETE, completeHandler);
            		loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
            		loader.addEventListener(Event.INIT, initHandler);
            		loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
            		loader.addEventListener(Event.OPEN, openHandler);
            		loader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
            		loader.addEventListener(Event.UNLOAD, unLoadHandler);
            		loader.load(url);
            
            		addChild(loader);
        }

        private function completeHandler(event:Event):void {
            trace("読み込み完了: " + event);
        }

        private function httpStatusHandler(event:HTTPStatusEvent):void {
            trace("http状態の変更: " + event);
        }

        private function initHandler(event:Event):void {
            trace("初期化 " + event);
        }

        private function ioErrorHandler(event:IOErrorEvent):void {
            trace("ioエラー: " + event);
        }

        private function openHandler(event:Event):void {
            trace("オープン: " + event);
        }

        private function progressHandler(event:ProgressEvent):void {
            trace("ロード中: bytesLoaded=" + event.bytesLoaded + " bytesTotal=" + event.bytesTotal);
        }

        private function unLoadHandler(event:Event):void {
            trace("アンロード: " + event);
        }
		
	}
}

解説

	var loader:Loader = new Loader();
	var url:URLRequest = new URLRequest("http://yino.sakura.ne.jp/hatena/blue.png");

今回の肝はココ。
loaderクラスがデータを読み込んでくれます。loaderクラスは、
SWF ファイルまたはイメージファイルを読み込むときに利用します。

また外部URLを利用する場合には、Flashのセキュリティモデルの問題が
発生します。長く説明すると時間がかかるので端的に説明しますと
外部ドメインの元にcrossdomain.xmlがおいてありなおかつそのxml
当該URLからのアクセスを許可してる場合に、そのファイルにアクセスできます。


たとえば、http://yino.sakura.ne.jp/hatena/blue.pngのファイルにアクセスするためには
http://yino.sakura.ne.jp/crossdomain.xmlというファイルがある必要があります。

また、その中に

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
   <allow-access-from domain="*" />
</cross-domain-policy>

のようなアクセス元ドメインからのアクセスの許可が
ある必要があります。この場合は、『*』すべてのドメインからのアクセスが
許可されているので問題ありません。

        private function completeHandler(event:Event):void {
            trace("読み込み完了: " + event);
        }

        private function httpStatusHandler(event:HTTPStatusEvent):void {
            trace("http状態の変更: " + event);
        }

        private function initHandler(event:Event):void {
            trace("初期化 " + event);
        }

        private function ioErrorHandler(event:IOErrorEvent):void {
            trace("ioエラー: " + event);
        }

        private function openHandler(event:Event):void {
            trace("オープン: " + event);
        }

        private function progressHandler(event:ProgressEvent):void {
            trace("ロード中: bytesLoaded=" + event.bytesLoaded + " bytesTotal=" + event.bytesTotal);
        }

        private function unLoadHandler(event:Event):void {
            trace("アンロード: " + event);
        }
		

これらのイベントハンドラで進行状態などが監視できます。
ここでprogressバーなどを出すこともできるでしょう。

addChild(hello);

いつもどおりloaderを表示するために
Spriteにaddしてあげましょう。