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)
PolyGeo
  • 65,136
  • 29
  • 109
  • 338
Khalil Aouachri
  • 43
  • 1
  • 1
  • 5

4 Answers4

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.

Ian Turton
  • 81,417
  • 6
  • 84
  • 185
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.

Mike T
  • 42,095
  • 10
  • 126
  • 187
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
  }
}
carusot42
  • 227
  • 1
  • 7
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.

bugmenot123
  • 11,011
  • 3
  • 34
  • 69