🐥

PostGIS における座標系と距離計算について: geometry 型と geography 型の違い

2025/03/08に公開

はじめに

PostGIS で位置情報データを扱う際には座標系と測地計算の違いに注意が必要です。

私は最近、IoT デバイスから発信される位置情報データを収集・分析する業務に携わりました。その中で、PostGIS を使って位置情報を扱う際に座標系と測地計算の違いについて新たに学びがあったため記事にまとめました。PostGIS で位置情報を扱う方々の参考になれば幸いです。

座標系とは

座標系(coordinate system)は、空間内の位置を表現するための基準となる枠組みのことです。座標系が定義されることで、点の位置を数値(座標)として表現し、計算や可視化が可能になります。座標系は地理座標系と投影座標系の 2 種類があります。

  • 地理座標系:地球の球面をそのまま扱う座標系。角度で表現される。
  • 投影座標系:地球の球面を平面に投影した座標系。メートルやフィートなどの距離で表現される。距離や面積の計算に適している。

1. geometry 型と geography 型の違い

PostGIS では位置情報を扱うための空間データ型として主に 2 つの型(geometry, geography)が用意されています。名前が似ているので混同しやすいですが、それぞれの違いを以下にまとめました。geometry 型と geography 型では計算方法/計算結果/距離の単位が異なります。

geometry

  • 座標系(SRID)を自由に設定可能WGS 84UTMEPSG:3857 など
  • 距離の単位は SRID に依存WGS 84 では「度」、投影座標系なら「メートル」
  • 平面座標での計算:地球の曲率を考慮しない単純な平面として計算
  • 計算が高速:単純な数学計算のため処理効率が良い

geography

  • 座標系は WGS 84(SRID:4326)に固定
  • 距離の単位は常にメートル
  • 測地計算:地球の球面/楕円体形状を考慮した計算
  • 地球の曲率を考慮するため、精度が高いが処理負荷も高い

2. 距離計算の方法

PostGIS では2 つのジオメトリ間の距離を計算する関数として、ST_DistanceST_DistanceSphereST_DistanceSpheroid が用意されています。

  • ST_Distance は、geometry 型と geography 型の両方で使用できます。
  • ST_DistanceSphere は、geometry 型のデータに対して使用できます。
  • ST_DistanceSpheroid は、geometry 型のデータに対して使用できます。

ST_Distance の構文

ST_Distance 関数の基本的な構文を下記に示します。

float ST_Distance(geometry g1, geometry g2);
float ST_Distance(geography geog1, geography geog2, boolean use_spheroid = true);

詳細は、公式ドキュメントを参照してください。
https://postgis.net/docs/ja/ST_Distance.html

ST_Distanceを使った距離計算(geometry型)(単位: 度 or メートル)

ここからは、実際のクエリ例を見ながら違いを確認してみましょう。
下記のクエリは、東京駅と大阪駅の距離を計算しています。

postgres=# SELECT ST_Distance(
    ST_SetSRID(ST_MakePoint(139.76701944398158, 35.68121661474183), 4326),  -- 例: 東京駅
    ST_SetSRID(ST_MakePoint(135.4957763072182, 34.70248840069602), 4326)   -- 例: 大阪駅
);
    st_distance
-------------------
 4.381943273288422 -- 計算結果の単位は「度」
(1 row)

ST_Distanceを使った距離計算(geography型)(単位: メートル)

postgres=# SELECT ST_Distance(
    ST_GeographyFromText('SRID=4326;POINT(139.76701944398158 35.68121661474183)'),  -- 例: 東京駅
    ST_GeographyFromText('SRID=4326;POINT(135.4957763072182 34.70248840069602)')  -- 例: 大阪駅
);
   st_distance
-----------------
 403832.10662839 -- 計算結果の単位は「メートル」  約403.8km
(1 row)

geography型では測地線距離(地球の曲面上の距離)を計算し、結果が直接メートル単位で返されます。これにより、場所を問わず一貫した距離計算が可能です。

ST_DistanceSphereST_DistanceSpheroid の活用

ただし、geometry型のままでも、ST_DistanceSphereST_DistanceSpheroid を使うと地球の形状を考慮した計算ができます。
以下に、ST_DistanceSphereST_DistanceSpheroid の構文を示します。

float ST_DistanceSphere(geometry geomlonlatA, geometry geomlonlatB, float8 radius=6371008);
float ST_DistanceSpheroid(geometry geomlonlatA, geometry geomlonlatB, spheroid measurement_spheroid=WGS84);

距離計算の例を示します。ST_DistanceSpheroidの計算結果のほうが、geography 型を使った距離計算(単位:メートル)の例で実行したクエリの結果と近い値が出るため、より正確な計算ができていることがわかります。

-- 地球を球体とみなした距離計算(単位:メートル)
postgres=# SELECT ST_DistanceSphere(
    ST_MakePoint(139.76701944398158, 35.68121661474183), -- 例: 東京駅
    ST_MakePoint(135.4957763072182, 34.70248840069602)  -- 例: 大阪駅
);
 st_distancesphere
-------------------
   403063.48270457 -- 計算結果の単位は「メートル」  約403.0km
(1 row)
-- より正確な楕円体モデルを使用した距離計算(単位:メートル)
postgres=# SELECT ST_DistanceSpheroid(
    ST_MakePoint(139.76701944398158, 35.68121661474183), -- 例: 東京駅
    ST_MakePoint(135.4957763072182, 34.70248840069602), -- 例: 大阪駅
    'SPHEROID["WGS 84",6378137,298.257223563]' -- 楕円体モデルのパラメータを指定可能(デフォルトはWGS84)
);
 st_distancespheroid
---------------------
   403832.1066283856 -- 計算結果の単位は「メートル」  約403.8km
(1 row)

ST_DistanceSphereST_DistanceSpheroid の違いをまとめると以下の通りです。

計算モデル

関数 使用モデル 特徴
ST_DistanceSphere 球体モデル 地球を完全な球体(半径約6371km)として扱う
ST_DistanceSpheroid 楕円体モデル WGS84などの楕円体モデルを使用(極半径と赤道半径の違いを考慮)

計算精度と性能

関数 精度 計算速度 適用範囲
ST_DistanceSphere 中程度 速い 広範囲でない場合や近似値で十分な場合
ST_DistanceSpheroid 高い 遅い 正確な測地距離が必要な場合、特に長距離や高緯度での計算

ST_DistanceSphere は地球を完全な球と仮定するため計算が速い反面、精度はST_DistanceSpheroidより劣ります。ST_DistanceSpheroidWGS84などの楕円体モデルを使用し、より正確な計算が可能です。正確さを重視する場合はST_DistanceSpheroidを使用すると良さそうです。

詳細は、公式ドキュメントを参照してください。
https://postgis.net/docs/ja/ST_DistanceSphere.html
https://postgis.net/docs/ja/ST_Distance_Spheroid.html

まとめ

PostGIS では、geometry 型と geography 型の両方で距離計算が可能ですが、データ型や座標系によって計算方法や計算結果の単位が異なるため、計算結果を正確に解釈するためには注意が必要です。

参考リンク

https://postgis.net/docs/ja/ST_Distance.html
https://postgis.net/docs/ja/ST_DistanceSphere.html
https://postgis.net/docs/ja/ST_Distance_Spheroid.html

GitHubで編集を提案

Discussion