gpt4 book ai didi

java - 关于Spatial4J中距离计算的一个问题

转载 作者:行者123 更新时间:2023-12-05 04:26:00 24 4
gpt4 key购买 nike

我对距离计算很困惑。

我使用这个网站作为引用: https://www.omnicalculator.com/other/latitude-longitude-distance

然后我从这里得到了距离计算(haversine)的实现: https://tutorialspoint.dev/algorithm/geometric-algorithms/program-distance-two-points-earth

我想将其与 Spatial4J 的各种不同实现进行比较。

我正在使用这些坐标来测试:

Point 1: 40.688939, -74.04455
Point 2: 40.746853, -73.985633

我发现计算这两点之间距离的不同方法之间存在很大差异。

首先,我主要担心的是网站(omnicalculator)和 tutorialspoint 的实现在距离上完全一致:8.132 km

但我的 Spatial4J 计算没有一个与该数字一致。最接近它的是 CartesianDistCalc8.262 km 处的实现。 tutorialspoint 演示代码声称使用了 haversine,但 Spatial4J haversine DistCalc 实现的输出在 7.313 km 处相距甚远。

但是有人可以向我解释这些差异的来源以及“正确”差异是什么吗?

下面是我的实验代码:

import org.junit.jupiter.api.Test;
import org.locationtech.spatial4j.context.SpatialContext;
import org.locationtech.spatial4j.distance.CartesianDistCalc;
import org.locationtech.spatial4j.distance.GeodesicSphereDistCalc;

class GeodesicCalculationTest {
@Test
void testGeodesicCalculations(){
SpatialContext ctx = SpatialContext.GEO;

var startPoint = ctx.getShapeFactory().pointLatLon(40.688939, -74.04455);
var endPoint = ctx.getShapeFactory().pointLatLon(40.746853, -73.985633);

System.out.println("GEO spatial context: " + ctx.calcDistance(startPoint, endPoint) * 100);
System.out.println("Haversine: " + new GeodesicSphereDistCalc.Haversine().distance(startPoint, endPoint) * 100);
System.out.println("Law of cosine: " + new GeodesicSphereDistCalc.LawOfCosines().distance(startPoint, endPoint) * 100);
System.out.println("Vincenty: " + new GeodesicSphereDistCalc.Vincenty().distance(startPoint, endPoint) * 100);
System.out.println("Cartesian: " + new CartesianDistCalc().distance(startPoint, endPoint) * 100);
System.out.println("Tutorials Point (haversine): " + distance(startPoint.getLat(), endPoint.getLat(), startPoint.getLon(), endPoint.getLon()));
}

public static double distance(double lat1, double lat2, double lon1, double lon2) {
// The math module contains a function
// named toRadians which converts from
// degrees to radians.
lon1 = Math.toRadians(lon1);
lon2 = Math.toRadians(lon2);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);

// Haversine formula
double dlon = lon2 - lon1;
double dlat = lat2 - lat1;
double a = Math.pow(Math.sin(dlat / 2), 2)
+ Math.cos(lat1) * Math.cos(lat2)
* Math.pow(Math.sin(dlon / 2),2);

double c = 2 * Math.asin(Math.sqrt(a));

// Radius of earth in kilometers. Use 3956
// for miles
double r = 6371;

// calculate the result
return(c * r);
}
}

运行结果:

GEO spatial context:         7.31307025220976
Haversine: 7.31307025220976
Law of cosine: 7.313070251733588
Vincenty: 7.3130702522095286
Cartesian: 8.261503667613857
Tutorials Point (haversine): 8.131763102409689

我将 Spatial4J 计算乘以 100,这也让我感到困惑...Spatial4J 给我的答案是 1/100 公里真的没有意义吗???

我意识到我一定是做错了什么或者完全误解了这里的某些前提。如果能帮助我理解那是什么,我将不胜感激。

最佳答案

SpatialContext.calcDistance(Point p, Point p2) 的结果以度为单位。要将这些度数转换为公里,您需要将其乘以常量 DistanceUtils.DEG_TO_KM

SpatialContext ctx = SpatialContext.GEO;
var startPoint = ctx.getShapeFactory().pointLatLon(40.688939, -74.04455);
var endPoint = ctx.getShapeFactory().pointLatLon(40.746853, -73.985633);
double distanceInDegrees = ctx.calcDistance(startPoint, endPoint);
double distanceInKm = distanceInDegrees * DistanceUtils.DEG_TO_KM;
System.out.println("GEO spatial context: " + distanceInKm);

这给你输出:

GEO spatial context:         8.131774297975046

这与您的示例非常接近

Tutorials Point (haversine): 8.131763102409689

差异是因为 Spatial4j 使用值 6371.0087714 作为以公里为单位的地球半径,而在您的示例中您使用的是 6371

关于java - 关于Spatial4J中距离计算的一个问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73121732/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com