今回はVBAを使って、緯度経度を元に二地点間の距離を算出するサンプルプログラムを紹介していきます。
尚、Access VBAでもExcel VBAでも、どちらも同様に動作します。
サンプルコード解説
緯度と経度を用いた2地点の距離を算出する方法は色々ありますが、今回のサンプルではhaversineと呼ばれる地球を完全な球体と仮定した場合における2地点間の距離を計算します。
自転により実際には楕円に近い形状なので、本来はその形状も考慮しないと、正確な距離は導き出せません。
しかし、そこまでの精度を求めなければ、今回紹介するサンプルコードの方が処理速度も速くおススメです。
VBA サンプルコード
VBEを開き、以下のコードを丸っと貼り付けてください。
Option Compare Database Option Explicit Const Pi = 3.14159265358979 '円周率 Const EarthRadius = 6378.137 '地球半径(GRS80) '緯度、経度の十進数表記からラジアンに変換します。 '引数1:緯度又は経度 '戻り値:ラジアン Function DegToRad(deg As Double) As Double DegToRad = deg * Pi / 180 End Function '引数で渡された二地点の緯度、経度から距離を返します。 '引数1:緯度(地点1) '引数2:経度(地点1) '引数3:緯度(地点2) '引数4:経度(地点2) '戻り値:距離(キロメートル単位) Function Get_GeoDistance(latitude1 As Double, longitude1 As Double, latitude2 As Double, longitude2 As Double) As Double Dim formula1 As Double Dim formula2 As Double Dim formula3 As Double '式が長いので分割します。 formula1 = Math.Cos(DegToRad(latitude1)) * Math.Cos(DegToRad(latitude2)) formula2 = Math.Cos((DegToRad(longitude2)) - (DegToRad(longitude1))) formula3 = Math.Sin(DegToRad(latitude1)) * Math.Sin(DegToRad(latitude2)) Get_GeoDistance = ArcCos(formula1 * formula2 + formula3) * EarthRadius End Function 'Excelのシート内関数にはあるが、VBAにはACOS関数が無いので自作します。 Function ArcCos(X) As Double ArcCos = Atn(-X / Sqr(-X * X + 1)) + 2 * Atn(1) End Function
上記のサンプルコードを呼び出してみましょう。
Sub test() '東京、シドニー間の距離を計測します。 MsgBox Round(Get_GeoDistance(35.41, 139.45, -33.526, 151.1), 2) & "キロメートル" End Sub
緯度経度のデータベース化と距離算出処理の活用方法
まず、地点ごとの緯度と経度を取得する必要があります。
有名どころでは、国交省が詳細な住所情報と位置情報を紐付けたcsvデータを公開しています。
このデータをデータベースに丸っと取り込めば良さそうですが、このデータに対して郵便番号もくっつけるとより使い勝手がよくなります。
郵便番号のマスタデータも日本郵便のサイトで提供されています。
この郵便番号マスタのデータはところどころおかしな部分もあり、国交省の位置情報と郵便番号を紐付けるのは結構大変になる可能性もありますが、郵便番号を元に大まかな位置情報を取得できるようになるので、大まかな距離で良ければ便利です。
いったん住所や郵便番号から経度緯度を取れる環境が作れれば、今回紹介したサンプルプログラムなどを利用して以下の様な業務活用が可能です。
- 顧客の住所と店舗との距離を参考にしてダイレクトメール発送リストを作成
- 社員の交通費や出張規程と照合して申請されてきた住所と申請内容のチェック自動化
- 顧客の住所を元に出店候補地との距離を算出してより顧客が周辺に多い場所を特定
などなど。
他にも色々な活用方法はあるので、是非自社の業務改善に役立ててみてください。
最後に
今回はVBAで緯度と経度情報を元に、2地点間の距離を算出するサンプルプログラムを紹介いたしました。
ある程度学術的な部分も調べたうえで実装したつもりですが、私は数学の専門家ではない為、もし処理内容に誤りなどありましたら、ツイッターか問い合わせフォームなどでこっそり教えて頂けますと助かります。
今回も読んで頂きましてありがとうございました。
それでは皆さまごきげんよう。