Saya memiliki garis yang dibentuk oleh 2 pasangan lat / lon, dan lat / lon suatu titik. Saya ingin mengetahui jarak tegak lurus antara garis dan titik pada permukaan bumi (dapat menganggap bumi sebagai bola besar), dan vektor tegak lurus minimum (yaitu "titik silang" yang diproyeksikan pada garis).
Saya mencoba menggunakan Geotools 8.0 dan JTS untuk ini. Di bawah ini diambil kode pengujian saya:
//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}));
}
metode createPoint () dan 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;
}
Namun, hasil "isOnLine ()" mengembalikan false. Saya bertanya-tanya apakah ada yang salah.
Apakah ada yang salah dengan metode verifikasi saya, atau sebenarnya cara yang saya gunakan untuk mengetahui jarak tegak lurus dan "titik silang" di permukaan bumi tidak benar?
PrecisionModel.FIXED
? Saya tidak dapat mengomentari sisa kode Anda, tetapi presisi ganda dapat menyebabkan kesalahan. Lihat Robustness & Precision di FAQ JTS.Jawaban:
Akhirnya saya menemukan utilitas java yang melakukan pekerjaan itu segera
http://biodiversityinformatics.amnh.org/open_source/pdc/documentation.php
sumber
Ada juga solusi menggunakan proyeksi Gonomonic yang disajikan oleh Charles Karnes dalam Algoritma untuk geodesik. Ada implementasi di Jawa yang tersedia dengan perpustakaan Barefoot: https://github.com/bmwcarit/barefoot
Untuk lebih jelasnya lihat jawabannya di sini: https://gis.stackexchange.com/a/184695/29490
Ini berfungsi untuk proyeksi jarak jauh ke garis besar tetapi juga perhitungan jarak dekat (lihat gambar).
sumber