Tìm khoảng cách vuông góc và vectơ vuông góc tối thiểu giữa Điểm và Đường bằng GeoTools và JTS?


8

Tôi có một dòng được hình thành bởi 2 cặp lat / lon và lat / lon của một điểm. Tôi muốn tìm ra khoảng cách vuông góc giữa đường thẳng và điểm trên bề mặt Trái đất (có thể giả sử Trái đất là hình cầu lớn) và vectơ vuông góc tối thiểu (nghĩa là "điểm chéo" được chiếu trên đường thẳng).

Tôi đang cố gắng sử dụng Geotools 8.0 và JTS cho việc này. Dưới đây đã bắt được mã thử nghiệm của tôi:

    //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}));
    }

các phương thức createPoint () và createdLine ():

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;
}

Tuy nhiên, kết quả của "isOnLine ()" trả về sai. Tôi đã tự hỏi nếu có bất cứ điều gì sai.

Có điều gì đó không đúng với phương pháp xác minh của tôi, hoặc thực tế là cách tôi đã sử dụng để tìm ra khoảng cách vuông góc và "điểm chéo" trên bề mặt Trái đất là không chính xác?


Bạn đã thử sử dụng PrecisionModel.FIXED? Tôi không thể nhận xét về phần còn lại của mã của bạn, nhưng độ chính xác kép có thể gây ra lỗi. Xem Độ mạnh & Chính xác trong Câu hỏi thường gặp của JTS.
hepiladron

@hepiladron, Cảm ơn lời đề nghị của bạn. Đã thử sử dụng PrecisionModel.FIXED nhưng vẫn nhận được kết quả tương tự ...
xlogger

Đối với những độc giả tương lai - điều này khó có thể phù hợp với bạn vì JTS giả định khuôn khổ Cartesian và hoàn toàn không xử lý hình học hình cầu.
Ian Turton

Câu trả lời:



3

Ngoài ra còn có một giải pháp sử dụng phép chiếu Gonomonic do Charles Karnes trình bày trong Thuật toán cho trắc địa. Có một triển khai trong Java có sẵn với thư viện Barefoot: 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);

Để biết thêm chi tiết, xem câu trả lời tại đây: https://gis.stackexchange.com/a/184695/29490

Nó hoạt động cho các khoảng cách lớn đến các phép chiếu đường thẳng nhưng cũng tính toán khoảng cách gần (xem hình ảnh).

nhập mô tả liên kết ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.