この記事のURL

http://www.dango-itimi.com/blog/archives/2010/001026.html


FLASH tips Google Maps API for Flash : マップ上に Polyline で円を描くクラス

javascript 版の Google Maps API (Version3)では円を描く処理はサポートされているようですが、Flash バージョンの Google Maps API では円描画はサポートされていない模様(javascript 版 Version2 相当?)なので、ネット上の記事を参考に円を描く処理をクラス化しました。

【 参考サイト 】

http://www.nanchatte.com/map/circle.html

【 ダウンロード 】

ファイル一式ダウンロード
http://www.dango-itimi.com/blog/swf/101/com.zip

上記ファイル内には以下の二つのファイルを配置しています。

・楕円頂点座標群取得用クラス
com.dango_itimi.geom.core.Polygons

・Google Maps 上に円描画用クラス
com.dango_itimi.googlemap.Circle


【 利用方法 】

事前に map インスタンス(com.google.maps.Map)を生成し、利用準備可能状態にしておく必要があります。
東京の緯度(35.689506)と経度(139.691701)に 頂点数 360 半径 300メートルの円を描画したい場合以下となります。

var lat:Number = 35.689506;
var lng:Number = 139.691701;
var circleData:Circle = Circle.create(new LatLng(lat, lng), 360, 300);
Circle.draw(map, circleData);


以下クラスのソースコードをそのまま記述。

■ 楕円頂点座標群取得用 Polygons クラス

package com.dango_itimi.geom.core {
	
	import flash.geom.Point;

	public class Polygons {

		public static function createEllipse(
			drawedFirstX:Number,	
			drawedFirstY:Number,	
			maxRadiusX:Number,
			maxRadiusY:Number,
			vertexTotal:uint
		):Vector.<flash.geom.Point>{
			
			var vertexMax:uint = vertexTotal + 1;
			var vertices:Vector.<flash.geom.Point> = new Vector.<flash.geom.Point>(vertexMax, true);
			
			for (var i:int = 0; i < vertexMax; i++) {
				
				var rad:Number = (i / (vertexTotal / 2)) * Math.PI;
				var x:Number = maxRadiusX * Math.sin(rad) + drawedFirstX;
				var y:Number = maxRadiusY * Math.cos(rad) + drawedFirstY;
				vertices[i] = new flash.geom.Point(x, y);
			}
			return vertices;
		}
	}
}

自作 Pointクラスを Polygons クラスと同パッケージ内に配置しているため、Vector 内型宣言の Point クラスは上記のようにフルパス記述にしています。これはなんとかしたいところですが保留中。


■ Google Maps 上に円描画用クラス

package com.dango_itimi.googlemap {
	
	import com.google.maps.overlays.Polyline;
	import com.google.maps.Map;
	import com.google.maps.LatLng;
	import com.dango_itimi.geom.core.Polygons;
	import flash.geom.Point;

	public class Circle {
		
		//赤道半径 (WGS-84) 
		private static var EQUATORIAL_RADIUS:Number = 6378137; 
		
		//扁平率の逆数 (WGS-84)
		private static var F:Number = 298.257223563;
		
		//離心率の2乗
		private static var E:Number;
		
		//π × 赤道半径	
		private static var PI_ER:Number;
		
		private static var TMP_LAT:Number;
		private static var TMP_LNG:Number;

		{
			E = ((2 * F) -1) / Math.pow(F, 2);	
			PI_ER = Math.PI * EQUATORIAL_RADIUS;
			TMP_LAT = PI_ER * (1 - E) / 180;
			TMP_LNG = PI_ER / 180;
		}

		public static function create(center:LatLng, vertexTotal:uint, meterRadius:Number):Circle {
			
			var TMP:Number = 1 - E * Math.pow(Math.sin(center.latRadians()), 2);
			var arc_lat:Number = TMP_LAT / Math.pow(TMP, 3/2);
			var arc_lng:Number = TMP_LNG * Math.cos(center.latRadians()) / Math.pow(TMP, 1/2);
			
			var vertices:Vector.<Point> = Polygons.createEllipse(
				center.lat(),
				center.lng(), 
				meterRadius / arc_lat,
				meterRadius / arc_lng,
				vertexTotal
			);
			return new Circle(vertices);
		}
		private var vertices:Vector.<Point>;
		private var latLngs:Array;
		
		public function Circle(vertices:Vector.<Point>) {
			
			this.vertices = vertices;
			latLngs = convertLatLng(vertices);
		}
		private static function convertLatLng(vertices:Vector.<Point>):Array {
			
			var latLngs:Array = new Array(vertices.length);
			for (var i:Number = 0; i < latLngs.length; i++) {
				
				var point:Point = vertices[i];
				latLngs[i] = new LatLng(point.x, point.y);
			}
			return latLngs;
		}
		public static function draw(map:Map, circleData:Circle):void {
			
			var line:Polyline = new Polyline(circleData.latLngs);
			map.addOverlay(line);
		}
	}
}

static フィールド内で事前に必要な処理は行ってしまっています。

[ FLASH ] [ tips ] 投稿者 siratama : 2010年08月13日 16:47

トラックバック

http://www.dango-itimi.com/blog/mt-tb.cgi/986

コメント

以下コメントを書き込むだけでは、管理人には通知が行われません。通知を行いたい場合、管理人の書き込みに「返信」を押してコメントをしていただくか、あるいは Google+, Twitter へご連絡ください。




[EDIT]