分析與測試CRM和數據平台營銷工具

使用 Haversine 公式計算或查詢緯度和經度點之間的大圓距離(PHP、JavaScript、Java、Python、MySQL、MSSQL 示例)

這個月,我一直在使用 PHP 和 MySQL 進行 GIS 程式設計。 在研究該主題時,我很難找到 地理計算 找到兩個位置之間的距離,所以我想在這里分享它們。

飛行地圖歐洲,具有很大的圓周距離

計算兩點之間的距離的簡單方法是使用勾股定律公式來計算三角形的斜邊(A²+B²=C²)。 這被稱為 歐氏距離.

這是一個有趣的開始,但它不適用於地理,因為緯度線和經度線之間的距離是 間隔距離不相等。 當你越接近赤道時,緯線就會變得越遠。 如果您使用簡單的三角測量方程,由於地球的曲率,它可能會在一個位置準確地測量距離,而在另一個位置測量錯誤。

大圓距離

繞地球運行很長距離的路線被稱為大圓距離。 那就是……球體上兩點之間的最短距離不同於平面地圖上的點。 將其與緯度和經度線不等距的事實結合起來......你的計算很困難。

這是有關Great Circles工作原理的精彩視頻說明。

Haversine公式

使用地球曲率的距離包含在 Haversine 公式中,該公式使用三角學來考慮地球的曲率。 當您計算地球上兩個地點之間的距離時(如烏鴉所言),一條直線實際上是一條弧線。

這適用於空中飛行——你有沒有看過實際的航班地圖並註意到它們是拱形的? 那是因為在兩點之間的拱形飛行比直接飛到該位置要短。

PHP:計算2個緯度和經度之間的距離

這是計算兩點之間距離的 PHP 公式(以及英里與公里的轉換),四捨五入到小數點後兩位。

function getDistanceBetweenPointsNew($latitude1, $longitude1, $latitude2, $longitude2, $unit = 'miles') {
  $theta = $longitude1 - $longitude2; 
  $distance = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))) + (cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * cos(deg2rad($theta))); 
  $distance = acos($distance); 
  $distance = rad2deg($distance); 
  $distance = $distance * 60 * 1.1515; 
  switch($unit) { 
    case 'miles': 
      break; 
    case 'kilometers' : 
      $distance = $distance * 1.609344; 
  } 
  return (round($distance,2)); 
}

變量是:

  • $緯度1 – 您的第一個位置的緯度變量。
  • $經度1 – 您的第一個位置的經度變量
  • $緯度2 – 第二個位置緯度的變量。
  • $經度2 – 第二個位置的經度變量。
  • $單位 – 默認是 英里. 這可以更新或傳遞為 公里.

Java:計算經緯度兩點之間的距離

public static double getDistanceBetweenPointsNew(double latitude1, double longitude1, double latitude2, double longitude2, String unit) {
    double theta = longitude1 - longitude2;
    double distance = 60 * 1.1515 * (180/Math.PI) * Math.acos(
        Math.sin(latitude1 * (Math.PI/180)) * Math.sin(latitude2 * (Math.PI/180)) + 
        Math.cos(latitude1 * (Math.PI/180)) * Math.cos(latitude2 * (Math.PI/180)) * Math.cos(theta * (Math.PI/180))
    );
    if (unit.equals("miles")) {
        return Math.round(distance, 2);
    } else if (unit.equals("kilometers")) {
        return Math.round(distance * 1.609344, 2);
    } else {
        return 0;
    }
}

變量是:

  • 緯度1 – 您的第一個位置的緯度變量。
  • 經度1 – 您的第一個位置的經度變量
  • 緯度2 – 第二個位置緯度的變量。
  • 經度2 – 第二個位置的經度變量。
  • 單位 – 默認是 英里. 這可以更新或傳遞為 公里.

JavaScript:計算兩點緯度和經度之間的距離

function getDistanceBetweenPoints(latitude1, longitude1, latitude2, longitude2, unit = 'miles') {
    let theta = longitude1 - longitude2;
    let distance = 60 * 1.1515 * (180/Math.PI) * Math.acos(
        Math.sin(latitude1 * (Math.PI/180)) * Math.sin(latitude2 * (Math.PI/180)) + 
        Math.cos(latitude1 * (Math.PI/180)) * Math.cos(latitude2 * (Math.PI/180)) * Math.cos(theta * (Math.PI/180))
    );
    if (unit == 'miles') {
        return Math.round(distance, 2);
    } else if (unit == 'kilometers') {
        return Math.round(distance * 1.609344, 2);
    }
}

變量是:

  • 緯度1 – 您的第一個位置的緯度變量。
  • 經度1 – 您的第一個位置的經度變量
  • 緯度2 – 第二個位置緯度的變量。
  • 經度2 – 第二個位置的經度變量。
  • 單位 – 默認是 英里. 這可以更新或傳遞為 公里.

Python:計算2個緯度和經度點之間的距離

以下是計算兩點之間距離(​​以及英里與公里轉換)的 Python 公式,四捨五入到小數點後兩位。 感謝我的兒子 Bill Karr,他是一名數據科學家 開放洞察, 對於代碼。

from numpy import sin, cos, arccos, pi, round

def rad2deg(radians):
    degrees = radians * 180 / pi
    return degrees

def deg2rad(degrees):
    radians = degrees * pi / 180
    return radians

def getDistanceBetweenPointsNew(latitude1, longitude1, latitude2, longitude2, unit = 'miles'):
    
    theta = longitude1 - longitude2
    
    distance = 60 * 1.1515 * rad2deg(
        arccos(
            (sin(deg2rad(latitude1)) * sin(deg2rad(latitude2))) + 
            (cos(deg2rad(latitude1)) * cos(deg2rad(latitude2)) * cos(deg2rad(theta)))
        )
    )
    
    if unit == 'miles':
        return round(distance, 2)
    if unit == 'kilometers':
        return round(distance * 1.609344, 2)

變量是:

  • 緯度1 – 您的第一個位置的變量 緯度.
  • 經度1 – 您的第一個位置的變量 經度
  • 緯度2 – 您的第二個位置的變量 緯度.
  • 經度2 – 您的第二個位置的變量 經度.
  • 單位 – 默認是 英里. 這可以更新或傳遞為 公里.

MySQL:通過使用緯度和經度以英里為單位計算距離來檢索範圍內的所有記錄

在 MySQL 中使用空間數據類型是處理地理數據(包括計算點之間的距離)的一種更高效、更方便的方法。 MySQL 支持空間數據類型,例如 POINT, LINESTRINGPOLYGON,以及空間函數,例如 ST_Distance.

當您使用 ST_Distance MySQL 中的函數,地理數據表示為 POINT 坐標,它考慮了地球表面的曲率。 使用的球形模型 ST_Distance 採用半正矢公式。 這種近似適用於大多數實際目的,但對於很長的距離可能會產生輕微的誤差。

以下是如何使用空間數據類型計算兩點之間的距離:

  1. 創建具有空間數據類型的表:首先創建一個表 POINT 存儲地理點的列。 例如:
CREATE TABLE locations (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    coordinates POINT
);

使用以下命令將您的地理點插入此表中 POINT 構造函數:

INSERT INTO locations (name, coordinates)
VALUES
    ('Point A', POINT(40.7128, -74.0060)), -- New York City
    ('Point B', POINT(34.0522, -118.2437)); -- Los Angeles
  1. 使用 ST_Distance 計算距離:您可以使用以下方法計算兩點之間的距離 ST_Distance 功能。 以下是計算兩點之間距離的示例查詢:
SELECT
    id1,
    id2,
    (ST_Distance(coordinates1, coordinates2) / 1609.344) AS distance_in_miles
FROM (
    SELECT
        l1.id AS id1,
        l2.id AS id2,
        l1.coordinates AS coordinates1,
        l2.coordinates AS coordinates2
    FROM
        locations l1,
        locations l2
    WHERE
        l1.id = 1 AND l2.id = 2
) AS distances;

更換 12 以及要計算其間距離的兩點的 ID。

  1. 結果:查詢將返回兩點之間的距離,單位為英里。

使用空間數據類型和 ST_Distance 函數提供了一種更高效、更準確的方式來處理 MySQL 中的地理數據。 它還簡化了點之間距離的計算,使管理和查詢數據變得更加容易。

MySQL:通過使用緯度和經度以公里為單位計算距離來檢索範圍內的所有記錄

默認情況下 ST_Distance 返回以米為單位的距離,因此您只需更新公里查詢:

SELECT
    id1,
    id2,
    (ST_Distance(coordinates1, coordinates2) / 1000) AS distance_in_kilometers
FROM (
    SELECT
        l1.id AS id1,
        l2.id AS id2,
        l1.coordinates AS coordinates1,
        l2.coordinates AS coordinates2
    FROM
        locations l1,
        locations l2
    WHERE
        l1.id = 1 AND l2.id = 2
) AS distances;

Microsoft SQL Server 地理距離:STDistance

如果您使用 Microsoft SQL Server,它們會提供自己的功能, 標準距離 用於使用 Geography 數據類型計算兩點之間的距離。

DECLARE @g geography;  
DECLARE @h geography;  
SET @g = geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656)', 4326);  
SET @h = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326);  
SELECT @g.STDistance(@h);  

向 Manash Sahoo 致敬,創辦人兼高級架構師 離子三號.

Douglas Karr

Douglas Karr 是 CMO 的 開放洞察 和創始人 Martech Zone。 道格拉斯幫助了數十家成功的 MarTech 新創公司,協助進行了超過 5 億美元的 MarTech 收購和投資盡職調查,並繼續協助公司實施和自動化其銷售和行銷策略。 道格拉斯是國際公認的數位轉型和 MarTech 專家和演講者。 道格拉斯也是一本傻瓜指南和一本商業領導書的出版作者。

相關文章

返回頂部按鈕
關閉

檢測到Adblock

Martech Zone 我們能夠免費為您提供這些內容,因為我們通過廣告收入、聯屬鏈接和讚助從我們的網站中獲利。 如果您在瀏覽我們的網站時刪除廣告攔截器,我們將不勝感激。