Java實現經緯度距離計算,精確計算兩點間距離的方法

一、概述

隨着全球經濟的發展和交通出行的便捷,我們需要對兩點之間的距離進行準確的計算,而經緯度距離計算就是最常見的一種計算方法。在Java中,我們可以使用不同的方法來實現經緯度距離計算,本文將針對這一問題,介紹一些經典的算法和代碼實現。

二、常見的經緯度距離計算方法

在實現經緯度距離計算時,常用的有以下三種方法:

1、球面餘弦定理:該方法適用於計算地球上兩點之間的距離,需要使用球面三角形的餘弦定理。

2、Vincenty公式:該方法是基於橢球體上的測地線距離計算的,是計算地球上兩點之間距離的精確方法。

3、Haversine公式:該方法是一種簡單的計算地球上兩點之間距離的方法,適用於全球各地的距離計算。

三、球面餘弦定理計算代碼示例:

public static final double EARTH_RADIUS = 6371.393;    //地球半徑,單位千米
public static double getDistance(double long1, double lat1, double long2, double lat2){
        long1 = Math.toRadians(long1);
        long2 = Math.toRadians(long2);
        lat1 = Math.toRadians(lat1);
        lat2 = Math.toRadians(lat2);
        double cos = Math.cos(lat1) * Math.cos(lat2) * Math.cos(long1 - long2) + Math.sin(lat1) * Math.sin(lat2);
        double distance = EARTH_RADIUS * Math.acos(cos);
        return distance;
}

以上代碼是基於球面餘弦定理實現的經緯度距離計算,通過該方法我們可以計算出兩點之間的準確距離。需要注意的是,計算的結果是千米,如果需要轉換為其他單位,需要自行進行轉換計算。

四、Vincenty公式計算代碼示例:

public static final double EARTH_RADIUS = 6378137;    //地球半徑,單位米
public static double getDistance(double long1, double lat1, double long2, double lat2){
        double a = EARTH_RADIUS;
        double b = a - 21.385 * (1 - Math.sin(Math.toRadians(lat1))) / 180;
        double f = (a - b) / a;
        double L = Math.toRadians(long2 - long1);
        double U1 = Math.atan((1 - f) * Math.tan(Math.toRadians(lat1)));
        double U2 = Math.atan((1 - f) * Math.tan(Math.toRadians(lat2)));
        double sinU1 = Math.sin(U1);
        double cosU1 = Math.cos(U1);
        double sinU2 = Math.sin(U2);
        double cosU2 = Math.cos(U2);
        double lambda = L;
        double sinLambda = Math.sin(lambda);
        double cosLambda = Math.cos(lambda);
        double sinSigma = 0;
        double cosSigma = 0;
        double sigma = 0;
        double sinAlpha = 0;
        double cosSqAlpha = 0;
        double cos2SigmaM = 0;
        double C = 0;
        double deltaLambda = 0;
        double tempLambda = 0;
        for (int i = 0; i < 100; i++) {
            tempLambda = lambda;
            sinLambda = Math.sin(tempLambda);
            cosLambda = Math.cos(tempLambda);
            sinSigma = Math.sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda));
            cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
            sigma = Math.atan2(sinSigma, cosSigma);
            sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
            cosSqAlpha = 1 - sinAlpha * sinAlpha;
            cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
            if (Double.isNaN(cos2SigmaM)) {
                cos2SigmaM = 0;
            }
            C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
            deltaLambda = L + (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
            if (Math.abs(deltaLambda - lambda) < 0.0001) {
                break;
            } else {
                lambda = deltaLambda;
            }
        }
        double distance = b * cosU2 * (deltaLambda - L);
        return distance;
}

以上代碼是基於Vincenty公式實現的距離計算,這個算法可以提供更高的計算精度,但計算量相對較大。

五、Haversine公式計算代碼示例:

public static final double EARTH_RADIUS = 6371.393;    //地球半徑,單位千米
public static double getDistance(double long1, double lat1, double long2, double lat2){
        double radLat1 = Math.toRadians(lat1);
        double radLat2 = Math.toRadians(lat2);
        double a = radLat1 - radLat2;
        double b = Math.toRadians(long1) - Math.toRadians(long2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        return s;
}

以上代碼是基於Haversine公式實現的經緯度距離計算,算法簡單而效率高,早在18世紀時就被廣泛應用于海洋導航。

六、總結

在本文中,我們介紹了三種不同的方法實現經緯度距離計算,分別是球面餘弦定理、Vincenty公式和Haversine公式。在實際應用中,我們需要根據具體情況選擇不同的方法。球面餘弦定理適用於需要快速計算近似距離的場景,Haversine公式可用於快速計算全球各地的距離,Vincenty公式則可提供更高的計算精度。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/181973.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-24 06:17
下一篇 2024-11-24 06:17

相關推薦

  • Python線性插值法:用數學建模實現精確預測

    本文將會詳細介紹Python線性插值法的實現方式和應用場景。 一、插值法概述 插值法是基於已知數據點得出缺失數據點的一種方法。它常用於科學計算中的函數逼近,是一種基礎的數學建模技術…

    編程 2025-04-27
  • 召回率與精確率的重要性

    一、什麼是召回率和精確率 在機器學習中,召回率和精確率是非常重要的指標,用來評估一個模型的性能表現。召回率是指模型正確預測正例的數量在所有正例中的比例;而精確率是指模型正確預測正例…

    編程 2025-04-24
  • 百度地圖獲取經緯度詳解

    一、獲取百度地圖上的經緯度 百度地圖JavaScript API提供了一個函數,可以獲取地圖上任意點的經緯度坐標。 // 點擊地圖獲取經緯度 map.addEventListene…

    編程 2025-04-23
  • Python Timedelta: 精確時間差計算模塊

    在現代社會中,我們經常需要計算兩個時間之間的時間差,例如計算程序運行時間、計算兩個事件之間的距離等。在Python中,我們可以使用timedelta模塊來計算時間差,該模塊提供了一…

    編程 2025-04-22
  • 深度解析精確率和召回率

    一、什麼是精確率和召回率? 在對分類模型進行性能評估時,精確率(Precision)和召回率(Recall)是最為常用的衡量指標之一。精確率和召回率均是指在二分類問題中,模型預測為…

    編程 2025-02-25
  • 如何在百度地圖中獲取經緯度

    一、百度地圖如何獲取經緯度坐標 百度地圖可以通過三種方式獲取經緯度坐標,它們分別是: 在地圖上點擊獲取經緯度坐標 使用百度地圖API獲取經緯度坐標 利用瀏覽器F12開發者工具獲取經…

    編程 2025-02-15
  • 如何精確將double數值取到小數點後兩位?

    一、使用DecimalFormat類實現精確的數值取捨 Java中提供了DecimalFormat類來格式化double數值,從而實現對數值的精確取捨。DecimalFormat默…

    編程 2025-02-05
  • 經緯度正則表達式詳解

    一、什麼是經緯度 經度和緯度是描述地球表面位置的坐標系,是地球表面的橫縱坐標,用於確定某個具體的地理位置。 經度是以本初子午線為基礎,東西兩邊各180度。東經0度是本初子午線,向東…

    編程 2025-01-21
  • java獲取小時,java獲取當前時間精確到秒

    本文目錄一覽: 1、java中對日期取小時的方法是什麼? 2、在java中怎樣用字符串技術獲取小時數、分鐘數、和秒數? 3、java中怎麼得到當前時間的小時 java中對日期取小時…

    編程 2025-01-16
  • cdr裏面行距快捷鍵,cdr字體間距快捷鍵

    本文目錄一覽: 1、CDR如何調整行間距 2、CDR字間距快捷鍵 3、朋友,在CDR文字排版中,字行距怎樣調?操作如何?快捷鍵是多少? 4、cdr裏面文字間距怎麼調,字不能變形,還…

    編程 2025-01-16

發表回復

登錄後才能評論