4

I'm trying to get the distance between two points with JTS. The problem is that this function with JTS

new Coordinate(Lon1,Lat1).distance(new Coordinate(Lon2,Lat2))

Is giving a different result from this function used in postgis(wich provides the good distance)

ST_Distance_Sphere(point1,point2)
1

4 Answers 4

8

The short answer is you can't do that unless your points are very close together and you want the answer in degrees. JTS knows nothing about units or the curvature of the earth. So you need to pull in some GeoTools jars that do know about such things. Then you can create a method like:

private void calculateDistance(CoordinateReferenceSystem crs, Point[] points) {
    if (crs == null) {
        crs = default_crs;
    }

    double distance = 0.0;
    try {
        distance = JTS.orthodromicDistance(
            points[0].getCoordinate(),
            points[1].getCoordinate(),
            crs
        );
    } catch (TransformException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Measure<Double, Length> dist = Measure.valueOf(distance, SI.METER);
    System.out.println(dist.doubleValue(SI.KILOMETER) + " Km");
    System.out.println(dist.doubleValue(NonSI.MILE) + " miles");
}

Which will take care of all the hard maths for you. The full example program can be seen here.

4

You could use the Java implementation of GeographicLib to solve the inverse geodesic problem on WGS84.

import net.sf.geographiclib.*;

...

    private double calculateDistance(
            double lon1, double lat1, double lon2, double lat2) {
        GeodesicData g = Geodesic.WGS84.Inverse(lat1, lon1, lat2, lon2);
        return g.s12;  // distance in metres
    }

The length of the geodesic, which represents the shortest distance in metres between the two points, is in g.s12.

2
  • 1
    Note that GeoTools is using the same library under the hood
    – Ian Turton
    Commented Feb 9, 2018 at 15:00
  • Thanks for the note @IanTurton, I was debating if I should pull in all of GeoTools just for this or if I could just use this smaller lib instead.
    – carusot42
    Commented Nov 22, 2019 at 17:07
1

In case anyone wants a Scala implementation using GeographicLib and JTS points:

Add to build.sbt

libraryDependencies += "net.sf.geographiclib" % "GeographicLib-Java" % "1.50"

Distance.scala

import net.sf.geographiclib.Geodesic

object Distance {
  def calculateDistance(pt1: Point, pt2: Point): Double = {
     Geodesic.WGS84.Inverse(pt1.getY, pt1.getX, pt2.getY, pt2.getX).s12
  }
}
0

Like the others already said, JTS does know nothing about geodesy or projections or coordinate systems. JTS does "linear geometry on the 2-dimensional Cartesian plane" (http://tsusiatsoftware.net/jts/main.html).

If you do not want to pull in another library and if the strict mathematical solution on a sphere is enough, you can simply implement the haversine formula in your code. It is very straight-forward (even if Wikipedia makes it look complicated if you are not used to mathematical formulas like me): https://en.wikipedia.org/wiki/Haversine_formula & http://rosettacode.org/wiki/Haversine_formula#Java

The earth is not a sphere though, so if you need high accuracy you probably don't want to do this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.