java基础操作3——java多种方案实现计算地图上两个坐标间距离

本文介绍了在项目中计算两点之间距离的几种方法,包括反余弦法、利用GoogleMap和高德地图API,以及考虑地球形状(平均半径或赤道半径)的精确算法,适用于不同精度需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在实际项目中,涉及定位和位置信息业务时,计算两个点的距离算是比较常见的问题。

以下是多个方案计算两个点坐标的方案,欢迎围观讨论。

需要注意的是:

  • 中国大约位于4°N——53°N多之间,跨纬度近50°,位于73°E——135°E,东西跨经度62°
  • 所有方案的入参说明:第一点的经度,第一点的纬度,第二点的经度,第二点的纬度
  • 所有方案的返回距离单位:米

如果需要计算三维空间两点之间的的绝对距离,请点击此链接查看。

1.反余弦计算方式(地球平均半径(单位:米))

public static double getCoordinateDistanceOne(double longitude1, double latitude1, 
                                                  double longitude2, double latitude2) {
        // 经纬度(角度)转弧度。弧度作为作参数,用以调用Math.cos和Math.sin
        // A经弧度
        double radiansAX = Math.toRadians(longitude1);
        // A纬弧度
        double radiansAY = Math.toRadians(latitude1);
        // B经弧度
        double radiansBX = Math.toRadians(longitude2);
        // B纬弧度
        double radiansBY = Math.toRadians(latitude2);
        // 公式中“cosβ1cosβ2cos(α1-α2)+sinβ1sinβ2”的部分,得到∠AOB的cos值
        double cos = Math.cos(radiansAY) * Math.cos(radiansBY) * Math.cos(radiansAX - radiansBX) + Math.sin(radiansAY) * Math.sin(radiansBY);
        // System.out.println("cos = " + cos); // 值域[-1,1]
        // 反余弦值
        double acos = Math.acos(cos);
        // System.out.println("acos = " + acos); // 值域[0,π]
        // System.out.println("∠AOB = " + Math.toDegrees(acos)); // 球心角 值域[0,180]
        // 最终结果
        return EARTH_AVG_RADIUS * acos;
    }

2.基于googleMap中的算法得到两经纬度之间的距离

其计算精度与谷歌地图的距离精度类似

public static double getCoordinateDistanceTwo(double longitude1, double latitude1,
                                                  double longitude2, double latitude2) {
        double radLat1 = rad(latitude1);
        double radLat2 = rad(latitude2);
        double a = radLat1 - radLat2;
        double b = rad(longitude1) - rad(longitude2);
        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_AVG_RADIUS;
        s = Math.round(s * 10000d) / 10000d;
        return s;
    }

需要注意的是前两种方案都需要:地球平均半径(单位:米)

    /**
     * 地球平均半径(单位:米)
     */
    private static final double EARTH_AVG_RADIUS = 6371000;

3.基于高德地图计算方法

public static double getCoordinateDistanceThree(double longitude1, double latitude1,
                                                    double longitude2, double latitude2) {
        if (longitude1 == 0 || latitude1 == 0 || latitude2 == 0 || longitude2 == 0) {
            return -1.0;
        }
        longitude1 *= 0.01745329251994329;
        latitude1 *= 0.01745329251994329;
        longitude2 *= 0.01745329251994329;
        latitude2 *= 0.01745329251994329;
        double var1 = Math.sin(longitude1);
        double var2 = Math.sin(latitude1);
        double var3 = Math.cos(longitude1);
        double var4 = Math.cos(latitude1);
        double var5 = Math.sin(longitude2);
        double var6 = Math.sin(latitude2);
        double var7 = Math.cos(longitude2);
        double var8 = Math.cos(latitude2);
        double[] var10 = new double[3];
        double[] var20 = new double[3];
        var10[0] = var4 * var3;
        var10[1] = var4 * var1;
        var10[2] = var2;
        var20[0] = var8 * var7;
        var20[1] = var8 * var5;
        var20[2] = var6;
        return Math.asin(Math.sqrt((var10[0] - var20[0]) * (var10[0] - var20[0]) + (var10[1] - var20[1]) * (var10[1] - var20[1]) + (var10[2] - var20[2]) * (var10[2] - var20[2])) / 2.0) * 1.27420015798544E7;
        // 结果四舍五入 保留2位小数
    }

4.反余弦计算方式(赤道半径(单位:米))

/**
 * 赤道半径(单位:米)
*/
private static final double EQUATOR_RADIUS = 6378137;

public static double getCoordinateDistanceFour(double longitude1, double latitude1, 
                                                   double longitude2, double latitude2) {
        // 纬度
        double lat1 = Math.toRadians(latitude1);
        double lat2 = Math.toRadians(latitude2);
        // 经度
        double lon1 = Math.toRadians(longitude1);
        double lon2 = Math.toRadians(longitude2);
        // 纬度之差
        double a = lat1 - lat2;
        // 经度之差
        double b = lon1 - lon2;
        // 计算两点距离的公式
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));
        // 弧长乘赤道半径, 返回单位: 米
        s = s * EQUATOR_RADIUS;
        return s;
    }

5.最终结果展示

此方案参考于:https://www.jb51.net/program/3079708iv.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值