在建置以位置為基礎的網路應用程式時,開發者通常預設使用 Haversine 公式來計算兩個 GPS 座標之間的距離和方位角。對大多數應用程式而言,假設地球是完美球體已經「足夠好」了。
但是,如果你正在建置一個應用程式,其絕對精確度是不可妥協的呢?
在建置 Quranbookk 的朝拜指南針——一個幫助全球穆斯林找到麥加克爾白確切方向的網路應用程式——時,我很快發現標準球面數學會引入不可接受的誤差範圍。
以下是我捨棄 Haversine 公式,以及如何使用 Next.js 和 Karney 的測地線演算法實作亞毫米級精確度解決方案的原因。
Haversine 公式的問題
Haversine 公式計算地球表面上的最短距離,但它假設地球是完美球體。實際上,地球是一個扁球體(赤道較寬、兩極較扁平)。
當從全球各地計算朝向麥加的方位角時(例如從北美或北歐),這種「球體假設」可能導致數度誤差。當建置一個宗教工具,用戶依賴絕對準確度時,偏離幾度對使用者體驗和信任而言是重大的失敗。
引入 Karney 的測地線演算法
為了解決這個問題,我改用 WGS84 橢球體模型,採用 Charles Karney 的測地線演算法。Karney 的演算法計算橢球體表面兩點之間的最短路徑,而非在完美球體上畫線。
數學複雜度顯著提高,涉及橢圓積分,但結果是方位角和距離計算準確至毫米以下的誤差範圍。
在 Next.js 中實作
由於我正在建置現代網路平台,效能至關重要。我使用 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。數學稍難一些,但精確度值得。如果你想查看即時實作,請前往我的平台: 朝拜指南針 - Quranbookk。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.