使用 GeoTools 计算两点之间的大距离

Nik*_*kar 1 gis geotools

GeoTools 和 GIS 新手,我正在尝试使用 GeoTools 库计算孟买和德班之间的距离。我正在接近小距离的准确结果,但当我进行较大距离时,计算结果偏离了 2000 公里,我不完全理解 CRS 系统。下面是我计算孟买和德班之间距离的代码

    Coordinate source = new Coordinate(19.0760, 72.8777);   ///Mumbai Lat Long
    Coordinate destination1 = new Coordinate(-29.883333, 31.049999); //Durban Lat Long

    GeometryFactory geometryFactory = new GeometryFactory();
    Geometry point1 = geometryFactory.createPoint(source);
    Geometry point2 = geometryFactory.createPoint(destination1);

    CoordinateReferenceSystem auto = auto = CRS.decode("AUTO:42001,13.45,52.3");
    MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);

    Geometry g3 = JTS.transform(point1, transform);
    Geometry g4 = JTS.transform(point2, transform);

    double distance = g3.distance(g4);
Run Code Online (Sandbox Code Playgroud)

Ian*_*ton 8

当您从 stackexchange问题中盲目复制代码而不阅读其所基于的问题来解释原因时,就会发生这种情况。

\n\n

我每次回答这个问题(并发布类似的代码)时,提问者都试图使用以度为单位的纬度/经度坐标来测量以米为单位的短距离。您问题中显示的技巧会创建一个自动 UTM 投影,以“AUTO:42001”位(在您的情况下为 52N 13E)之后指定的位置为中心 - 这需要是您感兴趣的区域的中心,因此在您的无论如何,这些值可能是错误的。

\n\n

但是您对孟买到德班的一个小区域不感兴趣,这是绕地球的一条重要路线,因此您需要考虑到地球表面的曲率。此外,您也不会尝试做一些困难的事情,而 JTS 是唯一的进程来源(例如缓冲)。在这种情况下,您应该使用GeodeticCalculatorCFF Karney, Algorithms for geodesics, J. Geodesy 87, 43\xe2\x80\x9355 (2013) 中的库来考虑地球的形状。

\n\n

无论如何,足够的解释将来没有人会读,这里是代码:

\n\n
  public static void main(String[] args) {\n    DefaultGeographicCRS crs = DefaultGeographicCRS.WGS84;\n    if (args.length != 4) {\n      System.err.println("Need 4 numbers lat_1 lon_1 lat_2 lon_2");\n      return;\n    }\n    GeometryFactory geomFactory = new GeometryFactory();\n    Point[] points = new Point[2];\n    for (int i = 0, k = 0; i < 2; i++, k += 2) {\n      double x = Double.valueOf(args[k]);\n      double y = Double.valueOf(args[k + 1]);\n      if (CRS.getAxisOrder(crs).equals(AxisOrder.NORTH_EAST)) {\n        System.out.println("working with a lat/lon crs");\n        points[i] = geomFactory.createPoint(new Coordinate(x, y));\n      } else {\n        System.out.println("working with a lon/lat crs");\n        points[i] = geomFactory.createPoint(new Coordinate(y, x));\n      }\n\n    }\n\n    double distance = 0.0;\n\n    GeodeticCalculator calc = new GeodeticCalculator(crs);\n    calc.setStartingGeographicPoint(points[0].getX(), points[0].getY());\n    calc.setDestinationGeographicPoint(points[1].getX(), points[1].getY());\n\n    distance = calc.getOrthodromicDistance();\n    double bearing = calc.getAzimuth();\n\n    Quantity<Length> dist = Quantities.getQuantity(distance, SI.METRE);\n    System.out.println(dist.to(MetricPrefix.KILO(SI.METRE)).getValue() + " Km");\n    System.out.println(dist.to(USCustomary.MILE).getValue() + " miles");\n    System.out.println("Bearing " + bearing + " degrees");\n  }\n
Run Code Online (Sandbox Code Playgroud)\n\n

给予:

\n\n
working with a lon/lat crs\nPOINT (72.8777 19.076)\nPOINT (31.049999 -29.883333)\n7032.866960793305 Km\n4370.020928274692 miles\nBearing -139.53428618565218 degrees\n
Run Code Online (Sandbox Code Playgroud)\n