Eu tenho uma linha formada por 2 pares lat / lon e lat / lon de um ponto. Gostaria de descobrir a distância perpendicular entre a linha e o ponto na superfície da Terra (pode assumir a Terra como grande esfera) e o vetor perpendicular mínimo (ou seja, o "ponto cruzado" projetado na linha).
Estou tentando usar o Geotools 8.0 e o JTS para isso. Abaixo capturou meu código de teste:
//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}));
}
os métodos createPoint () e 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;
}
No entanto, o resultado de "isOnLine ()" retorna falso. Eu queria saber se há algo errado.
Existe algo errado com o meu método de verificação ou, na verdade, a maneira como eu costumava descobrir a distância perpendicular e o "ponto de cruzamento" na superfície da Terra não está correta?
PrecisionModel.FIXED
? Não posso comentar o restante do seu código, mas uma precisão dupla pode introduzir erros. Consulte Robustez e precisão nas perguntas frequentes do JTS.Respostas:
Finalmente encontrei um utilitário java que faz o trabalho imediatamente
http://biodiversityinformatics.amnh.org/open_source/pdc/documentation.php
fonte
Há também uma solução usando projeção Gonomonic apresentada por Charles Karnes em Algoritmos para geodésica. Existe uma implementação em Java disponível na biblioteca Barefoot: https://github.com/bmwcarit/barefoot
Para obter mais detalhes, consulte a resposta aqui: https://gis.stackexchange.com/a/184695/29490
Ele funciona para projeções de grandes distâncias ponto a linha, mas também cálculos de distâncias próximas (veja imagens).
fonte