GeoPyで2点間の距離を計算する

投稿者: | 2022-02-17
gray pavement road towards mountains

各局皆様、こんにちは。アマチュア無線局、JS2IIUです。

2021年のバーチャルハムフェスタでFT8でのQSOコンテストが実施されました。(バーチャルハムフェスタ2021)私もコンテストに参加し、下から数えるとトップクラスの成績となりました。コンテスト後、参加者からADIFが提出されました。集約されたログは公開されて、解析コンテストも実施されました。解析コンテストには参加しませんが、良いきっかけなので、解析のための道具を作っておくことにしました。

目次

GeoPyを使えるようにする

% pip install goopy

Collecting geopy
  Downloading geopy-2.2.0-py3-none-any.whl (118 kB)
     |████████████████████████████████| 118 kB 3.7 MB/s            
Collecting geographiclib<2,>=1.49
  Downloading geographiclib-1.52-py3-none-any.whl (38 kB)
Installing collected packages: geographiclib, geopy

GeoPyの簡単な使い方

緯度経度がわかっている2点間の距離は以下のように計算することができる。

from geopy.distance import geodesic

# https://www.google.co.jp/maps/place/東京駅/@35.6812405,139.7649361,17z/data=!3m1!4b1!4m5!3m4!1s0x60188bfbd89f700b:0x277c49ba34ed38!8m2!3d35.6812362!4d139.7671248?hl=ja&authuser=0
# https://www.google.co.jp/maps/place/名古屋駅/@35.1709194,136.8793482,17z/data=!3m1!4b1!4m5!3m4!1s0x600376e794d78b89:0x81f7204bf8261663!8m2!3d35.170915!4d136.8815369?hl=ja&authuser=0

TokyoStation = (35.6812405, 139.7649361)
NagoyaStation = (35.1789194, 136.8793482)

dist = geodesic(TokyoStation, NagoyaStation)
print(dist)

出力は以下の通りとなりました。

267.8843516081899 km

グリッドロケータ間距離の計算

FT8で交信すると基本的にはGLを交換するため、自分のGLと相手のGLがADIFのログに残るので、これを利用して、交信距離を出そうと思います。2ヶ所のGLを入力すると、それらの距離を計算するプログラムを以下に示します。かなり冗長なプログラムですがご容赦ください。

GLtoLat Lon()でグリッドロケータの文字列から緯度経度を計算します。FT8ではPM85のように4文字のGLを交換しますが、PM85kgのような6桁でも対応するようにしています。入力したGLの中心位置での緯度経度およびGLの南西端の緯度経度を計算します。

GLdist()に2つのGL(文字列)を渡すと、それぞれのGL中心位置同士の距離を計算します。この計算でGeoPyを使っています。

from geopy.distance import geodesic

GL_DIGIT_LIST = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']

def GLtoLatLon(grid_locator):

    try:
        D1 = int( GL_DIGIT_LIST.index(grid_locator[0].upper()) )
        D2 = int( GL_DIGIT_LIST.index(grid_locator[1].upper()) )
        D3 = int( grid_locator[2] )
        D4 = int( grid_locator[3] )
        if len(grid_locator) == 6:
            D5 = int( GL_DIGIT_LIST.index(grid_locator[4].upper()) )
            D6 = int( GL_DIGIT_LIST.index(grid_locator[5].upper()) )
        elif len(grid_locator) == 4:
            D5 = 0
            D6 = 0
        else:
            return
    except:
        return

    longitude = -180 + D1 * 20 + D3 * 2 + D5 * 0.05
    latitude = -90 + D2 * 10 + D4 * 1 + D6 * 0.025

    if len(grid_locator) == 6:
        c_longitude = longitude + 0.05 / 2
        c_latitude = latitude + 0.025 / 2
    elif len(grid_locator) == 4:
        c_longitude = longitude + 2 / 2
        c_latitude = latitude + 1 / 2
    else:
        return

    retList = [grid_locator, longitude, latitude, c_longitude, c_latitude]

    return retList


def GLdist(gl1, gl2):

    g1 = ( GLtoLatLon(gl1)[4],GLtoLatLon(gl1)[3]) 
    g2 = ( GLtoLatLon(gl2)[4],GLtoLatLon(gl2)[3])

    dist = geodesic(g1, g2)

    return dist

print( GLdist('PM85kg', 'PM85ke') )

参考

最後まで読んでいただきありがとうございました。

コメントを残す

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