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 フィールド内で事前に必要な処理は行ってしまっています。