Ich habe eine Linie, die aus 2 Lat / Lon-Paaren und dem Lat / Lon eines Punktes besteht. Ich möchte den senkrechten Abstand zwischen der Linie und dem Punkt auf der Erdoberfläche (kann die Erde als große Kugel annehmen) und den minimalen senkrechten Vektor (dh den projizierten "Kreuzungspunkt" auf der Linie) herausfinden.
Ich versuche dafür Geotools 8.0 und JTS zu verwenden. Unten habe ich meinen Testcode erfasst:
//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}));
}
die Methoden createPoint () und 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;
}
Das Ergebnis von "isOnLine ()" gibt jedoch false zurück. Ich habe mich gefragt, ob etwas nicht stimmt.
Stimmt etwas mit meiner Überprüfungsmethode nicht oder stimmt die Art und Weise, wie ich den senkrechten Abstand und den "Kreuzungspunkt" auf der Erdoberfläche ermittelt habe, nicht?
PrecisionModel.FIXED
? Ich kann den Rest Ihres Codes nicht kommentieren, aber eine doppelte Genauigkeit kann zu Fehlern führen. Siehe Robustheit und Präzision in den JTS-FAQ.Antworten:
Schließlich fand ich ein Java-Dienstprogramm, das die Arbeit sofort erledigt
http://biodiversityinformatics.amnh.org/open_source/pdc/documentation.php
quelle
Es gibt auch eine Lösung mit der von Charles Karnes in Algorithmen für Geodäten vorgestellten gonomonischen Projektion. In der Barefoot-Bibliothek ist eine Implementierung in Java verfügbar: https://github.com/bmwcarit/barefoot
Weitere Informationen finden Sie in der Antwort hier: https://gis.stackexchange.com/a/184695/29490
Es funktioniert für Projektionen von Punkt zu Linie mit großer Entfernung, aber auch für Nahentfernungsberechnungen (siehe Bilder).
quelle