MySQL 5.7 で地理座標間の距離を計算する

MySQL 5.7 で地理座標間の距離を計算する

MySQL 5.7 で追加された ST_Distance_Sphere 関数を使うと、2 つの地理座標間の大圏距離を自前で実装せずに計算できます。

Takahiro Iwasa
6 min read

MySQL 5.7 で追加された ST_Distance_Sphere 関数を使えば、Haversine の公式を自前で実装しなくても、2 つの地理座標間の大圏距離を計算できます。

Important

ST_Distance_Sphere の引数は経度、緯度の順で指定する必要があり、一般的な「緯度、経度」表記とは逆になります。この順序を逆にしてもエラーは発生せず、誤った結果が返されるため注意が必要です。

短距離の例

まずは、大阪市内にある約 2 km 離れた 2 地点間の距離を計算します。

SELECT
ST_Distance_Sphere(
GeomFromText('POINT(135.507260 34.693946)'),
GeomFromText('POINT(135.526201 34.687316)')
) AS distance_meter
FROM
dual;
rowdistance_meter
11882.1360099034516

長距離の例

次に、約 400 km 離れた JR 大阪駅と JR 東京駅を使い、長距離での計算結果を確認します。

SELECT
ST_Distance_Sphere(
GeomFromText('POINT(135.495951 34.702488)'), -- JR Osaka station
GeomFromText('POINT(139.767052 35.681168)') -- JR Tokyo station
) AS distance_meter
FROM
dual;
rowdistance_meter
1403048.2752256764

極域に近い例

最後に、北極圏より北に位置するスヴァールバル諸島の 2 地点を使い、高緯度における球面近似の計算結果を確認します。

SELECT
ST_Distance_Sphere(
GeomFromText('POINT(16.379258 78.655621)'), -- Pyramiden Container Hostel
GeomFromText('POINT(16.328528 78.655143)') -- Hotel Tulpan
) AS distance_meter
FROM
dual;
rowdistance_meter
11110.8932928975748

ST_Distance との違い

名前は似ていますが、ST_DistanceST_Distance_Sphere では空間の扱い方が異なります。MySQL 5.7 の空間計算では、単位が定義されていない無限の平面直交座標系である SRID 0 が前提です。そのため、ST_Distance は 2 つのジオメトリ間の最短距離を、座標と同じ単位の平面距離として返します。

たとえば、経度と緯度を POINT(135.5, 34.7) として格納しても、ST_Distance はそれらを平面上の単純な X 座標と Y 座標として扱います。結果の単位はメートルやキロメートルではなく座標単位です。また、地球の丸みや、極に近づくほど経度 1 度が表す地表上の距離が短くなることも考慮しません。

一方、ST_Distance_Sphere は Point の X と Y を度単位の経度と緯度として解釈し、球面上の最短距離を計算してメートル単位で返します。MySQL 5.7 では、半径を明示しない場合に 6,370,986 メートルの球を使用します。

ST_DistanceST_Distance_Sphere
座標モデル平面直交座標球面
MySQL 5.7 での結果の単位座標単位(SRID 0 の単位は未定義)メートル
地球の丸み考慮しない球面近似として考慮する
対応するジオメトリ適用可能なジオメトリ型の組み合わせPoint/PointPoint/MultiPoint の組み合わせ
主な用途平面座標やジオメトリ形状間の距離経度・緯度から地表上のおおよその距離を求める場合

経度・緯度から地球上のおおよその物理距離を求める場合は、ST_Distance_Sphere を使います。すでに適切な平面座標へ変換されたデータを扱う場合や、ジオメトリ形状間の最短平面距離を求める場合は、ST_Distance を使います。どちらも道路、鉄道、徒歩などの経路距離を求める関数ではありません。

まとめ

3 つの例から、ST_Distance_Sphere を使って約 2 km と約 400 km の距離に加え、単純な平面近似では誤差が生じやすい北緯 78° 付近の距離も計算できることが分かりました。この関数が球面上の計算を処理するため、2 地点間の距離を求めるだけであれば、アプリケーション側で Haversine の公式を実装したり、別の地理空間ライブラリを導入したりする必要はありません。

ただし、GeomFromText('POINT(...)') では経度を緯度より先に指定します。一般的な緯度・経度の順序に慣れている場合は、引数を取り違えないよう注意してください。

About the author

Takahiro Iwasa

Takahiro Iwasa

Software Developer

This blog shares technical notes from hands-on projects—architecture, implementation, and AWS service integrations.