使用 geotools 为 lat/long 进行 GPS 操作

Do GPS operation for lat/long with geotools

首先我是GPS系统的新手。 我从 USB 中的基本 GPS 接收 WGS-84 中的 GPS 坐标。 我想计算这两点之间的距离。 但我想要平面距离。所以我必须首先将此坐标转换为 Lambert 93 的另一个 CRS 示例“EPSG:2154”。然后计算距离。 我尝试使用 Geotools,但文档中的示例与我无关,我不明白如何执行此操作。 我想首先我必须找到这样的匹配转换:

DefaultGeographicCRS crs = DefaultGeographicCRS.WGS84;
    //EPSG:2154 RGF93 / Lambert-93 (Google it)
    CoordinateReferenceSystem crs2 = CRS.decode("EPSG:2154");
    MathTransform transform = CRS.findMathTransform(crs, crs2);

但在阅读文档后,似乎转换适用于 x,y 坐标而不是 lat/long。而且我不明白如何使用 MathTransform,因为它不接受带 lat/long 的点。我也尝试了下面的示例,但执行代码并没有给我相同的结果。

Calculating distance between two points, using latitude longitude?

因此,如果任何精通 GPS 和 Geotools 的人能够帮助我。

谢谢

如果您只是想知道两个 GPS 点之间的距离,那么您可以使用 GeodeticCalculator 以米为单位进行计算(并使用单位库将其转换为您喜欢的任何距离单位:

import javax.measure.MetricPrefix;
import javax.measure.Quantity;
import javax.measure.quantity.Length;

import org.geotools.referencing.CRS;
import org.geotools.referencing.CRS.AxisOrder;
import org.geotools.referencing.GeodeticCalculator;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;

import si.uom.SI;
import systems.uom.common.USCustomary;
import tech.units.indriya.quantity.Quantities;

public class OrthodromicDistance2 {
  /**
   * take two pairs of lat/long and return bearing and distance.
   * 
   * @param args
   */
  public static void main(String[] args) {
    DefaultGeographicCRS crs = DefaultGeographicCRS.WGS84;
    if (args.length != 4) {
      System.err.println("Need 4 numbers lat_1 lon_1 lat_2 lon_2");
      return;
    }
    GeometryFactory geomFactory = new GeometryFactory();
    Point[] points = new Point[2];
    for (int i = 0, k = 0; i < 2; i++, k += 2) {
      double x = Double.parseDouble(args[k]);
      double y = Double.parseDouble(args[k + 1]);
      if (CRS.getAxisOrder(crs).equals(AxisOrder.NORTH_EAST)) {
        System.out.println("working with a lat/lon crs");
        points[i] = geomFactory.createPoint(new Coordinate(x, y));
      } else {
        System.out.println("working with a lon/lat crs");
        points[i] = geomFactory.createPoint(new Coordinate(y, x));
      }

    }
    System.out.println(points[0]);
    System.out.println(points[1]);
    double distance = 0.0;

    GeodeticCalculator calc = new GeodeticCalculator(crs);
    calc.setStartingGeographicPoint(points[0].getX(), points[0].getY());
    calc.setDestinationGeographicPoint(points[1].getX(), points[1].getY());

    distance = calc.getOrthodromicDistance();
    double bearing = calc.getAzimuth();

    Quantity<Length> dist = Quantities.getQuantity(distance, SI.METRE);
    System.out.println(dist.to(MetricPrefix.KILO(SI.METRE)).getValue() + " Km");
    System.out.println(dist.to(USCustomary.MILE).getValue() + " miles");
    System.out.println("Bearing " + bearing + " degrees");
  }
}

这适用于地球上的任何点,无论它们相距多远,并且利用了 Charles F. F. Karney 的 GeographicLib 并给出了纳米级的精度。

但是,如果您想对 points/lines 等执行更多几何操作,那么您希望将您的点转换为投影 CRS(例如 Lambert 93)是正确的:

CoordinateReferenceSystem wgs84= CRS.decode("EPSG:4326", true);
CoordinateReferenceSystem lambert = CRS.decode("EPSG:2154", true);
MathTransform toMeters= CRS.findMathTransform(wgs84, lambert);

Geometry output1 = JTS.transform(input1, toMeters);
Geometry output2 = JTS.transform(input2, toMeters);
double distance = output1.distance(output2);