farhan reza

位置情報ベースのWebアプリケーションを構築する際、開発者は通常、Haversine式を使用して2つのGPS座標間の距離と方位を計算します。ほとんどのアプリでは、地球を完全な球体と仮定することは「十分」だとされています。

しかし、絶対的な精度が必須となるアプリケーションを構築している場合はどうでしょうか?

世界中のイスラム教徒がメッカのカアバ神殿の正確な方向を見つけるのを支援するWebアプリケーションであるQuranbookkのQibla Finderを構築する中で、標準的な球面数学が許容できない誤差を生じさせていることに私はすぐに気づきました。

ここでは、Haversineを捨てた理由と、Next.jsとKarneyの測地線アルゴリズムを使用してサブミリメートル精度のソリューションを実装した方法について説明します。

Haversine式の問題点

Haversine式は地球表面上の最短距離を計算しますが、地球を完全な球体と仮定しています。実際の地球は赤道で膨らみ、極で平らな扁平楕円体です。

世界各地(北米や北欧など)からメッカの方位を計算する場合、その「球体仮定」は数度の誤差を生じさせる可能性があります。ユーザーが絶対的な精度を求める宗教的なツールを構築する場合、数度の誤差はユーザー体験と信頼の大きな失敗となります。

Karneyの測地線アルゴリズム

この問題を解決するため、Charles Karneyの測地線アルゴリズムを使用したWGS84楕円体モデルに移行しました。完全な球体に線を引く代わりに、Karneyのアルゴリズムは楕円体表面上の2点間の最短経路を計算します。

数学的な複雑さは楕円積分を含むため大幅に高くなりますが、その結果はミリメートルの端数以内の精度で方位と距離を計算できます。

Next.jsでの実装

最新のWebプラットフォームを構築していたため、パフォーマンスが重要でした。Next.js 15 App Routerを使用してアプリケーションを構築しました。

クライアントサイドのバンドルを肥大化させずに重い処理を処理するため、重い測地線計算は動的に処理できます。クライアントサイドでは、HTML5 Geolocation APIとDeviceOrientationイベントを組み合わせてデバイスの磁力計を読み取ります。

// A simplified conceptual approach
import { Geodesic } from 'geographiclib-geodesic';

export function calculatePreciseBearing(lat, lng, destinationLat, destinationLng) {
  const geod = Geodesic.WGS84;
  const r = geod.Inverse(lat, lng, destinationLat, destinationLng);

  // r.azi1 gives the precise forward azimuth (bearing)
  return r.azi1; 
}

Enter fullscreen mode Exit fullscreen mode

結果

KarneyのアルゴリズムとNext.jsのエッジパフォーマンスを組み合わせることで、結果として得られるコンパスは非常に軽量で、ブラウザ内で完全に動作し(モバイルアプリのダウンロードは不要)、ほとんどのネイティブアプリケーションを凌駕する数学的精度を提供します。

位置情報が重要なアプリケーションを構築している場合、Haversineに頼るのはやめましょう。数学は少し難しくなりますが、その精度は価値があります。ライブ実装はこちらのプラットフォームでご覧いただけます:Qibla Finder - Quranbookk