googleマップに半径と中心座標を使って円を描く

趣味でgooglemapをいじっており、マップに円描写をしたくて色々サイトを見て回ったのですが、
書いてあるサイトを見つけることが出来なかったです。
2点の座標から距離を求めて描写というものはあったものの、1点の座標と距離からもう1点の座標を求めて描写するというの手法が書かれたサイトがどうしても見つけられませんでした。
また、描画出来るものもあったのですが、mapの拡大縮小を行うとバグでおかしくなってしまいました。

なので、自分で作ることに。
幸い、1点の座標と距離からもう1点の座標を求めるための計算式は、海外サイトで見つけることが出来ました。

以下はjavascriptのソース。

/**
 * 半径の円描写用overlayを作成,削除及び、データの保持
 */
polygonCircle={};
(function() {
 var count=32;
 var equatorialr=6378.137;
 
 var polygon;
 var remove=function() {
  if(!polygon) {
   return;
  }
  map.removeOverlay(polygon);
  polygon=undefined;
 }
 var addPolygon=function() {
  map.addOverlay(polygon);
 }
 var createPolygonCircle = function(lat, lng, radius){ 
  var latlngs=[];
  var radiusr = radius/equatorialr;
  for (var i = 0; i < count+1; i++) {
   var tc = (i*2*Math.PI/count);
   var latr = Math.asin(Math.sin(lat)*Math.cos(radiusr)+Math.cos(lat)*Math.sin(radiusr)*Math.cos(tc));
   var dlon = Math.atan2(Math.sin(tc)*Math.sin(radiusr)*Math.cos(lat), Math.cos(radiusr)-Math.sin(lat)*Math.sin(latr));
   var lngr = ( ( lng - dlon + Math.PI ) % ( 2*Math.PI ) ) - Math.PI;
   
   var lati = 180*latr/Math.PI;
   var lngi = 180*lngr/Math.PI;
   var latlng = new GLatLng(lati,lngi);
   latlngs.push(latlng);
  }
  polygon = new GPolygon(latlngs, "#ff0000", 2, 0.5, "#0000ff", 0.1);
 }
 
 polygonCircle.remove=remove;
 polygonCircle.createPolygonCircle=createPolygonCircle;
 polygonCircle.addPolygon=addPolygon;
})();

これでどうにか描くことが出来ました。

さて、これでマップ内に離散しているマーカーの中から、
円の半径内にあるマーカーのみを表示させる、ということをすることが出来ます。

処理としては、
サーバにリクエストで円の中心となる座標、半径のデータを送信し、
それを基に該当するデータを抽出して送り返す、というもの。

以下はSQL文。
ちなみにDBにはマーカーの座標などが入っております。
また、S2Dao使っています。

select*from view_employeelocation as ve
where
/*radius*/ > 2*ASIN ( SQRT ( POW ( ( SIN ( ( /*lat*/ - RADIANS ( ve.latitude ) ) /2 ) ), 2 )+ COS( /*lat*/ )*COS( RADIANS( ve.latitude ) ) * POW ( ( SIN( ( /*lng*/ - RADIANS ( ve.longitude ) ) /2 ) ), 2 ) ) )

今回はDB側で計算しましたが、java側で計算した方が早いかもしれません。

作ってみたアプリのスナップショットは以下。
マーカー、検索部分は適当に作成。

fig.1 中心を新宿、半径30kmで検索後、円内のマーカ描写

fig.2 fig.1の結果のまま、半径を10kmに変更して検索

fig.3 fig.2の結果のまま、mapを拡大


座標から円を割り出しているため、拡大縮小しても問題なし。
商業用としては使えない精度のような気がしますが、趣味レベルでは十分だと思います。
ついでですが、googleで色のついたマーカーがいくつか用意されていました。
デフォルトのマーカーURLは
http://www.google.com/mapfiles/markerA.png
ですが、「marker_xxxA.png」のようにxxxに色を書くとその色のマーカーが使えます。
現時点で確認しているのは、黄色:_yellow, 黒色:_black, 白色:_white, 緑色:_green
です。


しかし、Javascriptは奥が深い。
どうやってこんな事実現しているの??と思ってしまうようなjsがそこら中にごろごろしており、非常に勉強になります。
HTMLのDOMもレベル2になってからややこしくなっており(バブル云々etc)、勉強しなきゃなーと思う今日この頃でした。