GoogleAPI~2つの住所から距離を求める~

前回までは、住所から緯度経度を取得する方法を紹介してきました。
前回の記事はmy-hobby : GoogleAPI~住所から緯度経度を取得する(その2)~に記載されています。

今回は2つの住所から、2点間のおおよその距離を測定する方法にチャレンジしてみたいと思います。
「おおよその距離」とはちょっと歯切れの悪い言い方ですが、
コレには理由があって、今回緯度経度を使って、2点間の距離を求める方法に
3平方の定理を使用するからです。

3平方の定理は、あくまで平面の世界において成立する定理であり、
地球の様に丸い(立体的な)物体に対しては正確な値は得られないので、
「おおよその距離」と表現しました。
ただ、日本の国土くらいの大きさならさほど誤差は出ないだろうという想定で、
今回この方法を使って実際に試してみたいと思います。

考え方は以下の通りです。
1.2地点の住所から緯度経度を求める。

2.2地点の緯度経度から、緯度差、経度差を求める。

経度差:139.7454109-135.5065076=4.2389033
緯度差:35.6586345-34.6524841=1.0061504

3.緯度差、経度差より、距離A、距離Bの距離を求める

距離A:4.2389033×111×cos34.6524841(※2)=387.0557915Km
距離B:1.0061504×111(※1)=111.6826944Km

※1については地球 – Wikipediaの「大きさ、質量、密度」に記載されている、以下の情報から経度、緯度それぞれの1度あたりの距離を算出しました。

赤道半径が6,378.137km、極半径が6,356.752km

計算式:半径×2×円周率÷360
実際の値(赤道半径):6,378.137km×2×3.14159÷360=111.3193968Km
実際の値(極半径):6,356.752km×2×3.14159÷360=110.9461584Km

上記の通り、地球は真円ではありませんが、これを考慮に入れると非常に計算式が難しくなるので、今回は地球を真円とみなし、1度あたりの距離も、111Kmで統一する事にします。

※2については、必ずしも1度あたりの距離が111Kmにはならないので、「cos34.6524841」はそれを補正する為の式となります。
詳細な説明は後日紹介します。

4.3平方の定理を使用し、距離Cを求める。

これらの内容をプログラムに組み込むと以下の様な感じになります。

■入力フォーム

■ソースコード

[vbnet]
Imports System.Xml
Imports System.Web
Imports System.Math

Public Class Form1
Private Sub btn_Search_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Search.Click

Dim xNode As XmlNodeList
Dim Enc_Address As String
Dim APIKey As String = "(各自で取得したAPIキー)"
Dim RequestUrl As String
Dim GeoCode() As String

Dim IdoWK As Double
Dim KeidoWK As Double
Dim KyoriWK As Double
Dim CosIdoWK As Double

If txt_Address.Text = "" Then
Exit Sub
End If

‘住所1の緯度経度を取得
Enc_Address = HttpUtility.UrlEncode(txt_Address.Text)
RequestUrl = "http://maps.google.com/maps/geo?&q=" & Enc_Address & "&output=xml&key=" & APIKey

Dim xDoc As XmlDocument = New XmlDocument
xDoc.Load(RequestUrl)

Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(xDoc.NameTable)
nsmgr.AddNamespace("gmap", "http://earth.google.com/kml/2.0")
xNode = xDoc.SelectNodes("/gmap:kml/gmap:Response/gmap:Status/gmap:code", nsmgr)

If xNode.Item(0).InnerText <> "200" Then
Exit Sub
End If

xNode = xDoc.SelectNodes("/gmap:kml/gmap:Response/gmap:Placemark/gmap:Point/gmap:coordinates", nsmgr)
GeoCode = Split(xNode.Item(0).InnerText, ",")
txt_Keido.Text = GeoCode(0)
txt_Ido.Text = GeoCode(1)

‘住所2の緯度経度取得
Enc_Address = HttpUtility.UrlEncode(txt_Address2.Text)
RequestUrl = "http://maps.google.com/maps/geo?&amp;q=" &amp; Enc_Address &amp; "&amp;output=xml&amp;key=" &amp; APIKey

xDoc.Load(RequestUrl)
xNode = xDoc.SelectNodes("/gmap:kml/gmap:Response/gmap:Status/gmap:code", nsmgr)

If xNode.Item(0).InnerText <> "200" Then
Exit Sub
End If

xNode = xDoc.SelectNodes("/gmap:kml/gmap:Response/gmap:Placemark/gmap:Point/gmap:coordinates", nsmgr)
GeoCode = Split(xNode.Item(0).InnerText, ",")
txt_Keido2.Text = GeoCode(0)
txt_Ido2.Text = GeoCode(1)

‘2地点の緯度経度より、距離を計算
If txt_Ido.Text < txt_Ido2.Text Then
CosIdoWK = txt_Ido.Text
Else
CosIdoWK = txt_Ido2.Text
End If

IdoWK = Abs(txt_Ido.Text – txt_Ido2.Text) * 111
KeidoWK = Abs(txt_Keido.Text – txt_Keido2.Text) * Cos(Math.PI / 180 * CosIdoWK) * 111
KyoriWK = (IdoWK ^ 2 + KeidoWK ^ 2) ^ (1 / 2)

txt_Kyori.Text = KyoriWK

End Sub
End Class
[/vbnet]

■実行結果

結果として、402.846385062963Km≒402.85Kmとなりました。
それでは測量計算(距離と方位角の計算)より実際の距離を測ってみたいと思います。

国土地理院のページなので、信頼性が高いと思い、このページで得られた結果を正解とします。
結果は401.99Kmとなりました。
誤差は0.86Km(0.2%の誤差)。予想以上に正確な値が出ました。

計算方法は「別途文献を見て下さい」との事でした。
「文献」と書いていある時点で難しそうなので、今回はここまでとします。

ちなみに、これを応用すれば、例えば日本全国の日帰り温泉の緯度経度情報を予め調べておき、ある地点から一番近い温泉を調べるといった事も出来るようになります。
GPSを搭載した携帯を持っていれば、郊外に出かけた際、ふと温泉に入りたくなった時に近場の日帰り温泉を探すのに便利ですね。。。

後日の調査で別の計算方式を載せた記事がありますので、よろしければ参考にしてください。
my-hobby : 2地点の緯度経度から距離を求める(Goole MAPS API ~距離の計算式編~)

カテゴリー: flashcast, google, VB.NET, 緯度経度検索 パーマリンク

GoogleAPI~2つの住所から距離を求める~ への4件のフィードバック

  1. ピンバック: my-hobby : 経度から緯度の距離を求める方法

  2. ピンバック: my-hobby : 2地点の緯度経度から距離を求める(global化 1/2)

  3. ピンバック: my-hobby : 2地点の緯度経度から距離を求める(global化 2/2)

  4. ピンバック: my-hobby : 2地点の緯度経度から距離を求める(Google MAPS APIとの比較~概念編~)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です