如何计算路径上两点之间的距离

时间:2021-01-27 05:34:48

标签: java geolocation gis geospatial

我有一个代表路径的坐标列表,以及源和目标坐标。因此,使用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 的资源非常少。

3 个答案:

答案 0 :(得分:2)

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。最后将所有计算出的距离相加。

答案 1 :(得分:2)

如果你想要精确,那么你应该去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

答案 2 :(得分:1)

我在这里看到的其他回复都很好,@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 的更多信息。

相关问题