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/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

发表回复

登录后才能评论