GeoToolsとJTSを使用して点と線の間の垂直距離と最小垂直ベクトルを見つけますか?


8

2つの緯度/経度のペアで構成される線と、ポイントの緯度/経度があります。線と地球表面上の点(地球を大球体と見なすことができる)との間の垂直距離、および最小垂直ベクトル(つまり、線上に投影された「クロスポイント」)を調べたいのですが。

私はこれにGeotools 8.0とJTSを使用しようとしています。以下は私のテストコードをキャプチャしました:

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

createPoint()および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;
}

ただし、「isOnLine()」の結果はfalseを返します。何か問題があるのか​​と思っていました。

私の検証方法に何か問題がありますか、または実際に私が垂直距離と地球表面の「クロスポイント」を見つけるために使用した方法が正しくありませんか?


使ってみましたPrecisionModel.FIXEDか?残りのコードについてはコメントできませんが、倍精度ではエラーが発生する可能性があります。JTS FAQのRobustness&Precisionを参照してください。
2012年

@hepiladron、ご提案ありがとうございます。PrecisionModel.FIXEDを使用して試したが、同じ結果が得られた...
xlogger

将来の読者のために-JTSがデカルトフレームワークを想定しており、球形ジオメトリをまったく処理しないため、これはうまくいかない可能性があります。
イアンTurton

回答:



3

測地線のアルゴリズムでCharles Karnesによって提示されたGonomonic投影を使用したソリューションもあります。Barefootライブラリで利用可能なJavaの実装があります: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);

詳細については、こちらの回答を参照してください:https : //gis.stackexchange.com/a/184695/29490

これは、遠距離のポイントからラインへの投影だけでなく、近距離の計算にも機能します(画像を参照)。

ここにリンクの説明を入力

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.