ドキュメント / コア / 地球上の計算

地球上の計算(Spherical)

距離・方位・面積・補間といった地理計算を、3プラットフォームで同じ名前・同じ結果で提供します。地図SDKごとのユーティリティに頼らないため、プロバイダを差し替えても数値が変わりません。SDK 内部のタップ判定や大圏コース描画も、すべてこの計算を使っています。

ELLIPSOID
WGS84
SEMI-MAJOR
6,378,137 m
FLATTENING
1 / 298.257…
UNIT
メートル / 度
プラットフォーム

01 · 基本の計算

よく使う関数は Spherical にまとまっています。距離はメートル、方位は真北を0とした度、面積は平方メートルで返ります。引数は座標そのもので、投影やズームには依存しません。

関数
説明
computeDistanceBetween
2点間の距離(メートル)。
computeHeading
始点から終点を見たときの方位(−180〜180度)。
computeOffset
始点から距離と方位を指定した先の座標。円やリングの生成に使います。
computeOffsetOrigin
終点・距離・方位から始点を逆算します。
computeLength
座標列に沿った全長(メートル)。ルートの距離表示に。
computeArea / computeSignedArea
閉じた座標列が囲む面積(平方メートル)。符号付きは回転方向の判定に使えます。
interpolate
2点間を大圏コース上で比率補間します。
Planar.interpolate
2点間を緯度経度の直線で比率補間します(直線モデル Planar のメソッド)。日付変更線をまたぐ場合も最短側を通ります。
com.mapconductor.core.spherical
val meters = Spherical.computeDistanceBetween(from, to)
val heading = Spherical.computeHeading(from, to)

// 円の外周マーカーを8方向に置く
val ring = (0 until 8).map { i ->
    Spherical.computeOffset(center, 3_000.0, i * 45.0)
}

val routeMeters = Spherical.computeLength(routePoints)
val areaSqMeters = Spherical.computeArea(polygonPoints)

02 · 球体モデルと楕円体モデル

地理計算には2つの精度水準を用意しています。地球を真球として扱う球体モデルと、WGS84 楕円体として扱う測地線モデルです。用途に応じて使い分けます。

定数はどちらも WGS84 に基づいています(赤道半径 6,378,137 m、扁平率 1/298.257223563)。3プラットフォームで同じ定数・同じ式を使うため、同じ入力なら同じ値が返ります。

Spherical

球体モデル(十分速く、十分正確)

半正矢(haversine)による距離、球面三角法による方位・補間です。数百km程度までなら誤差は実用上無視でき、計算コストが小さいのが利点です。

用途: 距離表示 · 方位 · リング生成 · 面積 · タップ判定
WGS84Geodesic

楕円体モデル(測地線)

WGS84 楕円体上の測地線(Vincenty 系の反復解)で計算します。Spherical と同じメソッド構成なので、球体なら Spherical、WGS84 なら WGS84Geodesic と、呼び出しを変えずに差し替えられます。面積は楕円体(authalic)で求めます。

用途: 長距離のフライト経路 · 精密な距離・方位・面積
FALLBACK

収束しないときは球体にフォールバック

楕円体の反復解は、ほぼ対極にある2点などで収束しないことがあります。その場合は球体モデルの結果に自動で切り替えるため、0 や NaN が返ることはありません。呼び出し側で例外処理を書く必要はありません。

03 · 画面との橋渡し

地図上の「指1本ぶん」や「16pxの余白」といった画面基準の量を、地理的な距離に換算する関数群です。ズームと緯度に応じた換算が入っているため、拡大率や場所が変わっても体感が変わりません。

calculateMetersPerPixel
指定ズーム・緯度における1ピクセルあたりのメートル数。
expandBounds
矩形範囲をメートル単位で外側に広げます。表示範囲より少し広めにデータを取るときに。
図 · タップ判定に使われる流れ
01
設定値の「指の大きさ」(論理単位)を画面ピクセルに変換します。
02
calculateMetersPerPixel で、現在のズームと緯度における許容距離(メートル)に換算します。
03
その許容距離を使って、線や図形との距離を地理座標のまま判定します。
この流れのおかげで、ズームを変えても線の押しやすさが変わらず、どのプロバイダでも同じ判定になります。

04 · 線と形のための計算

ポリラインやポリゴンの描画・判定を、どのプロバイダでも同じ結果にするための関数群です。SDK 内部で使っているものと同じものが公開されています。

関数
説明
WGS84Geodesic.createInterpolatePoints
測地線に沿って、区間ごとに座標を補完します。曲線を直接描けないエンジン向けの座標列を作ります。
Planar.createInterpolatePoints
緯度経度の直線に沿って座標を補完します。名前は同じで、名前空間だけが違います。
WGS84Geodesic.pointOnLineOrNull
測地線上の線分に対して、指定距離以内の最近点を返します。曲線のタップ判定に使います。
Planar.pointOnLineOrNull
直線の線分に対して、指定距離以内かを判定します。
splitByMeridian
経度180度をまたぐ座標列を、境界で分割します。名前空間に属さないトップレベルの関数です。
closestPointOnSegment
線分上でもっとも近い点を求めます。こちらもトップレベルの関数です。

createInterpolatePoints と pointOnLineOrNull は、WGS84Geodesic と Planar の両方に同じ名前で用意されています。呼び出し側は名前空間を差し替えるだけで、測地線モデルと直線モデルを切り替えられます。

CONSISTENCY

同じ入力なら同じ結果

Kotlin・Swift・TypeScript の実装は同じ式で書かれており、同じ定数を使います。プラットフォーム間で表示される距離や面積がずれることはありません。

PUBLIC API

アプリからも使える

コアの計算関数は内部専用ではなく公開APIです。ルート距離の表示、半径の計算、独自のヒット判定など、アプリ側のロジックにそのまま使えます。このページに挙げた関数はすべて 3 プラットフォームに揃っています。

関連ページ