I have a line formed by 2 lat/lon pairs, and the lat/lon of a point. I would like to find out the perpendicular distance between the line and the point on the Earth surface (can assume Earth as great sphere), and the minimum perpendicular vector (i.e. the projected "cross point" on the line).

I am trying to use Geotools 8.0 and JTS for this. Below captured my testing code:

    //Coordinates in lon, lat
    Coordinate linePt1 = new Coordinate(-5.71472, 50.06639);
    Coordinate linePt2 = new Coordinate(-3.07000, 58.64389);

    //Multiply all longitudes by the cosine of latitude.
    linePt1.x = linePt1.x * Math.cos(linePt1.y);
    linePt2.x = linePt2.x * Math.cos(linePt2.y);

    LineString line = createLine(new Coordinate[]{linePt1, linePt2});

    Coordinate pt1 = new Coordinate(-6, 54);
    pt1.x = pt1.x * Math.cos(pt1.y);
    Point point = createPoint(pt1.x, pt1.y);

    double distanceOp = DistanceOp.distance(line, point);
    System.out.println("Distance = " + distanceOp);

    //Find the minimum perpendicular vector using "closestPoints()"
    for (Coordinate c : DistanceOp.closestPoints(line, point)) {
        System.out.println("=== " + c);
        //verify if the point is on the line
        System.out.println(CGAlgorithms.isOnLine(c, new Coordinate[]{linePt1, linePt2}));

the createPoint() and createLine() methods:

public static LineString createLine(Coordinate[] coordinates){
    GeometryFactory factory = new GeometryFactory(new PrecisionModel(
            PrecisionModel.FLOATING), WGS84_SRID);
    LineString line = (LineString) factory.createLineString(coordinates);
    return line;

public static Point createPoint(double longitude, double latitude) {
    if (longitude < -180 || longitude > 180) {
        throw new IllegalArgumentException(
                "Longitude should be between -180 and 180");
    if (latitude < -90 || latitude > 90) {
        throw new IllegalArgumentException(
                "latitude should be between -90 and 90");
    GeometryFactory factory = new GeometryFactory(new PrecisionModel(
            PrecisionModel.FLOATING), WGS84_SRID);
    Point point = (Point) factory.createPoint(new Coordinate(longitude,
    return point;

However, the result of "isOnLine()" return false. I was wondering if there is anything wrong.

Is there something wrong with my verification method, or actually the way I used to find out the perpendicular distance and the "cross point" on the Earth surface is not correct?

  • Have you tried using PrecisionModel.FIXED? I can't comment on the rest of your code, but a double precision can introduce errors. See Robustness & Precision in the JTS FAQ.
    – hepiladron
    Oct 6, 2012 at 19:42
  • @hepiladron, Thanks for your suggestion. Tried using PrecisionModel.FIXED but still got the same result...
    – xlogger
    Oct 7, 2012 at 9:13
  • For future readers - this is unlikely to work out for you as JTS assumes a Cartesian framework and doesn't handle spherical geometry at all.
    – Ian Turton
    Jan 2, 2013 at 10:49

2 Answers 2


Finally I found a java utility that do the job right away



There's also a solution using Gonomonic projection presented by Charles Karnes in Algorithms for geodesics. There is an implementation in Java available with Barefoot library: https://github.com/bmwcarit/barefoot

SpatialOperator spatial = new Geography();

Point reykjavik = new Point(-21.933333, 64.15);
Point moskva = new Point(37.616667, 55.75);
Point berlin = new Point(13.408056, 52.518611);

double f = spatial.intercept(reykjavik, moskva, berlin);
Point interception = spatial.interpolate(reykjavik, moskva, f);

For more details see the answer here: https://gis.stackexchange.com/a/184695/29490

It works for large distance point to line projections but also close distance calculations (see images).

enter link description here

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.