PostGIS:linestringの片側ST_Bufferが奇妙な出力を生成する

Aug 18 2020

以下の例では、ラインストリングのPostGISテーブル(黒と黄色)と片面のST_Buffer出力ポリゴン(赤)があります。バッファ距離は、ラインストリングテーブルに格納されている属性値に基づいています。

ご覧のとおり、バッファの1つが正しくなく、それ自体の一部を特定の量だけ切り取っています。なぜこれが起こったのですか?修正できますか?線ストリング部分が凹状になる問題のようです。

同様のクエリを使用して、これを自分で試してください。

SELECT ST_BUFFER('LineString (638327 331059, 638337 331048, 638337 331037, 638343 331023, 638358 331014, 638380 330991, 638382 330978, 638391 330966, 638410 330959, 638420 330953)',50,'side=right')

別の例では、これが発生しているのがわかります(黒い線は1つのフィーチャであり、バッファポリゴンも同様です)。

そしてこれでこれを試してください:

SELECT ST_BUFFER('LineString (600296 172961, 600304 172962, 600307 172965, 600307 172969, 600307 172971, 600309 172974, 600308 172976, 600307 172979, 600306 172981, 600307 172982, 600311 172980, 600313 172979, 600317 172979, 600321 172982, 600325 172982, 600327 172979, 600328 172976, 600331 172974, 600338 172974)',10,'side=right')

見知らぬ結果のためにバッファ距離を増やします。EPSG:どちらの場合も27700。

回答

7 dr_jts Aug 18 2020 at 05:53

これらは、片側バッファアルゴリズムの欠陥が原因で発生します(バグではなく、アルゴリズム設計の既知の制限です)。

これはGEOSの問題として記録されます。ただし、修正のためのETAはまだありません。

TheoF Aug 20 2020 at 01:04

この問題を修正する回避策パイプラインを作成しました。途中でいくつかの一時的な中間テーブルを作成する必要がありますが、その場でそれらを削除できます。

  1. ST_BUFFER通常を使用してラインをバッファリングします。無秩序な出力はありません。(つまり、'side=left/right'パラメーターを使用しないでください)。
  2. 線を使用ST_Splitして、ステップ1のバッファを中央に沿って半分に分割するために使用します。ST_UNION隣接する接続線のある線!これにより、切断線がバッファーを通過して超えて延びることが保証されます。それ以外は何もカットしません。
  3. ラインを再度バッファリングしますが、今回は片側のみをバッファリングします。これはあなた望まない側でなければなりません。
  4. ST_PointOnSurface「間違った」サイドバッファ形状ごとにを使用してポイントテーブルを作成します。
  5. この新しいポイントテーブルを使用して、ポイントと交差していることがわかった分割ポリゴンバッファ(手順2から)からポリゴンを削除します。
  6. これで、「間違った」側が削除された完全なバッファ形状が残ります。すなわち。あなたは望ましい正しい面を残されています。

私はこれを大規模に要約し、各線分について、切断に役立つ隣接する接続線があると仮定しました。また、数千のセグメントがある海岸線に対してもこれを行いました。そこで、ホストテーブルを使用して、上記の手順の各反復をに挿入しました。各ラインセグメントをループするために、ラインテーブルに自動インクリメントID列があることを確認しました(したがって、各ラインセグメントについて、その前後のセグメントとマージできます:つまり、n-1、n、n + 1)。詳細を明確にするために、この回答をすぐに更新します。