问题描述
我有一个代表路径的坐标列表,以及源和目标坐标。因此,使用spatial4j、JTS、GeoTools 或任何其他库如何计算预定路径(坐标列表)上两点(源和目标)之间的距离。
以下是我尝试使用 spatail4j 的示例,它是直线距离。但是,我们如何在路径上实现相同的事情,我使用了 spatial4j,但使用了不同的库,如 JTS、GeoTools 等,
public static void main(String[] args) {
SpatialContext ctx = SpatialContext.GEO;
Point p1= ctx.getShapeFactory().pointXY( 77.610099,12.91502);
Point p2= ctx.getShapeFactory().pointXY( 77.59038,12.917055);
System.out.println(ctx.getdistCalc().distance(p1,p2) * distanceUtils.DEG_TO_KM);
}
// output: 2.149124512680105
以下是路线/路径地理点:
12.91502,77.610099
12.91502,77.610092
12.913957,77.610069
12.913954,77.610033
12.91644,77.610048
12.916573,77.605512
12.916618,77.603053
12.916622,77.601803
12.916652,77.600092
12.916735,77.597653
12.916896,77.590946
12.916927,77.590242
12.916936,77.589467
12.917083,77.589466
12.917055,77.59038
根据谷歌地图,该值应为2.8Km
。是否有任何其他 java 库使用我们实现相同的东西,因为空间 4j 的资源非常少。
解决方法
public static void main(String[] args) {
ArrayList<Point> points = new ArrayList<>();
points.add(new Point(1,0));
points.add(new Point(2,0));
points.add(new Point(3,0));
int distance = 0;
for (int i = 1; i < points.size(); i++) {
Point smaller = points.get(i-1);
Point bigger = points.get(i);
distance += Math.sqrt(Math.pow(bigger.x-smaller.x,2)+Math.pow(bigger.y-smaller.y,2));
}
System.out.println(distance);
}
它可以这样工作。使用毕达哥拉斯计算点 1 和 2 之间的距离,然后是点 2 和 3。最后将所有计算出的距离相加。
,如果你想要精确,那么你应该去Haversine Formula,幸运的是,你总能找到一个有用的浏览网页的解决方案
public static Double getDistance(Double lat1,Double lon1,Double lat2,Double lon2) {
final int R = 6371; // Earth Radius in km,use 3959 if you want in miles
Double latDistance = toRad(lat2-lat1);
Double lonDistance = toRad(lon2-lon1);
Double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) +
Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *
Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
Double c = 2 * Math.atan2(Math.sqrt(a),Math.sqrt(1-a));
return R * c;
}
我实际上只是根据您的用例调整了 this。
,我在这里看到的其他回复都很好,@Luiz's 简单明了,而 @8bit's 更准确。
无论您选择哪种实现方式(甚至您在问题本身 ctx.getDistCalc().distance
中提供的实现方式),我都想深入了解您似乎最苦恼的问题:如何在整个列表上应用和累积距离函数的结果?
IntStream.range(0,path.length)
.map(i -> i == 0
? 0.0d
: ctx.getDistCalc().distance(path[i - 1],path[i]))
.sum()
* DistanceUtils.DEG_TO_KM;
这假设 path
是一个包含您的点的数组。
有关流 here 的更多信息。