Nan在使用纬度和经度计算距离

Posted

技术标签:

【中文标题】Nan在使用纬度和经度计算距离【英文标题】:Nan in calculating Distance using Latitude and Longitude 【发布时间】:2013-04-16 16:54:40 【问题描述】:

我正在计算两个纬度和经度之间的距离。我得到了一些距离的结果,但有时,我得到的结果是 NAN。

这是我得到的2个地方的纬度和经度。

例如: 38.655553,-121.091611

38.654875,-121.091324

我正在使用下面的代码参考下面的链接计算距离

Calculating distance between two geographic locations

public static double distanceBetween (double currentLat2, double currentLong2, double mallLat2, double mallLong2)

     float pk = (float) (180/3.14169);

        double a1 = currentLat2 / pk;
        double a2 = currentLong2 / pk;
        double b1 = mallLat2 / pk;
        double b2 = mallLong2 / pk;

        double t1 = FloatMath.cos((float) a1)*FloatMath.cos((float) a2)*FloatMath.cos((float) b1)*FloatMath.cos((float) b2);
        double t2 = FloatMath.cos((float) a1)*FloatMath.sin((float) a2)*FloatMath.cos((float) b1)*FloatMath.sin((float) b2);
        double t3 = FloatMath.sin((float) a1)*FloatMath.sin((float) b1);
        double tt = Math.acos(t1 + t2 + t3);

       return 6366000*tt;               

有什么帮助吗?

谢谢。

【问题讨论】:

Location已经有了distanceTO,怎么回事? 我正在使用 distancebetween() 它有时会给出 NAN 作为结果。 【参考方案1】:

MathFloatfloat 强制转换是导致问题的原因。

我重写了,现在可以了,它给了 79.34m

但主要问题是您在此任务中使用了错误的公式,您在这里使用了具有余弦定律的较大圆距离公式,众所周知,该公式对于浮点运算是“病态的”。然后更糟糕的是,您只使用单精度,而不是双精度。

更强大的公式是haversine 公式。 它旨在克服大圆公式的缺点。

这里您的原始代码已修复,(但我仍然建议改用半正弦公式)

public void test1() 

    // 79.34253285803419
    double lat1 = 38.655553;
    double lon1 = -121.091611;

    double lat2 = 38.654875;
    double lon2 = -121.091324;

    System.out.println(distanceBetween(lat1,  lon1,  lat2,  lon2));


public static double distanceBetween (double currentLat2, double currentLong2, double mallLat2, double mallLong2)

        double pk = 180 / Math.PI;
        double a1 = currentLat2 / pk;
        double a2 = currentLong2 / pk;
        double b1 = mallLat2 / pk;
        double b2 = mallLong2 / pk;

        double t1 = Math.cos( a1) * Math.cos(a2) * Math.cos(b1) * Math.cos(b2);
        double t2 = Math.cos( a1) * Math.sin(a2) * Math.cos(b1) * Math.sin(b2);
        double t3 = Math.sin( a1) * Math.sin(b1);
        double tt = Math.acos(t1 + t2 + t3);

       return 6366000*tt;

【讨论】:

【参考方案2】:

Location.distanceTo(LOcation) 的文档说:

返回此位置与该位置之间的大致距离(以米为单位) 给定的位置。距离是使用 WGS84 椭球定义的。

所以你可以试试这个方法:

public static float distanceBetween (double currentLat2, double currentLong2, double mallLat2, double mallLong2) 
        Location loc1 = new Location("");
        loc1.setLatitude(currentLat2);
        loc1.setLongitude(currentLong2);

        Location loc2 = new Location("");
        loc2.setLatitude(mallLat2);
        loc2.setLongitude(mallLong2);

        return loc1.distanceTo(loc2);

【讨论】:

【参考方案3】:

您可以记录 t1、t2、t3 的输出吗?我感觉Math.acos() 的参数超出了范围。也不确定为什么当您可以使用 Math.sinMath.cos 时,您会不必要地强制转换为浮动并返回双倍。

编辑

使用 Math.PI 而不是 3.14169。这个近似值导致了您的错误。

【讨论】:

以下是详细信息:t1:0.043878812342882156 t2:0.0023341665510088205 t3:0.9537870287895203 dist:NaN 这些加起来是 1.0000000076834112765,所以当域为 [-1, 1] 时,您将大于 1 的数字传递给 Math.acos。请参阅上面的编辑。

以上是关于Nan在使用纬度和经度计算距离的主要内容,如果未能解决你的问题,请参考以下文章

我需要使用现有的纬度/经度、距离和方向来计算纬度/经度

经纬度之间的最小距离

如何在php中计算纬度/经度的距离?

如何使用它们的经度和纬度值计算两个位置之间的距离

纬度/经度计算的总和指定地图距离吗?

计算两个纬度/经度点之间的距离不一致