javagpsgeotools

Do GPS operation for lat/long with geotools


First I'm a newbie in GPS system. I have GPS coordinates in WGS-84 receive from a basic GPS in USB. I want to calculate the distance beetween this two point. But I want the plane distances. So I have first to convert this coordinates to an other CRS example "EPSG:2154" for Lambert 93. And after calulate the distance. I try to use Geotools but the examples in the docs are not releveant for me and I d'ont understand how to do this. I thought first I have to found the matching transform like this :

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

But after reading docs it seems the transformation works for x,y coordinates not lat/long. And i do not understand how to use the MathTransform as it doesn't accept point with lat/long. I also try the example below but executing the code doesn't give the same results for me.

Calculating distance between two points, using latitude longitude?

So if anyone with good knowledge in GPS and Geotools is able to help me.

Thanks


Solution

  • If you simply want the distance between two GPS points then you can use the GeodeticCalculator to calculate this in metres (and the Units library to convert it to any distance unit you like:

    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");
      }
    }
    

    This will work for any points on the globe no matter how far apart they are and makes use of GeographicLib by Charles F. F. Karney and gives an accuracy of nanometres.

    If however, you want to carry out more geometry operations on your points/lines etc then you are right to want to transform your points to a projected CRS (such as 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);