PostGIS における座標系と距離計算について: geometry 型と geography 型の違い
はじめに
PostGIS で位置情報データを扱う際には座標系と測地計算の違いに注意が必要です。
私は最近、IoT デバイスから発信される位置情報データを収集・分析する業務に携わりました。その中で、PostGIS を使って位置情報を扱う際に座標系と測地計算の違いについて新たに学びがあったため記事にまとめました。PostGIS で位置情報を扱う方々の参考になれば幸いです。
座標系とは
座標系(coordinate system)は、空間内の位置を表現するための基準となる枠組みのことです。座標系が定義されることで、点の位置を数値(座標)として表現し、計算や可視化が可能になります。座標系は地理座標系と投影座標系の 2 種類があります。
- 地理座標系:地球の球面をそのまま扱う座標系。角度で表現される。
- 投影座標系:地球の球面を平面に投影した座標系。メートルやフィートなどの距離で表現される。距離や面積の計算に適している。
geometry
型と geography
型の違い
1. PostGIS では位置情報を扱うための空間データ型として主に 2 つの型(geometry
, geography
)が用意されています。名前が似ているので混同しやすいですが、それぞれの違いを以下にまとめました。geometry
型と geography
型では計算方法/計算結果/距離の単位が異なります。
geometry
型
-
座標系(SRID)を自由に設定可能:
WGS 84
、UTM
、EPSG:3857
など -
距離の単位は SRID に依存:
WGS 84
では「度」、投影座標系なら「メートル」 - 平面座標での計算:地球の曲率を考慮しない単純な平面として計算
- 計算が高速:単純な数学計算のため処理効率が良い
geography
型
- 座標系は WGS 84(SRID:4326)に固定
- 距離の単位は常にメートル
- 測地計算:地球の球面/楕円体形状を考慮した計算
- 地球の曲率を考慮するため、精度が高いが処理負荷も高い
2. 距離計算の方法
PostGIS では2 つのジオメトリ間の距離を計算する関数として、ST_Distance
と ST_DistanceSphere
と ST_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);
詳細は、公式ドキュメントを参照してください。
geometry
型)(単位: 度 or メートル)
ST_Distanceを使った距離計算(ここからは、実際のクエリ例を見ながら違いを確認してみましょう。
下記のクエリは、東京駅と大阪駅の距離を計算しています。
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)
geography
型)(単位: メートル)
ST_Distanceを使った距離計算(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_DistanceSphere
と ST_DistanceSpheroid
の活用
ただし、geometry
型のままでも、ST_DistanceSphere
や ST_DistanceSpheroid
を使うと地球の形状を考慮した計算ができます。
以下に、ST_DistanceSphere
と ST_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_DistanceSphere
と ST_DistanceSpheroid
の違いをまとめると以下の通りです。
計算モデル
関数 | 使用モデル | 特徴 |
---|---|---|
ST_DistanceSphere |
球体モデル | 地球を完全な球体(半径約6371km)として扱う |
ST_DistanceSpheroid |
楕円体モデル | WGS84などの楕円体モデルを使用(極半径と赤道半径の違いを考慮) |
計算精度と性能
関数 | 精度 | 計算速度 | 適用範囲 |
---|---|---|---|
ST_DistanceSphere |
中程度 | 速い | 広範囲でない場合や近似値で十分な場合 |
ST_DistanceSpheroid |
高い | 遅い | 正確な測地距離が必要な場合、特に長距離や高緯度での計算 |
ST_DistanceSphere
は地球を完全な球と仮定するため計算が速い反面、精度はST_DistanceSpheroid
より劣ります。ST_DistanceSpheroid
はWGS84
などの楕円体モデルを使用し、より正確な計算が可能です。正確さを重視する場合はST_DistanceSpheroid
を使用すると良さそうです。
詳細は、公式ドキュメントを参照してください。
まとめ
PostGIS では、geometry
型と geography
型の両方で距離計算が可能ですが、データ型や座標系によって計算方法や計算結果の単位が異なるため、計算結果を正確に解釈するためには注意が必要です。
参考リンク
Discussion