【问题标题】:How to calculate distance between two point over a path如何计算路径上两点之间的距离
【发布时间】:2021-04-30 22:48:36
【问题描述】:

我有一个代表路径的坐标列表,以及源和目标坐标。因此,使用 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 库可以用来实现相同的目标,因为 spatial4j 的资源非常少。

【问题讨论】:

  • 不就是把所有路径段的距离相加吗?
  • 是的,但首先我们必须检查源和目的地是否位于路径上,如果位于则我们必须计算源和目的地之间的距离。但不确定如何使用 spatial4j 来做到这一点。
  • 看看这个 - 一个现成的库现在可用,你可以使用它。 stackoverflow.com/a/57482299/1486762
  • @BilboBaggins 但这会计算两点之间的距离,我的要求是计算预定义路径(经度集)上的距离。

标签: java geolocation gis geospatial


【解决方案1】:

如果你想要精确,那么你应该去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】:
    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。最后将所有计算出的距离相加。

    【讨论】:

      【解决方案3】:

      我在这里看到的其他回复都不错,@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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-14
        • 1970-01-01
        • 2022-01-08
        • 1970-01-01
        • 2010-10-30
        • 1970-01-01
        相关资源
        最近更新 更多