计算两点经纬度之间的距离

        利用第三方包spatial4j里面的三种方法实现两点之间的经纬度计算,并测试北京到上海两点经纬度的距离。

目录

1.环境配置

2.方法一:余弦定理

3.方法二:Vincenty椭球模型

4.方法三:Haversine球面模型


1.环境配置

     maven环境引入spatial4j包环境,使用DistanceUtils方法。import包环境:

  import org.locationtech.spatial4j.distance.DistanceUtils;
<dependency>
    <groupId>org.locationtech.spatial4j</groupId>
    <artifactId>spatial4j</artifactId>
    <version>0.8</version>
</dependency>

2.方法一:余弦定理

     DistanceUtils.distLawOfCosinesRAD:余弦定理,平面计算通过三角函数,误差较大。这里我把distLawOfCosinesRAD方法的底层实现源码提供出来。

public static double distLawOfCosinesRAD(double lat1, double lon1, double lat2, double lon2) {
        if (lat1 == lat2 && lon1 == lon2) {
            return 0.0;
        } else {
            double dLon = lon2 - lon1;
            double cosB = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos(dLon);
            if (cosB < -1.0) {
                return Math.PI;
            } else {
                return cosB >= 1.0 ? 0.0 : Math.acos(cosB);
            }
        }
    }

这个计算的实现过程和下面我将提到的distHaversineRAD、distVincentyRAD有区别,后面我会专门出一篇文章详细说一下区别。

3.方法二:Vincenty椭球模型

     DistanceUtils.distVincentyRAD:椭球模型,类似于地球的椭圆形状,在多次计算的迭代情况下计算的经度较高。

public static double distVincentyRAD(double lat1, double lon1, double lat2, double lon2) {
        if (lat1 == lat2 && lon1 == lon2) {
            return 0.0;
        } else {
            double cosLat1 = Math.cos(lat1);
            double cosLat2 = Math.cos(lat2);
            double sinLat1 = Math.sin(lat1);
            double sinLat2 = Math.sin(lat2);
            double dLon = lon2 - lon1;
            double cosDLon = Math.cos(dLon);
            double sinDLon = Math.sin(dLon);
            double a = cosLat2 * sinDLon;
            double b = cosLat1 * sinLat2 - sinLat1 * cosLat2 * cosDLon;
            double c = sinLat1 * sinLat2 + cosLat1 * cosLat2 * cosDLon;
            return Math.atan2(Math.sqrt(a * a + b * b), c);
        }
    }

 4.方法三:Haversine球面模型

      DistanceUtils.distHaversineRAD:常用的Haversine公式,类似于球模型,以赤道的半径为基准,因此计算时纬度越高误差就会越大,但是计算的速度会很快。


 public static double distHaversineRAD(double lat1, double lon1, double lat2, double lon2) {
        if (lat1 == lat2 && lon1 == lon2) {
            return 0.0;
        } else {
            double hsinX = Math.sin((lon1 - lon2) * 0.5);
            double hsinY = Math.sin((lat1 - lat2) * 0.5);
            double h = hsinY * hsinY + Math.cos(lat1) * Math.cos(lat2) * hsinX * hsinX;
            if (h > 1.0) {
                h = 1.0;
            }

            return 2.0 * Math.atan2(Math.sqrt(h), Math.sqrt(1.0 - h));
        }
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wsgodlike

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值