6

I need to find distance in meters between some point with given latitude and longitude and line (on Earth) defined by several points with lat/lon coordinates.

I read these questions:

In the second it is said that this is impossible with JTS and author decided to use some other utility.

If so, could you recommend any other java library for such problems?

In first, code in the accepted answer doesn't work for me, may be because of that I don't understand which transformation I should choose (and point can be on a big distance from the line, so the transformation may produce not accurate results).

My code for testing code from the first question:

GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
    Point spb = geometryFactory.createPoint(new Coordinate(30.3, 59.95));
    Point msk = geometryFactory.createPoint(new Coordinate(37.6167, 55.75));
    Point khabarovsk = geometryFactory.createPoint(new Coordinate(135.0667, 48.4833));

    Point syktyvkar = geometryFactory.createPoint(new Coordinate(50.8167, 61.6667));

    Coordinate[] coords = new Coordinate[] {
            spb.getCoordinate(),
            msk.getCoordinate(),
            khabarovsk.getCoordinate()
    };

    LineString route = geometryFactory.createLineString(coords);
    System.out.println(route.distance(syktyvkar)); //result: 6.881897419667442

    try {
        CoordinateReferenceSystem auto = CRS.decode("AUTO:42001,13.45,52.3");
        MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84,
                auto);
        Geometry g3 = JTS.transform(route, transform);
        Geometry g4 = JTS.transform(syktyvkar, transform);
        System.out.println(g3.distance(g4)); //result: 619842.1091396079
    }
    catch(Exception e) {}
}

The result must be quite close to 170 000 meters.

6
  • in Second I said that relying on JTS wouldn't work. Did you actually try the code from the first question? It automatically chooses the transformation.
    – Ian Turton
    Commented Jan 28, 2015 at 14:59
  • right, I'm sorry. Do you know solution for geotools?
    – Lia
    Commented Jan 28, 2015 at 15:02
  • yes, I tried the code from the first question but got wrong results.
    – Lia
    Commented Jan 28, 2015 at 15:05
  • did you try changing CoordinateReferenceSystem auto = CRS.decode("AUTO:42001,13.45,52.3"); to be "near" your lines?
    – Ian Turton
    Commented Jan 28, 2015 at 15:16
  • I tried change it to CRS.decode("AUTO:42001,30.3,52.3"), the result was 49088.1638350715, which is also wrong. Besides, the line can be random and with big distances between points, so I don't know which transform can be appropriate at different moment of time.
    – Lia
    Commented Jan 28, 2015 at 15:21

1 Answer 1

2

The code from the previous question does in fact solve this problem once you have explored the issue a bit.

Basically your line doesn't have enough points so it "cuts" the corner across the more localised projection that is used to allow JTS to proceed as if the Earth is flat. This needs one additional line of code:

route = (LineString) Densifier.densify(route, .01);

enter image description here

The brown line is your original 3 point line and the blue line is a densified line (that has points added so it projects properly), shown in a local projection (EPSG:2470). As you can see the distance to the brown line to the point is much shorter than it should be.

So here is some suitably modified code:

public double getDistance(Point point, LineString line) {
double dist = -1.0;
try {
  String code = "AUTO:42001," + point.getX() + "," + point.getY();
  CoordinateReferenceSystem auto = CRS.decode(code);
  // auto = CRS.decode("epsg:2470");
  MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);
  Geometry g3 = JTS.transform(line, transform);
  Geometry g4 = JTS.transform(point, transform);

  Coordinate[] c = DistanceOp.nearestPoints(g4, g3);

  Coordinate c1 = new Coordinate();
  //System.out.println(c[1].distance(g4.getCoordinate()));
  JTS.transform(c[1], c1, transform.inverse());
  //System.out.println(geometryFactory.createPoint(c1));
  dist = JTS.orthodromicDistance(point.getCoordinate(), c1, DefaultGeographicCRS.WGS84);
} catch (Exception e) {
  e.printStackTrace();
}
return dist;

}

And incase you are wondering about the difference between the "flat distance" (c[1].distance(g4.getCoordinate())) is 760.731km and the "curved distance" (JTS.orthodromicDistance(point.getCoordinate(), c1, DefaultGeographicCRS.WGS84);) is 760.980km. For reference the distance tool in QGIS gives 760.919 km.

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.