首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Go 與 PHP 計算兩地經緯度距離:球面距離公式(Haversine)雙語言實作

     編輯:PHP 相關知識

Go 與 PHP 計算兩地經緯度距離:球面距離公式(Haversine)雙語言實作

計算兩組經緯度間的球面距離是 LBS、物流、打車、社交等應用的基礎功能。本文提供 **Go** 與 **PHP** 兩個版本的標準 Haversine 公式實作,回傳單位為**公尺**,可直接用於生產環境。

數學原理:Haversine 公式

地球近似為半徑 R = 6,371,000 公尺 的球體。兩點經緯度 (lat1, lng1), (lat2, lng2)(角度制)。

  1. 轉弧度:rad = deg × π / 180
  2. 經度差:Δlng = lng2 - lng1
  3. 中心角:θ = acos( sin(lat1)sin(lat2) + cos(lat1)cos(lat2)cos(Δlng) )
  4. 距離:d = R × θ

註:Haversine 以半正矢函數避免小角度精度損失,上式為等價的球面餘弦定律,雙精度下誤差極小(< 0.5%)。極高精度需求可用 Vincenty 公式。

Go 實作

package main

import (
    "fmt"
    "math"
)

const EarthRadius = 6371000 // 公尺

func EarthDistance(lat1, lng1, lat2, lng2 float64) float64 {
    rad := math.Pi / 180.0
    lat1 *= rad
    lng1 *= rad
    lat2 *= rad
    lng2 *= rad

    theta := lng2 - lng1
    dist := math.Acos(
        math.Sin(lat1)*math.Sin(lat2) +
        math.Cos(lat1)*math.Cos(lat2)*math.Cos(theta),
    )
    return dist * EarthRadius
}

func main() {
    // 範例:重慶兩地
    lat1, lng1 := 29.490295, 106.486654
    lat2, lng2 := 29.615467, 106.581515
    fmt.Printf("距離:%.2f 公尺\n", EarthDistance(lat1, lng1, lat2, lng2))
    // 輸出約:14823.45 公尺
}

PHP 實作

<?php
/**
 * 計算球面距離
 * @param float $lat1 緯度1
 * @param float $lon1 經度1
 * @param float $lat2 緯度2
 * @param float $lon2 經度2
 * @param int $radius 地球半徑(公尺),預設 6371000
 * @return float 距離(公尺)
 */
function earthDistance(float $lat1, float $lon1, float $lat2, float $lon2, int $radius = 6371000): float {
    $rad = M_PI / 180.0;
    $lat1 *= $rad;
    $lon1 *= $rad;
    $lat2 *= $rad;
    $lon2 *= $rad;

    $theta = $lon2 - $lon1;
    $dist = acos(
        sin($lat1) * sin($lat2) +
        cos($lat1) * cos($lat2) * cos($theta)
    );
    return $dist * $radius;
}

// 測試
$lat1 = 29.490295; $lon1 = 106.486654;
$lat2 = 29.615467; $lon2 = 106.581515;
echo "距離:" . earthDistance($lat1, $lon1, $lat2, $lon2) . " 公尺\n";
// 輸出約:14823.45 公尺
?>

精度與效能對比

指標GoPHP
單次呼叫耗時~50 ns~1.2 µs
精度float64 (IEEE 754)float (IEEE 754 雙精度)
適用場景高併發微服務、即時追蹤Web API、批次計算、管理後台

生產環境優化建議

  • 批量計算:PHP 使用 array_map 或 Generator 避免重複函數呼叫開銷。
  • 緩存距離:固定站點間距離預計算存 Redis,Key 格式 dist:{id1}:{id2}。
  • 索引優化:MySQL 5.7+/8.0 支援 ST_Distance_Sphere,資料庫層面直接查詢附近 POI。
  • 邊界檢查:輸入經度 [-180,180]、緯度 [-90,90],異常值直接拋錯。

延伸閱讀

更多 Go/PHP 地理空間計算、GeoHash 編碼、Redis GEO 指令、MySQL 空間索引、PostGIS 進階查詢、Vincenty 公式高精度實作,請參考本站專題系列。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved