PostGISで2本の線が交差する角度を計算する方法は?


19

PostGISで交差する2つの線の間の角度を計算します。

PostGISでの角度計算の開始点はST_Azimuthのようですが、それは入力として点を取ります。最初に考えたのは、交差する線の終点を取得し、それらの方位角計算を実行することでした。ほとんどのラインフィーチャが直線ではないため、これでは十分ではありません。交差点の角度に興味があります。だから私が思いついたのは、次の手順を実行するネストされた操作です:

  1. 2つのラインフィーチャテーブル間のすべての交点を特定します。
  2. 交差点の周りに非常に小さなバッファーを作成します
  3. ラインフィーチャがバッファの外部と交差するポイントを特定します(複数ある場合は最初のポイントを取得します-角度が0、90、または180度に近いかどうかにのみ関心があります)
  4. これらの2つのポイントのST_Azimuthを計算します。

完全なSQLはここに投稿するのに少し時間がかかりますが、興味があるならここでそれを説明しました。(ところで、WITHステートメントを下るすべてのフィールドを引き継ぐよりも良い方法はありますか?)

結果は正しく見えないので、明らかに何か間違ったことをしています:

出力例1 出力例2

編集私はEPSG:3785で計算をやり直しましたが、結果は少し異なりますが、まだ正しくありません:

3785#1の出力 3785#2の出力

私の質問は、このプロセスのどこに欠陥があるのか​​です。ST_Azimuthの機能を誤解していますか?CRSの問題はありますか?他に何かありますか?それとも、もっと簡単な方法がありますか?


1
元のCRSは何でしたか?角度の計算は、投影されていない緯度/経度(SRID = 4326)ではなく、正角投影で行う必要があります。
マイクT

元々はEPSG:4326座標でしたが、すべての処理が同じCRSで行われることを100%保証するために、ST_Translateを含めました。等角投影を試みます、ありがとう。
mvexel

EPSG:3785の計算をやり直し、違いが生じます-新しい結果を表示するために質問を修正します-しかし、結果は実際の角度を反映していません。
mvexel

回答:


12

ひらめきがありました。むしろありふれたものです。PostGISが正しい角度を計算するために不可欠な情報を1つ省略していました。

私が計算していたのは、小さなバッファの外部と交差する2つのポイント間の角度だけでした。交差の角度を計算するには、バッファー外部の両方のポイントと2つのラインフィーチャの交差ポイントの間の両方の角度を計算し、それらを減算する必要があります。

完全なSQLを更新しましたが、ここに顕著なビットがあります:

SELECT
    ...
    abs
    (
        round
        (
            degrees
            (
            ST_Azimuth
            (
                points.point2,
                points.intersection
            )
            -
            ST_Azimuth
            (
                points.point1,
                points.intersection
            )
        )::decimal % 180.0
        ,2
    )
)
AS angle
...
FROM
points 

1
私は、インスタセクションに対する緩衝ポイントの角度について考えていましたが、詳細に説明する時間はありません。別の側面は角度単位です。結果を度単位で取得するには、ST_Azimuthからのラジアン単位の結果に180.0 / pi()を掛ける必要があります。
マイクT

うん、ありがとう、私はそのためにPostgreSQLのdegrees()関数を使用しています。
mvexel

包丁。(これまで度関数があることすら知りませんでした。)このすべてのロジックを関数呼び出しでラップするのはいいことですが、どのように機能するかを概念化するのは困難ST_IntersectionAngle(...です。
マイクT

実際に、PostGIS関数ではないことに驚きました。これについてご意見をお寄せいただきありがとうございます。
mvexel

2

私は最近同じことを計算しなければなりませんでしたが、よりシンプルで、おそらくより高速なアプローチを決定しました。

方位計算のための余分なポイントを見つけるには、私は(それは非常に行の先頭に起こることはまれ場合または後)交差点の後ろの長さのpermyriadを確認し使用してST_Line_Locate_PointST_Line_Interpolate_Pointを

abs(degrees( 
  ST_Azimuth (
    intersection, 
    ST_Line_Interpolate_Point(
      line1, 
      abs(ST_Line_Locate_Point(line1, intersection) - 0.0001)
    )
  )
  -
  ST_Azimuth (
    intersection, 
    ST_Line_Interpolate_Point(
      line2, 
      abs(ST_Line_Locate_Point(line2, intersection) - 0.0001)
    )
  )
))

無数は任意であり、より一貫した結果を得るには、絶対オフセットを使用した方が良いでしょう。たとえば、事前に20mを確認するには20/ST_Length(line1)20/ST_Length(line2)それぞれに0.0001を変更します。

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