Tengo una línea formada por 2 pares lat / lon, y el lat / lon de un punto. Me gustaría averiguar la distancia perpendicular entre la línea y el punto en la superficie de la Tierra (puede asumir la Tierra como gran esfera), y el vector perpendicular mínimo (es decir, el "punto de cruce" proyectado en la línea).
Estoy tratando de usar Geotools 8.0 y JTS para esto. A continuación capturó mi código de prueba:
//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.
//http://gis.stackexchange.com/a/29713/10772
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}));
}
los métodos createPoint () y createLine ():
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,
latitude));
return point;
}
Sin embargo, el resultado de "isOnLine ()" devuelve falso. Me preguntaba si hay algo mal.
¿Hay algún problema con mi método de verificación, o en realidad la forma en que solía averiguar la distancia perpendicular y el "punto de cruce" en la superficie de la Tierra no es correcta?

PrecisionModel.FIXED? No puedo comentar sobre el resto de su código, pero una precisión doble puede introducir errores. Consulte Robustez y precisión en las preguntas frecuentes de JTS.Respuestas:
Finalmente encontré una utilidad Java que hace el trabajo de inmediato
http://biodiversityinformatics.amnh.org/open_source/pdc/documentation.php
fuente
También hay una solución que utiliza la proyección gonomónica presentada por Charles Karnes en Algoritmos para geodésicas. Hay una implementación en Java disponible con la biblioteca Barefoot: https://github.com/bmwcarit/barefoot
Para obtener más detalles, consulte la respuesta aquí: https://gis.stackexchange.com/a/184695/29490
Funciona para proyecciones de punto a línea de gran distancia, pero también para cálculos de corta distancia (ver imágenes).
fuente