在 Java 与 Javascript 之间计算距离

Posted

技术标签:

【中文标题】在 Java 与 Javascript 之间计算距离【英文标题】:computeDistanceBetween Java vs Javascript 【发布时间】:2018-06-05 09:47:43 【问题描述】:

所以我在 javascript 中使用 google.maps.geometry.spherical.computeDistanceBetween,在 Java 中使用 SphericalUtil 中的 computeDistanceBetween。

https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/SphericalUtil.java

对于相同的位置,我得到不同的距离。我可以做些什么来将它们校准为相同,或者我可以使用两个库在前端(Javascript)和后端(Java)中获得相似的结果吗?

以下是一些值和示例:

在 Javascript 中:

var from = new google.maps.LatLng(33.44138, -111.97500000000002);
var to = new google.maps.LatLng(33.505904166596224, -112.09470748901367);
var distanceBetween = google.maps.geometry.spherical.computeDistanceBetween(from, to);
console.log(distanceBetween);

在 Java 中:

LatLng from = new LatLng(Float.parseFloat("33.44138"), Float.parseFloat("-111.97500000000002"));
LatLng to = new LatLng(Float.parseFloat("33.505904166596224"), Float.parseFloat("-112.09470748901367"));
double distanceBetween = SphericalUtil.computeDistanceBetween(from, to);
System.out.println(distanceBetween);

在 Java 中使用 Double 而不是 Float:

LatLng from = new LatLng(Double.parseDouble("33.44138"), Double.parseDouble("-111.97500000000002"));
LatLng to = new LatLng(Double.parseDouble("33.505904166596224"), Double.parseDouble("-112.09470748901367"));
double distanceBetween = SphericalUtil.computeDistanceBetween(from, to);
System.out.println(distanceBetween);

Javascript 值为:13234.355969270651 Java(浮点)值为:13219.474110913057 Java(双精度)值为:13219.565680296535

谢谢!

【问题讨论】:

不同的浮点指针精度类型? 嘿,你是阿米尔,不是罗伯特!请发布您的代码和结果以进行比较。 好的,我会添加示例。 好的,我添加了一个例子。您现在可以看到输出之间存在差异。谢谢! 这可能是地球底层模型的差异。 Google 可能使用扁球体,而 Java 模型似乎使用球形模型 - 但我无法证实这一点。你可以在edwilliams.org/gccalc.htm查看一堆模型。 【参考方案1】:

查看文档以了解所使用的地球半径值。

尝试使用此代码将结果与其他 2 个进行比较。

Tier3Toolbox.EARTH_RADIUS = 6378137; /* Equitorial Radius instead of 6371000 */
Tier3Toolbox.toRad = 
    function (num) 
        return num * Math.PI / 180;
    ;  
Tier3Toolbox.calculateDistance =
    function(lat1, lon1, lat2, lon2)
        var dLat = this.toRad(lat2 - lat1);
        var dLon = this.toRad(lon2 - lon1);
        var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(this.toRad(lat1)) * 
                Math.cos(this.toRad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
        var distance = this.EARTH_RADIUS * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return distance;
    

【讨论】:

相同的代码但使用 6378137 作为半径而不是 6371000 让我更接近。 Java 结果现在是 13234.264297438078。所以看起来谷歌地图的javascript代码在幕后使用了赤道半径。感谢您的建议!【参考方案2】:

Javascript 在浮点数中有52 significant bits,它是浮点数的~15 位有效数字。 Java 的浮点数只有 24 位精度。请记住,距离公式包含减法。如果你减去两个足够接近的非精确值,你会得到一个巨大的错误。

尝试将Float改为DoubleDouble.parseDouble()

【讨论】:

所以我根据您的建议在 Java 端尝试了 Double。该值与 Float Java 值略有不同,但仍有大约 5 米的差异(将示例和值放在原始帖子中)。 这是一个了不起的问题。 真是令人沮丧! :P

以上是关于在 Java 与 Javascript 之间计算距离的主要内容,如果未能解决你的问题,请参考以下文章

倒计时

使用距位置的距离有效地计算最近的 5 个位置

单台计算机上的 java 应用程序和 javascript 应用程序之间的高性能通信 [关闭]

前端之JavaScript

iOS中文行间距富文本高度与显示那些坑

盒模型