アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

GoogleMapの地図上に表示したラインの距離を求める方法

こんにちは。笹亀です。

最近は、冬の寒さと乾燥した場所に弱いもので、
もっぱら体調がよくない日々をおくっています。
特に寒さには弱く、社内で一人だけ上着を着た状態で日々の業務をしていることが多く、軽く浮いております(;´▽`A``

今回は、以前にGoogleMapを使ったときに行ったことを紹介したいと思います。
地図を表示したいときによく使用されるGoogleMapですが、地図を表示するだけではなく、GoogleMapの地図上にライン(線)を引くこともできます。
しかし、その引いたラインの距離を求めるにはGoogleMapの標準メソッドでは距離を取得するメソッドは用意されていません。
そこで、複数の線の緯度経度情報からラインの距離を算出する方法を紹介します。

下記のソースは、実際にGoogleMap上にラインを引く処理とラインの距離を算出することができる状態のサンプルソースになります。ところどころの処理にコメントを記述しておりますので、参考にしていただけたらと思います。
 ※少し長文になりますが、ご了承くださいませ。


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
	<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
	<title>SampleMaps</title>
	<script src="http://maps.google.com/maps?file=api &amp;v=2 &amp;key=ABQIAAAAb3kQrCmW9jK9pfLnTGwrDBRy7x2pvRmU9nyFXjHNvjAIsiOmuhQWNSE0_7Zgs4yiUBfBlWoOYWPbzg" type="text/javascript"></script>
	<script type="text/javascript">
		var deflon = 139.759409;
		var deflat = 35.707014;
		var defzoom = 14;
		var mapDiv;
		var map;
		var marker;
		var DistPoint = new Array();
		var DistOL = null;
		//地図を表示するための初期設定
		function initMap() {
			map = new GMap2(mapDiv);
			map.addControl(new GScaleControl());
			map.addControl(new GLargeMapControl());
			map.addControl(new GMapTypeControl(true));
			map.setCenter(new GLatLng(deflat, deflon), defzoom);

			//地図をクリックしたときのアクション
			GEvent.addListener(map, "click", function(overlay, point) {
				if(overlay == null){
					DistPoint.push(point);
					if(DistPoint.length > 1) {
						line_view();
					}else{
						try {
							map.removeOverlay(marker);
						}catch(error) {
						
						}
						marker = new GMarker(point,{ draggable:true });
						map.addOverlay(marker);
					}
				}
				//マウスのボタンを離したときのアクション
				GEvent.addListener(marker, "mouseup", function() {
					DistPoint.shift();
					DistPoint.unshift(marker.getPoint());
					line_view();
				});
			});

			//地図のドラッグを終了時のアクション
			GEvent.addListener(map, "moveend", function(overlay, point) {
				var zahyo = map.getCenter();
			});
		}
		//ライン(線)を表示する処理
		function line_view(){
			try {
				map.removeOverlay(DistOL);
			}catch(error){}
			//ラインの色と太さと濃さを指定してオブジェクト生成
			DistOL = new GPolyline(DistPoint, "#6600cc", 10, 0.5 );
			map.addOverlay(DistOL);
			
			//ここから線を表示する処理
			var dist = 0;
			var i = 0;
			var str = "";
			while(i < DistPoint.length){
				str = str + DistPoint[i].y + "," +  DistPoint[i].x + "|";
				i++;
			}
			//ここまで
			
			//ここから線の距離を求める処理
			var i = 0;
			while(i < DistPoint.length - 1){
				dist += Gdistance(DistPoint[i], DistPoint[++i]);
			}
			//ここまで

			document.getElementById("distance").innerHTML = "引いた線の距離 約 " + (dist/1000) + "km";
		}

		//初期化呼び出し
		function initPage() {
			mapDiv = document.getElementById("map");
			initMap();
		}
		
		//ひとつ前に戻る処理
		function clearPointBack() {
			var num = DistPoint.length - 1;
			DistPoint.pop();
			line_view();
		}

		//線をクリアする処理
		function clearPoints() {
			DistPoint = new Array();
			map.removeOverlay(DistOL);
			document.getElementById("distance").innerHTML = "引いた線の距離 約 0km";
			DistOL = null;
		}
		
		//2点の線から距離を求める
		function Gdistance(from , to) {
			var from_x = from.x * Math.PI / 180;
			var from_y = from.y * Math.PI / 180;
			var to_x = to.x * Math.PI / 180;
			var to_y = to.y * Math.PI / 180;
			var deg = Math.sin(from_y) * Math.sin(to_y) + Math.cos(from_y) * Math.cos(to_y) * Math.cos(to_x-from_x);
			var dist = 6378140 * (Math.atan( -deg / Math.sqrt(-deg * deg + 1)) + Math.PI / 2);
			return Math.round(dist);
		}
	</script>
</head>

<body onload="initPage()" onunload="GUnload()">
  <div id="map" style="width: 350px; height: 350px"></div>
  <div id="distance" style="font-size: 70%;">引いた線の距離 約 0km</div>
  <form>
    <input type="button" onClick="clearPoints()" value="線をクリア" />
    <input type="button" onClick="clearPointBack()" value="ひとつ前に戻る" />
  </form>
</body>
</html>

実際に作成した地図のサンプルは以下のようになります。
線を引いていくと、距離が加算されていきます。

ここで紹介したラインの距離は必ずしも正確な値とは限りません。
また、傾斜などを考慮した距離にもなっていませんのでご注意ください。

この際、傾斜を考慮した計算を入れてより正確な値を求められたら、より使い道があるものになっていいなと思います。(実際にそういったサイトも見つけましたが・・

GoogleMapはただ単に地図を表示する以外にも自分の画像を地図にしてみたりと、
いろいろな使い方ができます。
これを機会に是非とも、GoogleMapを使ってみてはいかがでしょうか。